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.

228 lines
5.8 KiB

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