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.

327 lines
7.2 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*********************************************************************************************
  3. *
  4. *
  5. * Module Name:
  6. *
  7. * Ptrarray.cpp
  8. *
  9. * Abstract:
  10. * This is file has implementation of CPtrArray class borrowed from MFC
  11. *
  12. * Author:
  13. *
  14. *
  15. * Revision:
  16. *
  17. *
  18. ************************************************************************************************/
  19. #include "stdafx.h"
  20. #include "PtrArray.h"
  21. #include <windows.h>
  22. #include <assert.h>
  23. CPtrArray::CPtrArray()
  24. {
  25. m_pData = NULL;
  26. m_nSize = m_nMaxSize = m_nGrowBy = 0;
  27. }
  28. CPtrArray::~CPtrArray()
  29. {
  30. delete[] (BYTE*)m_pData;
  31. }
  32. //
  33. // inform user whether or not setsize failed or not
  34. //
  35. BOOL CPtrArray::SetSize(int nNewSize, int nGrowBy)
  36. {
  37. assert(nNewSize >= 0);
  38. if (nGrowBy != -1)
  39. m_nGrowBy = nGrowBy; // set new size
  40. if (nNewSize == 0)
  41. {
  42. // shrink to nothing
  43. delete[] (BYTE*)m_pData;
  44. m_pData = NULL;
  45. m_nSize = m_nMaxSize = 0;
  46. }
  47. else if (m_pData == NULL)
  48. {
  49. // create one with exact size
  50. #ifdef SIZE_T_MAX
  51. assert(nNewSize <= SIZE_T_MAX/sizeof(void*)); // no overflow
  52. #endif
  53. m_pData = (void**) new BYTE[nNewSize * sizeof(void*)];
  54. if( m_pData != NULL )
  55. {
  56. memset(m_pData, 0, nNewSize * sizeof(void*)); // zero fill
  57. m_nSize = m_nMaxSize = nNewSize;
  58. }
  59. else
  60. {
  61. m_nSize = m_nMaxSize = 0;
  62. return FALSE;
  63. }
  64. }
  65. else if (nNewSize <= m_nMaxSize)
  66. {
  67. if (nNewSize > m_nSize)
  68. {
  69. // initialize the new elements
  70. memset(&m_pData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(void*));
  71. }
  72. m_nSize = nNewSize;
  73. }
  74. else
  75. {
  76. // otherwise, grow array
  77. int nGrowBy = m_nGrowBy;
  78. if (nGrowBy == 0)
  79. {
  80. // heuristically determine growth when nGrowBy == 0
  81. // (this avoids heap fragmentation in many situations)
  82. nGrowBy = min(1024, max(4, m_nSize / 8));
  83. }
  84. int nNewMax;
  85. if (nNewSize < m_nMaxSize + nGrowBy)
  86. nNewMax = m_nMaxSize + nGrowBy; // granularity
  87. else
  88. nNewMax = nNewSize; // no slush
  89. assert(nNewMax >= m_nMaxSize); // no wrap around
  90. #ifdef SIZE_T_MAX
  91. assert(nNewMax <= SIZE_T_MAX/sizeof(void*)); // no overflow
  92. #endif
  93. void** pNewData = (void**) new BYTE[nNewMax * sizeof(void*)];
  94. // copy new data from old
  95. if( pNewData != NULL )
  96. {
  97. memcpy(pNewData, m_pData, m_nSize * sizeof(void*));
  98. // construct remaining elements
  99. assert(nNewSize > m_nSize);
  100. memset(&pNewData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(void*));
  101. // get rid of old stuff (note: no destructors called)
  102. delete[] (BYTE*)m_pData;
  103. m_pData = pNewData;
  104. m_nSize = nNewSize;
  105. m_nMaxSize = nNewMax;
  106. }
  107. else
  108. {
  109. return FALSE;
  110. }
  111. }
  112. return TRUE;
  113. }
  114. int CPtrArray::Append(const CPtrArray& src)
  115. {
  116. assert(this != &src); // cannot append to itself
  117. int nOldSize = m_nSize;
  118. SetSize(m_nSize + src.m_nSize);
  119. memcpy(m_pData + nOldSize, src.m_pData, src.m_nSize * sizeof(void*));
  120. return nOldSize;
  121. }
  122. void CPtrArray::Copy(const CPtrArray& src)
  123. {
  124. assert(this != &src); // cannot append to itself
  125. SetSize( src.m_nSize );
  126. if( m_pData != NULL )
  127. {
  128. memcpy(m_pData, src.m_pData, src.m_nSize * sizeof(void*));
  129. }
  130. }
  131. void CPtrArray::FreeExtra()
  132. {
  133. if (m_nSize != m_nMaxSize)
  134. {
  135. // shrink to desired size
  136. #ifdef SIZE_T_MAX
  137. assert(m_nSize <= SIZE_T_MAX/sizeof(void*)); // no overflow
  138. #endif
  139. void** pNewData = NULL;
  140. if (m_nSize != 0)
  141. {
  142. pNewData = (void**) new BYTE[m_nSize * sizeof(void*)];
  143. // copy new data from old
  144. if( pNewData != NULL )
  145. {
  146. memcpy(pNewData, m_pData, m_nSize * sizeof(void*));
  147. }
  148. else
  149. {
  150. m_nSize = 0;
  151. }
  152. }
  153. // get rid of old stuff (note: no destructors called)
  154. delete[] (BYTE*)m_pData;
  155. m_pData = pNewData;
  156. m_nMaxSize = m_nSize;
  157. }
  158. }
  159. /////////////////////////////////////////////////////////////////////////////
  160. BOOL CPtrArray::SetAtGrow(int nIndex, void* newElement)
  161. {
  162. assert(nIndex >= 0);
  163. if (nIndex >= m_nSize)
  164. {
  165. if( !SetSize( nIndex+1 ) )
  166. {
  167. return FALSE;
  168. }
  169. }
  170. if( m_pData != NULL )
  171. {
  172. m_pData[nIndex] = newElement;
  173. return TRUE;
  174. }
  175. return FALSE;
  176. }
  177. BOOL CPtrArray::InsertAt(int nIndex, void* newElement, int nCount)
  178. {
  179. assert(nIndex >= 0); // will expand to meet need
  180. assert(nCount > 0); // zero or negative size not allowed
  181. if (nIndex >= m_nSize)
  182. {
  183. // adding after the end of the array
  184. if( !SetSize(nIndex + nCount ) ) // grow so nIndex is valid
  185. {
  186. return FALSE;
  187. }
  188. }
  189. else
  190. {
  191. // inserting in the middle of the array
  192. int nOldSize = m_nSize;
  193. if( !SetSize(m_nSize + nCount) ) // grow it to new size
  194. {
  195. return FALSE;
  196. }
  197. // shift old data up to fill gap
  198. memmove(&m_pData[nIndex+nCount], &m_pData[nIndex],
  199. (nOldSize-nIndex) * sizeof(void*));
  200. // re-init slots we copied from
  201. memset(&m_pData[nIndex], 0, nCount * sizeof(void*));
  202. }
  203. // insert new value in the gap
  204. assert(nIndex + nCount <= m_nSize);
  205. while (nCount--)
  206. m_pData[nIndex++] = newElement;
  207. return TRUE;
  208. }
  209. void CPtrArray::RemoveAt(int nIndex, int nCount)
  210. {
  211. assert(nIndex >= 0);
  212. assert(nCount >= 0);
  213. assert(nIndex + nCount <= m_nSize);
  214. // just remove a range
  215. int nMoveCount = m_nSize - (nIndex + nCount);
  216. if (nMoveCount)
  217. memcpy(&m_pData[nIndex], &m_pData[nIndex + nCount],
  218. nMoveCount * sizeof(void*));
  219. m_nSize -= nCount;
  220. }
  221. void CPtrArray::InsertAt(int nStartIndex, CPtrArray* pNewArray)
  222. {
  223. assert(pNewArray != NULL);
  224. assert(nStartIndex >= 0);
  225. if (pNewArray->GetSize() > 0)
  226. {
  227. if( InsertAt(nStartIndex, pNewArray->GetAt(0), pNewArray->GetSize()) )
  228. {
  229. for (int i = 0; i < pNewArray->GetSize(); i++)
  230. {
  231. SetAt(nStartIndex + i, pNewArray->GetAt(i));
  232. }
  233. }
  234. }
  235. }
  236. int CPtrArray::GetSize() const
  237. { return m_nSize; }
  238. int CPtrArray::GetUpperBound() const
  239. { return m_nSize-1; }
  240. void CPtrArray::RemoveAll()
  241. { SetSize(0); }
  242. void* CPtrArray::GetAt(int nIndex) const
  243. { assert(nIndex >= 0 && nIndex < m_nSize);
  244. return m_pData[nIndex]; }
  245. void CPtrArray::SetAt(int nIndex, void* newElement)
  246. { assert(nIndex >= 0 && nIndex < m_nSize);
  247. m_pData[nIndex] = newElement; }
  248. void*& CPtrArray::ElementAt(int nIndex)
  249. { assert(nIndex >= 0 && nIndex < m_nSize);
  250. return m_pData[nIndex]; }
  251. const void** CPtrArray::GetData() const
  252. { return (const void**)m_pData; }
  253. void** CPtrArray::GetData()
  254. { return (void**)m_pData; }
  255. BOOL CPtrArray::Add(void* newElement)
  256. {
  257. int nIndex = m_nSize;
  258. if( !SetAtGrow(nIndex, newElement) )
  259. {
  260. return FALSE;
  261. }
  262. return TRUE;
  263. }
  264. void* CPtrArray::operator[](int nIndex) const
  265. { return GetAt(nIndex); }
  266. void*& CPtrArray::operator[](int nIndex)
  267. { return ElementAt(nIndex); }