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.

227 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 <snmpcoll.h>
  23. CObArray::CObArray()
  24. {
  25. m_pData = NULL;
  26. m_nSize = m_nMaxSize = m_nGrowBy = 0;
  27. }
  28. CObArray::~CObArray()
  29. {
  30. delete[] (BYTE*)m_pData;
  31. }
  32. void CObArray::SetSize(int nNewSize, int nGrowBy)
  33. {
  34. if (nGrowBy != -1)
  35. m_nGrowBy = nGrowBy; // set new size
  36. if (nNewSize == 0)
  37. {
  38. // shrink to nothing
  39. delete[] (BYTE*)m_pData;
  40. m_pData = NULL;
  41. m_nSize = m_nMaxSize = 0;
  42. }
  43. else if (m_pData == NULL)
  44. {
  45. // create one with exact size
  46. m_pData = (CObject**) new BYTE[nNewSize * sizeof(CObject*)];
  47. memset(m_pData, 0, nNewSize * sizeof(CObject*)); // zero fill
  48. m_nSize = m_nMaxSize = nNewSize;
  49. }
  50. else if (nNewSize <= m_nMaxSize)
  51. {
  52. // it fits
  53. if (nNewSize > m_nSize)
  54. {
  55. // initialize the new elements
  56. memset(&m_pData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(CObject*));
  57. }
  58. m_nSize = nNewSize;
  59. }
  60. else
  61. {
  62. // otherwise, grow array
  63. int nGrowBy = m_nGrowBy;
  64. if (nGrowBy == 0)
  65. {
  66. // heuristically determine growth when nGrowBy == 0
  67. // (this avoids heap fragmentation in many situations)
  68. nGrowBy = min(1024, max(4, m_nSize / 8));
  69. }
  70. int nNewMax;
  71. if (nNewSize < m_nMaxSize + nGrowBy)
  72. nNewMax = m_nMaxSize + nGrowBy; // granularity
  73. else
  74. nNewMax = nNewSize; // no slush
  75. CObject** pNewData = (CObject**) new BYTE[nNewMax * sizeof(CObject*)];
  76. // copy new data from old
  77. memcpy(pNewData, m_pData, m_nSize * sizeof(CObject*));
  78. // construct remaining elements
  79. memset(&pNewData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(CObject*));
  80. // get rid of old stuff (note: no destructors called)
  81. delete[] (BYTE*)m_pData;
  82. m_pData = pNewData;
  83. m_nSize = nNewSize;
  84. m_nMaxSize = nNewMax;
  85. }
  86. }
  87. int CObArray::Append(const CObArray& src)
  88. {
  89. int nOldSize = m_nSize;
  90. SetSize(m_nSize + src.m_nSize);
  91. memcpy(m_pData + nOldSize, src.m_pData, src.m_nSize * sizeof(CObject*));
  92. return nOldSize;
  93. }
  94. void CObArray::Copy(const CObArray& src)
  95. {
  96. SetSize(src.m_nSize);
  97. memcpy(m_pData, src.m_pData, src.m_nSize * sizeof(CObject*));
  98. }
  99. void CObArray::FreeExtra()
  100. {
  101. if (m_nSize != m_nMaxSize)
  102. {
  103. // shrink to desired size
  104. CObject** pNewData = NULL;
  105. if (m_nSize != 0)
  106. {
  107. pNewData = (CObject**) new BYTE[m_nSize * sizeof(CObject*)];
  108. // copy new data from old
  109. memcpy(pNewData, m_pData, m_nSize * sizeof(CObject*));
  110. }
  111. // get rid of old stuff (note: no destructors called)
  112. delete[] (BYTE*)m_pData;
  113. m_pData = pNewData;
  114. m_nMaxSize = m_nSize;
  115. }
  116. }
  117. /////////////////////////////////////////////////////////////////////////////
  118. void CObArray::SetAtGrow(int nIndex, CObject* newElement)
  119. {
  120. if (nIndex >= m_nSize)
  121. SetSize(nIndex+1);
  122. m_pData[nIndex] = newElement;
  123. }
  124. void CObArray::InsertAt(int nIndex, CObject* newElement, int nCount)
  125. {
  126. if (nIndex >= m_nSize)
  127. {
  128. // adding after the end of the array
  129. SetSize(nIndex + nCount); // grow so nIndex is valid
  130. }
  131. else
  132. {
  133. // inserting in the middle of the array
  134. int nOldSize = m_nSize;
  135. SetSize(m_nSize + nCount); // grow it to new size
  136. // shift old data up to fill gap
  137. memmove(&m_pData[nIndex+nCount], &m_pData[nIndex],
  138. (nOldSize-nIndex) * sizeof(CObject*));
  139. // re-init slots we copied from
  140. memset(&m_pData[nIndex], 0, nCount * sizeof(CObject*));
  141. }
  142. // insert new value in the gap
  143. while (nCount--)
  144. m_pData[nIndex++] = newElement;
  145. }
  146. void CObArray::RemoveAt(int nIndex, int nCount)
  147. {
  148. // just remove a range
  149. int nMoveCount = m_nSize - (nIndex + nCount);
  150. if (nMoveCount)
  151. memcpy(&m_pData[nIndex], &m_pData[nIndex + nCount],
  152. nMoveCount * sizeof(CObject*));
  153. m_nSize -= nCount;
  154. }
  155. void CObArray::InsertAt(int nStartIndex, CObArray* pNewArray)
  156. {
  157. if (pNewArray->GetSize() > 0)
  158. {
  159. InsertAt(nStartIndex, pNewArray->GetAt(0), pNewArray->GetSize());
  160. for (int i = 0; i < pNewArray->GetSize(); i++)
  161. SetAt(nStartIndex + i, pNewArray->GetAt(i));
  162. }
  163. }
  164. int CObArray::GetSize() const
  165. { return m_nSize; }
  166. int CObArray::GetUpperBound() const
  167. { return m_nSize-1; }
  168. void CObArray::RemoveAll()
  169. { SetSize(0); }
  170. CObject* CObArray::GetAt(int nIndex) const
  171. { return m_pData[nIndex]; }
  172. void CObArray::SetAt(int nIndex, CObject* newElement)
  173. { m_pData[nIndex] = newElement; }
  174. CObject*& CObArray::ElementAt(int nIndex)
  175. { return m_pData[nIndex]; }
  176. const CObject** CObArray::GetData() const
  177. { return (const CObject**)m_pData; }
  178. CObject** CObArray::GetData()
  179. { return (CObject**)m_pData; }
  180. int CObArray::Add(CObject* newElement)
  181. { int nIndex = m_nSize;
  182. SetAtGrow(nIndex, newElement);
  183. return nIndex; }
  184. CObject* CObArray::operator[](int nIndex) const
  185. { return GetAt(nIndex); }
  186. CObject*& CObArray::operator[](int nIndex)
  187. { return ElementAt(nIndex); }
  188. /////////////////////////////////////////////////////////////////////////////