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.

229 lines
6.3 KiB

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (c) 1992-2001 Microsoft Corporation, All Rights Reserved
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. /////////////////////////////////////////////////////////////////////////////
  11. //
  12. // Implementation of parameterized Array
  13. //
  14. /////////////////////////////////////////////////////////////////////////////
  15. // NOTE: we allocate an array of 'm_nMaxSize' elements, but only
  16. // the current size 'm_nSize' contains properly constructed
  17. // objects.
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "precomp.h"
  20. #include <provexpt.h>
  21. #include <plex.h>
  22. #include <provcoll.h>
  23. #include "provmt.h"
  24. #include "plex.h"
  25. CObArray::CObArray()
  26. {
  27. m_pData = NULL;
  28. m_nSize = m_nMaxSize = m_nGrowBy = 0;
  29. }
  30. CObArray::~CObArray()
  31. {
  32. delete[] (BYTE*)m_pData;
  33. }
  34. void CObArray::SetSize(int nNewSize, int nGrowBy)
  35. {
  36. if (nGrowBy != -1)
  37. m_nGrowBy = nGrowBy; // set new size
  38. if (nNewSize == 0)
  39. {
  40. // shrink to nothing
  41. delete[] (BYTE*)m_pData;
  42. m_pData = NULL;
  43. m_nSize = m_nMaxSize = 0;
  44. }
  45. else if (m_pData == NULL)
  46. {
  47. // create one with exact size
  48. m_pData = (CObject**) new BYTE[nNewSize * sizeof(CObject*)];
  49. memset(m_pData, 0, nNewSize * sizeof(CObject*)); // zero fill
  50. m_nSize = m_nMaxSize = nNewSize;
  51. }
  52. else if (nNewSize <= m_nMaxSize)
  53. {
  54. // it fits
  55. if (nNewSize > m_nSize)
  56. {
  57. // initialize the new elements
  58. memset(&m_pData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(CObject*));
  59. }
  60. m_nSize = nNewSize;
  61. }
  62. else
  63. {
  64. // otherwise, grow array
  65. int nGrowBy = m_nGrowBy;
  66. if (nGrowBy == 0)
  67. {
  68. // heuristically determine growth when nGrowBy == 0
  69. // (this avoids heap fragmentation in many situations)
  70. nGrowBy = min(1024, max(4, m_nSize / 8));
  71. }
  72. int nNewMax;
  73. if (nNewSize < m_nMaxSize + nGrowBy)
  74. nNewMax = m_nMaxSize + nGrowBy; // granularity
  75. else
  76. nNewMax = nNewSize; // no slush
  77. CObject** pNewData = (CObject**) new BYTE[nNewMax * sizeof(CObject*)];
  78. // copy new data from old
  79. memcpy(pNewData, m_pData, m_nSize * sizeof(CObject*));
  80. // construct remaining elements
  81. memset(&pNewData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(CObject*));
  82. // get rid of old stuff (note: no destructors called)
  83. delete[] (BYTE*)m_pData;
  84. m_pData = pNewData;
  85. m_nSize = nNewSize;
  86. m_nMaxSize = nNewMax;
  87. }
  88. }
  89. int CObArray::Append(const CObArray& src)
  90. {
  91. int nOldSize = m_nSize;
  92. SetSize(m_nSize + src.m_nSize);
  93. memcpy(m_pData + nOldSize, src.m_pData, src.m_nSize * sizeof(CObject*));
  94. return nOldSize;
  95. }
  96. void CObArray::Copy(const CObArray& src)
  97. {
  98. SetSize(src.m_nSize);
  99. memcpy(m_pData, src.m_pData, src.m_nSize * sizeof(CObject*));
  100. }
  101. void CObArray::FreeExtra()
  102. {
  103. if (m_nSize != m_nMaxSize)
  104. {
  105. // shrink to desired size
  106. CObject** pNewData = NULL;
  107. if (m_nSize != 0)
  108. {
  109. pNewData = (CObject**) new BYTE[m_nSize * sizeof(CObject*)];
  110. // copy new data from old
  111. memcpy(pNewData, m_pData, m_nSize * sizeof(CObject*));
  112. }
  113. // get rid of old stuff (note: no destructors called)
  114. delete[] (BYTE*)m_pData;
  115. m_pData = pNewData;
  116. m_nMaxSize = m_nSize;
  117. }
  118. }
  119. /////////////////////////////////////////////////////////////////////////////
  120. void CObArray::SetAtGrow(int nIndex, CObject* newElement)
  121. {
  122. if (nIndex >= m_nSize)
  123. SetSize(nIndex+1);
  124. m_pData[nIndex] = newElement;
  125. }
  126. void CObArray::InsertAt(int nIndex, CObject* newElement, int nCount)
  127. {
  128. if (nIndex >= m_nSize)
  129. {
  130. // adding after the end of the array
  131. SetSize(nIndex + nCount); // grow so nIndex is valid
  132. }
  133. else
  134. {
  135. // inserting in the middle of the array
  136. int nOldSize = m_nSize;
  137. SetSize(m_nSize + nCount); // grow it to new size
  138. // shift old data up to fill gap
  139. memmove(&m_pData[nIndex+nCount], &m_pData[nIndex],
  140. (nOldSize-nIndex) * sizeof(CObject*));
  141. // re-init slots we copied from
  142. memset(&m_pData[nIndex], 0, nCount * sizeof(CObject*));
  143. }
  144. // insert new value in the gap
  145. while (nCount--)
  146. m_pData[nIndex++] = newElement;
  147. }
  148. void CObArray::RemoveAt(int nIndex, int nCount)
  149. {
  150. // just remove a range
  151. int nMoveCount = m_nSize - (nIndex + nCount);
  152. if (nMoveCount)
  153. memcpy(&m_pData[nIndex], &m_pData[nIndex + nCount],
  154. nMoveCount * sizeof(CObject*));
  155. m_nSize -= nCount;
  156. }
  157. void CObArray::InsertAt(int nStartIndex, CObArray* pNewArray)
  158. {
  159. if (pNewArray->GetSize() > 0)
  160. {
  161. InsertAt(nStartIndex, pNewArray->GetAt(0), pNewArray->GetSize());
  162. for (int i = 0; i < pNewArray->GetSize(); i++)
  163. SetAt(nStartIndex + i, pNewArray->GetAt(i));
  164. }
  165. }
  166. int CObArray::GetSize() const
  167. { return m_nSize; }
  168. int CObArray::GetUpperBound() const
  169. { return m_nSize-1; }
  170. void CObArray::RemoveAll()
  171. { SetSize(0); }
  172. CObject* CObArray::GetAt(int nIndex) const
  173. { return m_pData[nIndex]; }
  174. void CObArray::SetAt(int nIndex, CObject* newElement)
  175. { m_pData[nIndex] = newElement; }
  176. CObject*& CObArray::ElementAt(int nIndex)
  177. { return m_pData[nIndex]; }
  178. const CObject** CObArray::GetData() const
  179. { return (const CObject**)m_pData; }
  180. CObject** CObArray::GetData()
  181. { return (CObject**)m_pData; }
  182. int CObArray::Add(CObject* newElement)
  183. { int nIndex = m_nSize;
  184. SetAtGrow(nIndex, newElement);
  185. return nIndex; }
  186. CObject* CObArray::operator[](int nIndex) const
  187. { return GetAt(nIndex); }
  188. CObject*& CObArray::operator[](int nIndex)
  189. { return ElementAt(nIndex); }
  190. /////////////////////////////////////////////////////////////////////////////