Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
4.1 KiB

  1. //
  2. // strary.h
  3. //
  4. // CStructArray -- growable struct array
  5. //
  6. #ifndef STRARY_H
  7. #define STRARY_H
  8. #include "private.h"
  9. #include "mem.h"
  10. class CVoidStructArray
  11. {
  12. public:
  13. CVoidStructArray(int iElemSize)
  14. {
  15. _iElemSize = iElemSize; // Issue: iElemSize should be const in template
  16. _pb = NULL;
  17. _cElems = 0;
  18. _iSize = 0;
  19. }
  20. virtual ~CVoidStructArray() { cicMemFree(_pb); }
  21. inline void *GetPtr(int iIndex)
  22. {
  23. Assert(iIndex >= 0);
  24. Assert(iIndex <= _cElems); // there's code that uses the first invalid offset for loop termination
  25. return _pb + (iIndex * _iElemSize);
  26. }
  27. BOOL Insert(int iIndex, int cElems);
  28. void Remove(int iIndex, int cElems);
  29. void *Append(int cElems)
  30. {
  31. return Insert(Count(), cElems) ? GetPtr(Count()-cElems) : NULL;
  32. }
  33. int Count()
  34. {
  35. return _cElems;
  36. }
  37. void Clear()
  38. {
  39. cicMemFree(_pb);
  40. _pb = NULL;
  41. _cElems = _iSize = 0;
  42. }
  43. void Reset(int iMaxSize)
  44. {
  45. BYTE *pb;
  46. _cElems = 0;
  47. if (_iSize <= iMaxSize)
  48. return;
  49. Assert(_pb != NULL); // _iSize should be zero in this case
  50. if ((pb = (BYTE *)cicMemReAlloc(_pb, iMaxSize*_iElemSize))
  51. == NULL)
  52. {
  53. return;
  54. }
  55. _pb = pb;
  56. _iSize = iMaxSize;
  57. }
  58. protected:
  59. BYTE *_pb; // the array
  60. int _cElems; // num eles in the array
  61. int _iElemSize; // num eles in the array
  62. int _iSize; // actual size (in void *'s) of the array
  63. };
  64. //
  65. // typesafe version
  66. //
  67. template<class T>
  68. class CStructArray : public CVoidStructArray
  69. {
  70. public:
  71. CStructArray():CVoidStructArray(sizeof(T)) {}
  72. T *GetPtr(int iIndex) { return (T *)CVoidStructArray::GetPtr(iIndex); }
  73. T *Append(int cElems) { return (T *)CVoidStructArray::Append(cElems); }
  74. };
  75. //
  76. // GUID version
  77. //
  78. class CGUIDArray : private CVoidStructArray
  79. {
  80. public:
  81. CGUIDArray():CVoidStructArray(sizeof(GUID)) {}
  82. int Count() { return _cElems; }
  83. GUID *GetPtr(int iIndex) { return (GUID *)CVoidStructArray::GetPtr(iIndex); }
  84. GUID *Append(int cElems) { return (GUID *)CVoidStructArray::Append(cElems); }
  85. int InsertGuid(const GUID *pguid)
  86. {
  87. int nIndex;
  88. Find(pguid, &nIndex);
  89. nIndex++;
  90. Insert(nIndex, 1);
  91. *(((GUID *)_pb) + nIndex) = *pguid;
  92. return nIndex;
  93. }
  94. int RemoveGuid(const GUID *pguid)
  95. {
  96. int nIndex = Find(pguid, NULL);
  97. if (nIndex == -1)
  98. return -1;
  99. Remove(nIndex, 1);
  100. return nIndex;
  101. }
  102. int Find(const GUID *pguid, int *piOut)
  103. {
  104. int iMatch = -1;
  105. int iMid = -1;
  106. int iMin = 0;
  107. int iMax = _cElems;
  108. LONG l;
  109. while(iMin < iMax)
  110. {
  111. iMid = (iMin + iMax) / 2;
  112. l = memcmp(pguid, ((GUID *)_pb) + iMid, sizeof(GUID));
  113. if (l < 0)
  114. {
  115. iMax = iMid;
  116. }
  117. else if (l > 0)
  118. {
  119. iMin = iMid + 1;
  120. }
  121. else
  122. {
  123. iMatch = iMid;
  124. break;
  125. }
  126. }
  127. if (piOut)
  128. {
  129. if ((iMatch == -1) && (iMid >= 0))
  130. {
  131. if (memcmp(pguid, ((GUID *)_pb) + iMid, sizeof(GUID)) < 0)
  132. iMid--;
  133. }
  134. *piOut = iMid;
  135. }
  136. return iMatch;
  137. }
  138. };
  139. //
  140. // Ref-counted version.
  141. //
  142. // Note: this is limited, because there's no dtor for struct elements.
  143. //
  144. template<class T>
  145. class CSharedStructArray : public CStructArray<T>
  146. {
  147. public:
  148. CSharedStructArray() : CStructArray<T>()
  149. {
  150. _cRef = 1;
  151. }
  152. void _AddRef()
  153. {
  154. _cRef++;
  155. }
  156. void _Release()
  157. {
  158. Assert(_cRef > 0);
  159. if (--_cRef == 0)
  160. {
  161. delete this;
  162. }
  163. }
  164. private:
  165. LONG _cRef;
  166. };
  167. #endif // STRARY_H