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.

261 lines
5.4 KiB

  1. #ifndef __h323ics_dynarray_h
  2. #define __h323ics_dynarray_h
  3. // a dense array
  4. typedef const void * BINARY_SEARCH_KEY;
  5. template <class OBJECT>
  6. class DYNAMIC_ARRAY
  7. {
  8. public:
  9. // returns positive if ObjectA > ObjectB
  10. // returns negative if ObjectA < ObjectB
  11. // returns zero if ObjectA = ObjectB
  12. typedef int (__cdecl * COMPARE_FUNC) (const OBJECT * ObjectA, const OBJECT * ObjectB);
  13. public:
  14. OBJECT * Data;
  15. DWORD Length;
  16. DWORD MaxLength;
  17. public:
  18. void Clear (void) {
  19. Length = 0;
  20. }
  21. void Free (void) {
  22. if (Data) {
  23. HeapFree (GetProcessHeap(), 0, Data);
  24. Data = NULL;
  25. Length = 0;
  26. MaxLength = 0;
  27. }
  28. else {
  29. _ASSERTE (!Length);
  30. _ASSERTE (!MaxLength);
  31. }
  32. }
  33. DWORD GetLength (void) { return Length; }
  34. DWORD GetMax (void) { return MaxLength; }
  35. BOOL Grow (DWORD MaxLengthRequested) {
  36. OBJECT * NewData;
  37. DWORD NewMaxLength; // in OBJECT units
  38. DWORD BytesRequested;
  39. if (MaxLengthRequested <= MaxLength)
  40. return TRUE;
  41. // very arbitrary heuristic
  42. NewMaxLength = MaxLengthRequested + (MaxLengthRequested >> 1) + 0x20;
  43. BytesRequested = NewMaxLength * sizeof (OBJECT);
  44. if (Data) {
  45. NewData = (OBJECT *) HeapReAlloc (GetProcessHeap(), 0, Data, BytesRequested);
  46. if (!NewData)
  47. DebugF (_T("DYNAMIC_ARRAY::Grow: HeapReAlloc failed, BytesRequested %08XH\n"), BytesRequested);
  48. }
  49. else {
  50. NewData = (OBJECT *) HeapAlloc (GetProcessHeap(), 0, BytesRequested);
  51. if (!NewData)
  52. DebugF (_T("DYNAMIC_ARRAY::Grow: HeapAlloc failed, BytesRequested %08XH\n"), BytesRequested);
  53. }
  54. if (!NewData)
  55. return FALSE;
  56. Data = NewData;
  57. MaxLength = NewMaxLength;
  58. return TRUE;
  59. }
  60. OBJECT * AllocRangeAtPos (DWORD pos, DWORD RangeLength) {
  61. _ASSERTE (pos <= Length);
  62. if (!Grow (Length + RangeLength))
  63. return NULL;
  64. memmove (Data + pos + RangeLength, Data + pos, (Length - pos) * sizeof (OBJECT));
  65. Length += RangeLength;
  66. return Data + pos;
  67. }
  68. OBJECT * AllocAtPos (DWORD pos) {
  69. return AllocRangeAtPos (pos, 1);
  70. }
  71. OBJECT * AllocAtEnd (void) {
  72. return AllocAtPos (Length);
  73. }
  74. void DeleteRangeAtPos (DWORD pos, DWORD RangeLength) {
  75. _ASSERTE (Data);
  76. _ASSERTE (MaxLength);
  77. _ASSERTE (Length);
  78. _ASSERTE (pos < Length);
  79. _ASSERTE (Length - pos >= RangeLength);
  80. memmove (Data + pos, Data + pos + RangeLength, (Length - pos - RangeLength) * sizeof (OBJECT));
  81. Length -= RangeLength;
  82. }
  83. void DeleteAtPos (DWORD pos) {
  84. DeleteRangeAtPos (pos, 1);
  85. }
  86. void DeleteEntry (OBJECT * Object) {
  87. _ASSERTE (Object >= Data);
  88. _ASSERTE (Object < Data + Length);
  89. DeleteAtPos ((DWORD)(Object - Data));
  90. }
  91. DYNAMIC_ARRAY (void)
  92. : Data (NULL), Length (0), MaxLength (0) {}
  93. ~DYNAMIC_ARRAY (void) {
  94. Free();
  95. }
  96. void QuickSort (COMPARE_FUNC CompareFunc) {
  97. qsort (Data, Length, sizeof (OBJECT), (int (__cdecl *) (const void *, const void *)) CompareFunc);
  98. }
  99. // a templatized version of BinarySearch
  100. // SearchFunc should:
  101. // return positive if SearchKey > Comparand
  102. // return negative if SearchKey < Comparand
  103. // return zero if SearchKey = Comparand
  104. template <class SEARCH_KEY>
  105. BOOL BinarySearch (
  106. IN INT (*SearchFunc) (const SEARCH_KEY * SearchKey, const OBJECT * Comparand),
  107. IN const SEARCH_KEY * SearchKey,
  108. OUT DWORD * ReturnIndex)
  109. {
  110. DWORD Start;
  111. DWORD End;
  112. DWORD Index;
  113. OBJECT * Object;
  114. int CompareResult;
  115. assert (ReturnIndex);
  116. Start = 0;
  117. End = Length;
  118. for (;;) {
  119. Index = (Start + End) / 2;
  120. if (Index == End) {
  121. *ReturnIndex = Index;
  122. return FALSE;
  123. }
  124. Object = Data + Index;
  125. CompareResult = (*SearchFunc) (SearchKey, Object);
  126. if (CompareResult == 0) {
  127. *ReturnIndex = Index;
  128. return TRUE;
  129. }
  130. else if (CompareResult > 0) {
  131. Start = Index + 1;
  132. }
  133. else {
  134. End = Index;
  135. }
  136. }
  137. }
  138. BOOL FindIndex (COMPARE_FUNC CompareFunc,
  139. OBJECT * ObjectArg,
  140. DWORD * ReturnIndex)
  141. {
  142. DWORD Start;
  143. DWORD End;
  144. DWORD Index;
  145. OBJECT *Object;
  146. int CompareResult;
  147. _ASSERTE (ReturnIndex);
  148. Start = 0;
  149. End = Length;
  150. for (;;) {
  151. Index = (Start + End) / 2;
  152. if (Index == End) {
  153. *ReturnIndex = Index;
  154. return FALSE;
  155. }
  156. Object = Data + Index;
  157. CompareResult = (*CompareFunc)(ObjectArg, Object);
  158. if (CompareResult == 0) {
  159. *ReturnIndex = Index;
  160. return TRUE;
  161. }
  162. else if (CompareResult > 0) {
  163. Start = Index + 1;
  164. }
  165. else {
  166. End = Index;
  167. }
  168. }
  169. }
  170. void GetExtents (
  171. OUT OBJECT ** ReturnStart,
  172. OUT OBJECT ** ReturnEnd)
  173. {
  174. _ASSERTE (ReturnStart);
  175. _ASSERTE (ReturnEnd);
  176. *ReturnStart = Data;
  177. *ReturnEnd = Data + Length;
  178. }
  179. OBJECT & operator[] (
  180. IN DWORD Index)
  181. {
  182. _ASSERTE (Index < Length);
  183. return Data [Index];
  184. }
  185. };
  186. // Hack/Hint for Alpha compiler
  187. #define DECLARE_SEARCH_FUNC_CAST_X(Suffix,Key,Object) typedef INT (* SEARCH_FUNC_##Suffix)(const Key *, const Object *)
  188. #define DECLARE_SEARCH_FUNC_CAST(Key,Object) DECLARE_SEARCH_FUNC_CAST_X(Object,Key,Object)
  189. // I hope these don't conflict with someone else's m_Array, etc.
  190. // Should eventually globally replace all references to the right names
  191. #define m_Array Data
  192. #define m_Length Length
  193. #define m_Max MaxLength
  194. #endif // __h323ics_dynarray_h