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.

210 lines
5.1 KiB

  1. /*++
  2. Copyright (C) 1994-2001 Microsoft Corporation
  3. Module Name:
  4. ARRAY_D.CPP
  5. Abstract:
  6. MiniAFX implementation. 09/25/94 TSE.
  7. History:
  8. --*/
  9. #include "precomp.h"
  10. #define ASSERT(x)
  11. #define ASSERT_VALID(x)
  12. /////////////////////////////////////////////////////////////////////////////
  13. CDWordArray::CDWordArray()
  14. {
  15. m_pData = NULL;
  16. m_nSize = m_nMaxSize = m_nGrowBy = 0;
  17. }
  18. CDWordArray::~CDWordArray()
  19. {
  20. ASSERT_VALID(this);
  21. delete (BYTE*)m_pData;
  22. }
  23. void CDWordArray::SetSize(int nNewSize, int nGrowBy /* = -1 */)
  24. {
  25. ASSERT_VALID(this);
  26. ASSERT(nNewSize >= 0);
  27. if (nGrowBy != -1)
  28. m_nGrowBy = nGrowBy; // set new size
  29. if (nNewSize == 0)
  30. {
  31. // shrink to nothing
  32. delete (BYTE*)m_pData;
  33. m_pData = NULL;
  34. m_nSize = m_nMaxSize = 0;
  35. }
  36. else if (m_pData == NULL)
  37. {
  38. // create one with exact size
  39. #ifdef SIZE_T_MAX
  40. ASSERT((long)nNewSize * sizeof(DWORD) <= SIZE_T_MAX); // no overflow
  41. #endif
  42. m_pData = (DWORD*) new BYTE[nNewSize * sizeof(DWORD)];
  43. memset(m_pData, 0, nNewSize * sizeof(DWORD)); // zero fill
  44. m_nSize = m_nMaxSize = nNewSize;
  45. }
  46. else if (nNewSize <= m_nMaxSize)
  47. {
  48. // it fits
  49. if (nNewSize > m_nSize)
  50. {
  51. // initialize the new elements
  52. memset(&m_pData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(DWORD));
  53. }
  54. m_nSize = nNewSize;
  55. }
  56. else
  57. {
  58. // Otherwise grow array
  59. int nNewMax;
  60. if (nNewSize < m_nMaxSize + m_nGrowBy)
  61. nNewMax = m_nMaxSize + m_nGrowBy; // granularity
  62. else
  63. nNewMax = nNewSize; // no slush
  64. #ifdef SIZE_T_MAX
  65. ASSERT((long)nNewMax * sizeof(DWORD) <= SIZE_T_MAX); // no overflow
  66. #endif
  67. DWORD* pNewData = (DWORD*) new BYTE[nNewMax * sizeof(DWORD)];
  68. // copy new data from old
  69. memcpy(pNewData, m_pData, m_nSize * sizeof(DWORD));
  70. // construct remaining elements
  71. ASSERT(nNewSize > m_nSize);
  72. memset(&pNewData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(DWORD));
  73. // get rid of old stuff (note: no destructors called)
  74. delete (BYTE*)m_pData;
  75. m_pData = pNewData;
  76. m_nSize = nNewSize;
  77. m_nMaxSize = nNewMax;
  78. }
  79. }
  80. void CDWordArray::FreeExtra()
  81. {
  82. ASSERT_VALID(this);
  83. if (m_nSize != m_nMaxSize)
  84. {
  85. // shrink to desired size
  86. #ifdef SIZE_T_MAX
  87. ASSERT((long)m_nSize * sizeof(DWORD) <= SIZE_T_MAX); // no overflow
  88. #endif
  89. DWORD* pNewData = NULL;
  90. if (m_nSize != 0)
  91. {
  92. pNewData = (DWORD*) new BYTE[m_nSize * sizeof(DWORD)];
  93. // copy new data from old
  94. memcpy(pNewData, m_pData, m_nSize * sizeof(DWORD));
  95. }
  96. // get rid of old stuff (note: no destructors called)
  97. delete (BYTE*)m_pData;
  98. m_pData = pNewData;
  99. m_nMaxSize = m_nSize;
  100. }
  101. }
  102. /////////////////////////////////////////////////////////////////////////////
  103. void CDWordArray::SetAtGrow(int nIndex, DWORD newElement)
  104. {
  105. ASSERT_VALID(this);
  106. ASSERT(nIndex >= 0);
  107. if (nIndex >= m_nSize)
  108. SetSize(nIndex+1);
  109. m_pData[nIndex] = newElement;
  110. }
  111. void CDWordArray::InsertAt(int nIndex, DWORD newElement, int nCount /*=1*/)
  112. {
  113. ASSERT_VALID(this);
  114. ASSERT(nIndex >= 0); // will expand to meet need
  115. ASSERT(nCount > 0); // zero or negative size not allowed
  116. if (nIndex >= m_nSize)
  117. {
  118. // adding after the end of the array
  119. SetSize(nIndex + nCount); // grow so nIndex is valid
  120. }
  121. else
  122. {
  123. // inserting in the middle of the array
  124. int nOldSize = m_nSize;
  125. SetSize(m_nSize + nCount); // grow it to new size
  126. // shift old data up to fill gap
  127. memmove(&m_pData[nIndex+nCount], &m_pData[nIndex],
  128. (nOldSize-nIndex) * sizeof(DWORD));
  129. // re-init slots we copied from
  130. memset(&m_pData[nIndex], 0, nCount * sizeof(DWORD));
  131. }
  132. // insert new value in the gap
  133. ASSERT(nIndex + nCount <= m_nSize);
  134. while (nCount--)
  135. m_pData[nIndex++] = newElement;
  136. }
  137. void CDWordArray::RemoveAt(int nIndex, int nCount /* = 1 */)
  138. {
  139. ASSERT_VALID(this);
  140. ASSERT(nIndex >= 0);
  141. ASSERT(nCount >= 0);
  142. ASSERT(nIndex + nCount <= m_nSize);
  143. // just remove a range
  144. int nMoveCount = m_nSize - (nIndex + nCount);
  145. if (nMoveCount)
  146. memcpy(&m_pData[nIndex], &m_pData[nIndex + nCount],
  147. nMoveCount * sizeof(DWORD));
  148. m_nSize -= nCount;
  149. }
  150. void CDWordArray::InsertAt(int nStartIndex, CDWordArray* pNewArray)
  151. {
  152. ASSERT_VALID(this);
  153. ASSERT(pNewArray != NULL);
  154. ASSERT(pNewArray->IsKindOf(RUNTIME_CLASS(CDWordArray)));
  155. ASSERT_VALID(pNewArray);
  156. ASSERT(nStartIndex >= 0);
  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. }