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.

278 lines
7.6 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. //
  5. // FLEXARRY.CPP
  6. //
  7. // CFlexArray implementation (non-arena).
  8. //
  9. // 15-Jul-97 raymcc Created.
  10. // 8-Jun-98 bobw cleaned up for WBEMPERF usage
  11. //
  12. //***************************************************************************
  13. #include "wpheader.h"
  14. #include <stdio.h>
  15. //***************************************************************************
  16. //
  17. // CFlexArray::CFlexArray
  18. //
  19. // Constructs the array.
  20. //
  21. // Parameters:
  22. // <nSize> The starting preallocated size of the array.
  23. // <nGrowBy> The amount to grow by when the array fills up.
  24. //
  25. // Size() returns the number of elements in use, not the 'true' size.
  26. //
  27. //***************************************************************************
  28. // ok
  29. CFlexArray::CFlexArray(
  30. int nSize,
  31. int nGrowBy
  32. )
  33. {
  34. m_nExtent = nSize;
  35. m_nSize = 0;
  36. m_nGrowBy = nGrowBy;
  37. m_hHeap = GetProcessHeap(); // call this once and save heap handle locally
  38. m_pArray = (void **) ALLOCMEM(m_hHeap, HEAP_ZERO_MEMORY, sizeof(void *) * nSize);
  39. if( NULL == m_pArray ){
  40. assert(FALSE);
  41. m_nExtent = 0;
  42. }
  43. }
  44. //***************************************************************************
  45. //
  46. // CFlexArray::~CFlexArray
  47. //
  48. //***************************************************************************
  49. // ok
  50. CFlexArray::~CFlexArray()
  51. {
  52. FREEMEM(m_hHeap, 0, m_pArray);
  53. }
  54. //***************************************************************************
  55. //
  56. // Copy constructor.
  57. //
  58. // Copies the pointers, not their contents.
  59. //
  60. //***************************************************************************
  61. // ok
  62. CFlexArray::CFlexArray(CFlexArray &Src)
  63. {
  64. m_pArray = 0;
  65. m_nSize = 0;
  66. m_nExtent = 0;
  67. m_nGrowBy = 0;
  68. *this = Src;
  69. }
  70. //***************************************************************************
  71. //
  72. // operator =
  73. //
  74. // Assignment operator.
  75. //
  76. // Arenas are not copied. This allows transfer of arrays between arenas.
  77. // Arrays are copied by pointer only.
  78. //
  79. //***************************************************************************
  80. // ok
  81. CFlexArray& CFlexArray::operator=(CFlexArray &Src)
  82. {
  83. m_nSize = Src.m_nSize;
  84. m_nExtent = Src.m_nExtent;
  85. m_nGrowBy = Src.m_nGrowBy;
  86. FREEMEM (m_hHeap, 0, m_pArray);
  87. m_pArray = (void **) ALLOCMEM(m_hHeap, HEAP_ZERO_MEMORY, sizeof(void *) * m_nExtent);
  88. if (m_pArray) {
  89. memcpy(m_pArray, Src.m_pArray, sizeof(void *) * m_nExtent);
  90. }
  91. return *this;
  92. }
  93. //***************************************************************************
  94. //
  95. // CFlexArray::RemoveAt
  96. //
  97. // Removes the element at the specified location. Does not
  98. // actually delete the pointer. Shrinks the array over the top of
  99. // the 'doomed' element.
  100. //
  101. // Parameters:
  102. // <nIndex> The location of the element.
  103. //
  104. // Return value:
  105. // range_error The index is not legal.
  106. // no_error Success.
  107. //
  108. //***************************************************************************
  109. // ok
  110. int CFlexArray::RemoveAt(int nIndex)
  111. {
  112. int i;
  113. if (nIndex >= m_nSize) {
  114. return range_error;
  115. }
  116. for (i = nIndex; i < m_nSize - 1; i++) {
  117. m_pArray[i] = m_pArray[i + 1];
  118. }
  119. m_nSize--;
  120. m_pArray[m_nSize] = 0;
  121. return no_error;
  122. }
  123. int CFlexArray::Remove( void* p )
  124. {
  125. for (int i = 0; i < m_nSize; i++) {
  126. if( m_pArray[i] == p ){
  127. return RemoveAt( i );
  128. }
  129. }
  130. return failed;
  131. }
  132. //***************************************************************************
  133. //
  134. // CFlexArray::InsertAt
  135. //
  136. // Inserts a new element at the specified location. The pointer is copied.
  137. //
  138. // Parameters:
  139. // <nIndex> The 0-origin location at which to insert the new element.
  140. // <pSrc> The pointer to copy. (contents are not copied).
  141. //
  142. // Return value:
  143. // array_full
  144. // out_of_memory
  145. // no_error
  146. //
  147. //***************************************************************************
  148. // ok
  149. int CFlexArray::InsertAt(int nIndex, void *pSrc)
  150. {
  151. void **pTmp; // pointer to new array
  152. int nReturn = no_error;
  153. LONG lOldSize;
  154. LONG lNewSize;
  155. // If the array is full, we need to expand it.
  156. // ===========================================
  157. if (m_nSize == m_nExtent) {
  158. if (m_nGrowBy == 0) {
  159. nReturn = array_full;
  160. } else {
  161. // compute sizes
  162. lOldSize = sizeof(void *) * m_nExtent;
  163. m_nExtent += m_nGrowBy;
  164. lNewSize = sizeof(void *) * m_nExtent;
  165. // allocate new array
  166. pTmp = (void **) ALLOCMEM(m_hHeap, HEAP_ZERO_MEMORY, lNewSize);
  167. if (!pTmp) {
  168. nReturn = out_of_memory;
  169. } else {
  170. // move bits from old array to new array
  171. memcpy (pTmp, m_pArray, lOldSize);
  172. // toss old arrya
  173. FREEMEM (m_hHeap, 0, m_pArray);
  174. // save pointer to new array
  175. m_pArray = pTmp;
  176. }
  177. }
  178. }
  179. if( nIndex > m_nSize ){
  180. nReturn = range_error;
  181. }
  182. // Special case of appending. This is so frequent
  183. // compared to true insertion that we want to optimize.
  184. // ====================================================
  185. if (nReturn == no_error) {
  186. if (nIndex == m_nSize) {
  187. m_pArray[m_nSize++] = pSrc;
  188. } else {
  189. // If here, we are inserting at some random location.
  190. // We start at the end of the array and copy all the elements
  191. // one position farther to the end to make a 'hole' for
  192. // the new element.
  193. // ==========================================================
  194. for (int i = m_nSize; i > nIndex; i--) {
  195. m_pArray[i] = m_pArray[i - 1];
  196. }
  197. m_pArray[nIndex] = pSrc;
  198. m_nSize++;
  199. }
  200. }
  201. return nReturn;
  202. }
  203. //***************************************************************************
  204. //
  205. // CFlexArray::Compress
  206. //
  207. // Removes NULL elements by moving all non-NULL pointers to the beginning
  208. // of the array. The array "Size" changes, but the extent is untouched.
  209. //
  210. //***************************************************************************
  211. // ok
  212. void CFlexArray::Compress()
  213. {
  214. int nLeftCursor = 0, nRightCursor = 0;
  215. while (nLeftCursor < m_nSize - 1) {
  216. if (m_pArray[nLeftCursor]) {
  217. nLeftCursor++;
  218. continue;
  219. }
  220. else {
  221. nRightCursor = nLeftCursor + 1;
  222. while (m_pArray[nRightCursor] == 0 && nRightCursor < m_nSize)
  223. nRightCursor++;
  224. if (nRightCursor == m_nSize)
  225. break; // Short circuit, no more nonzero elements.
  226. m_pArray[nLeftCursor] = m_pArray[nRightCursor];
  227. m_pArray[nRightCursor] = 0;
  228. }
  229. }
  230. while (m_pArray[m_nSize - 1] == 0 && m_nSize > 0) m_nSize--;
  231. }
  232. //***************************************************************************
  233. //
  234. // CFlexArray::Empty
  235. //
  236. // Clears the array of all pointers (does not deallocate them) and sets
  237. // its apparent size to zero.
  238. //
  239. //***************************************************************************
  240. // ok
  241. void CFlexArray::Empty()
  242. {
  243. FREEMEM(m_hHeap, 0, m_pArray);
  244. m_pArray = (void **) ALLOCMEM(m_hHeap, HEAP_ZERO_MEMORY, sizeof(void *) * m_nGrowBy);
  245. m_nSize = 0;
  246. m_nExtent = m_nGrowBy;
  247. }