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.3 KiB

  1. //
  2. // CLUAArray implementation.
  3. //
  4. template <typename TYPE>
  5. CLUAArray<TYPE>::CLUAArray()
  6. :
  7. m_cElements(0),
  8. m_cMax(0),
  9. m_pData(NULL)
  10. {
  11. }
  12. template <typename TYPE>
  13. CLUAArray<TYPE>::~CLUAArray()
  14. {
  15. SetSize(0);
  16. }
  17. template <typename TYPE>
  18. DWORD CLUAArray<TYPE>::GetSize() const
  19. {
  20. return m_cElements;
  21. }
  22. template <typename TYPE>
  23. DWORD CLUAArray<TYPE>::GetAllocSize() const
  24. {
  25. return m_cMax;
  26. }
  27. template <typename TYPE>
  28. bool CLUAArray<TYPE>::IsEmpty() const
  29. {
  30. return (m_cElements ? false : true);
  31. }
  32. template <typename TYPE>
  33. VOID CLUAArray<TYPE>::SetSize(DWORD iNewSize)
  34. {
  35. ASSERT(iNewSize >= 0, "Size cannot be negative");
  36. if (iNewSize)
  37. {
  38. if (m_pData)
  39. {
  40. // we already allocated enough space.
  41. if (iNewSize <= m_cMax)
  42. {
  43. if (iNewSize < m_cElements)
  44. {
  45. DestructElements(m_pData + iNewSize, m_cElements - iNewSize);
  46. }
  47. else
  48. {
  49. ConstructElements(m_pData + m_cElements, iNewSize - m_cElements);
  50. }
  51. m_cElements = iNewSize;
  52. }
  53. else // we don't have enough space.
  54. {
  55. // we allocate double of the requested size.
  56. m_cMax = iNewSize * 2;
  57. TYPE* pNewData = (TYPE*) new BYTE [m_cMax * sizeof(TYPE)];
  58. memcpy(pNewData, m_pData, m_cElements * sizeof(TYPE));
  59. ConstructElements(pNewData + m_cElements, iNewSize - m_cElements);
  60. delete [] (BYTE*)m_pData;
  61. m_pData = pNewData;
  62. m_cElements = iNewSize;
  63. }
  64. }
  65. else // it's an empty array, we need to allocate spaces for iNewSize elements.
  66. {
  67. m_pData = (TYPE*) new BYTE [iNewSize * sizeof(TYPE)];
  68. ConstructElements(m_pData, iNewSize);
  69. m_cElements = m_cMax = iNewSize;
  70. }
  71. }
  72. else // if it's 0, we should destroy all the Elements in the array.
  73. {
  74. if (m_pData)
  75. {
  76. DestructElements(m_pData, m_cElements);
  77. delete [] (BYTE*)m_pData;
  78. m_pData = NULL;
  79. }
  80. m_cElements = 0;
  81. }
  82. }
  83. template <typename TYPE>
  84. VOID CLUAArray<TYPE>::SetAtGrow(DWORD iIndex, TYPE newElement)
  85. {
  86. ASSERT(iIndex >= 0, "Index cannot be negative");
  87. if (iIndex >= m_cElements)
  88. {
  89. SetSize(iIndex + 1);
  90. }
  91. m_pData[iIndex] = newElement;
  92. }
  93. template <typename TYPE>
  94. DWORD CLUAArray<TYPE>::Add(TYPE newElement)
  95. {
  96. SetAtGrow(m_cElements, newElement);
  97. return m_cElements;
  98. }
  99. template <typename TYPE>
  100. DWORD CLUAArray<TYPE>::Append(const CLUAArray& src)
  101. {
  102. ASSERT(this != &src, "Cannot append to itself");
  103. DWORD nOldSize = m_cElements;
  104. SetSize(m_cElements + src.m_cElements);
  105. CopyElements(m_pData + nOldSize, src.m_pData, src.m_cElements);
  106. return nOldSize;
  107. }
  108. template <typename TYPE>
  109. VOID CLUAArray<TYPE>::Copy(const CLUAArray& src)
  110. {
  111. ASSERT(this != &src, "Cannot copy to itself");
  112. SetSize(src.m_cElements);
  113. CopyElements(m_pData, src.m_pData, src.m_cElements);
  114. }
  115. template <typename TYPE>
  116. VOID CLUAArray<TYPE>::RemoveAt(DWORD iIndex, DWORD nCount)
  117. {
  118. ASSERT(iIndex >= 0, "Index cannot be negative");
  119. ASSERT(nCount >= 0, "Count cannot be negative");
  120. ASSERT(iIndex + nCount <= m_nSize, "Requested to remove too many items");
  121. // just remove a range
  122. int nMoveCount = m_nSize - (iIndex + nCount);
  123. if (nMoveCount)
  124. {
  125. memcpy(&m_pData[iIndex], &m_pData[iIndex + nCount],
  126. nMoveCount * sizeof(BYTE));
  127. }
  128. m_nSize -= nCount;
  129. }
  130. template <typename TYPE>
  131. const TYPE& CLUAArray<TYPE>::operator[](DWORD iIndex) const
  132. {
  133. ASSERT(iIndex >= 0 && iIndex < m_cElements, "Index out of bound");
  134. return m_pData[iIndex];
  135. }
  136. template <typename TYPE>
  137. TYPE& CLUAArray<TYPE>::operator[](DWORD iIndex)
  138. {
  139. ASSERT(iIndex >= 0 && iIndex < m_cElements, "Index out of bound");
  140. return m_pData[iIndex];
  141. }
  142. template <typename TYPE>
  143. const TYPE& CLUAArray<TYPE>::GetAt(DWORD iIndex) const
  144. {
  145. ASSERT(iIndex >= 0 && iIndex < m_cElements, "Index out of bound");
  146. return m_pData[iIndex];
  147. }
  148. template <typename TYPE>
  149. TYPE& CLUAArray<TYPE>::GetAt(DWORD iIndex)
  150. {
  151. ASSERT(iIndex >= 0 && iIndex < m_cElements, "Index out of bound");
  152. return m_pData[iIndex];
  153. }
  154. template <typename TYPE>
  155. VOID CLUAArray<TYPE>::DestructElements(TYPE* pElements, DWORD nCount)
  156. {
  157. for (; nCount--; pElements++)
  158. {
  159. pElements->~TYPE();
  160. }
  161. }
  162. //
  163. // define placement new and delete.
  164. //
  165. inline void *__cdecl operator new(size_t, void *P)
  166. {
  167. return (P);
  168. }
  169. inline void __cdecl operator delete(void *, void *)
  170. {
  171. return;
  172. }
  173. template <typename TYPE>
  174. VOID CLUAArray<TYPE>::ConstructElements(TYPE* pElements, DWORD nCount)
  175. {
  176. // we zero memory first here.
  177. memset(pElements, 0, nCount * sizeof(TYPE));
  178. for (; nCount--; pElements++)
  179. {
  180. new (pElements) TYPE;
  181. }
  182. }
  183. template <typename TYPE>
  184. VOID CLUAArray<TYPE>::CopyElements(TYPE* pDest, const TYPE* pSrc, DWORD nCount)
  185. {
  186. while (nCount--)
  187. {
  188. *pDest++ = *pSrc++;
  189. }
  190. }