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.

174 lines
5.0 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1995 - 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: AutoArray.inl
  6. * Content: CAutoArray methods
  7. *
  8. * History:
  9. * Date By Reason
  10. * ====== == ======
  11. * 12-12-2001 simonpow Created
  12. ***************************************************************************/
  13. template <class T>
  14. void CAutoArray<T>::SetExistingElements(DWORD dwIndex, const T * pElemData, DWORD dwNumElem)
  15. {
  16. DNASSERT(dwIndex+dwNumElem<=m_dwSize);
  17. //have to handle the case where pElemData is actually a pointer
  18. //into this arrays data (don't want to overwrite original data
  19. //with copied data prematurely).
  20. //copy from top down if destination is in front of source
  21. T * pDest=m_pData+dwIndex;
  22. if (pDest>pElemData)
  23. {
  24. T * pDestScan=pDest+dwNumElem-1;
  25. pElemData+=(dwNumElem-1);
  26. while (pDestScan>=pDest)
  27. *pDestScan--=*pElemData--;
  28. }
  29. //otherwise it must be bottom up
  30. else
  31. {
  32. T * pDestScan=pDest;
  33. pDest+=dwNumElem;
  34. while (pDestScan<pDest)
  35. *pDestScan++=*pElemData++;
  36. }
  37. }
  38. //make array larger so index falls within its range
  39. //N.B. Caller must have tested that dwIndex>=m_dwSize already!
  40. template <class T>
  41. BOOL CAutoArray<T>::GrowToAtLeast(DWORD dwIndex)
  42. {
  43. //allocate new memory block
  44. DWORD dwNewSize=GetArraySize(dwIndex);
  45. T * pNewData=new T[dwNewSize];
  46. if (!pNewData)
  47. return FALSE;
  48. //if we've got existing data copy it to new block
  49. if (m_pData)
  50. {
  51. for (DWORD dwLoop=0; dwLoop<m_dwSize; dwLoop++)
  52. pNewData[dwLoop]=m_pData[dwLoop];
  53. delete[] m_pData;
  54. }
  55. //set state based on newly allocated block
  56. m_pData=pNewData;
  57. m_dwSize=dwNewSize;
  58. return TRUE;
  59. }
  60. //Set a block of elements in the array
  61. template <class T>
  62. BOOL CAutoArray<T>::SetElements(DWORD dwIndex, const T * pElemData, DWORD dwNumElem)
  63. {
  64. //calculate the top dwIndex+1 we need to touch
  65. DWORD dwCeilingIndex=dwIndex+dwNumElem;
  66. DWORD dwLoop;
  67. //Are we going to exceed current array size
  68. if (dwCeilingIndex<=m_dwSize)
  69. {
  70. //No=easy case, just set new elements
  71. for (dwLoop=dwIndex; dwLoop<dwCeilingIndex; dwLoop++)
  72. m_pData[dwLoop]=*pElemData++;
  73. return TRUE;
  74. }
  75. //need to grow the array, calc size/allocate new array based on the top index
  76. DWORD dwNewSize=GetArraySize(dwCeilingIndex-1);
  77. T * pNewData=new T[dwNewSize];
  78. if (!pNewData)
  79. return FALSE;
  80. //copy in new elements. N.B. We have do this now and not leave it to
  81. //end since elem could be a pointer to our own data. Hence, if we
  82. //wait we'll either have duff data (if we only copied the elements that
  83. //will survive) or we'll risk overwriting elements that we've only
  84. //just copied
  85. for (dwLoop=dwIndex; dwLoop<dwCeilingIndex; dwLoop++)
  86. pNewData[dwLoop]=*pElemData++;
  87. //copy across any old elements, clipping against the block
  88. //of elements just inserted
  89. if (m_pData)
  90. {
  91. if (dwIndex<m_dwSize)
  92. m_dwSize=dwIndex;
  93. for (dwLoop=0; dwLoop<m_dwSize; dwLoop++)
  94. pNewData[dwLoop]=m_pData[dwLoop];
  95. delete[] m_pData;
  96. }
  97. m_pData=pNewData;
  98. m_dwSize=dwNewSize;
  99. return TRUE;
  100. }
  101. //Move a block of elements within the array
  102. template <class T>
  103. BOOL CAutoArray<T>::MoveElements(DWORD dwIndex, DWORD dwNumElements,
  104. DWORD dwNewIndex, BOOL bCopySemantics)
  105. {
  106. DNASSERT(dwIndex+dwNumElements<=m_dwSize);
  107. DWORD dw;
  108. //Are we shifting element block down?
  109. if (dwNewIndex<=dwIndex)
  110. {
  111. //Yes=easy case. Just copy elements from bottom up
  112. for (dw=0; dw<dwNumElements; dw++)
  113. m_pData[dwNewIndex+dw]=m_pData[dwIndex+dw];
  114. return TRUE;
  115. }
  116. //New to move element up. Do we need to grow array?
  117. dw=dwNewIndex+dwNumElements-1;
  118. if (dw<m_dwSize)
  119. {
  120. //No=easy case. Just copy elements top down
  121. dwNewIndex--;
  122. dwIndex--;
  123. for (dw=dwNumElements; dw>0; dw--)
  124. m_pData[dwNewIndex+dw]=m_pData[dwIndex+dw];
  125. return TRUE;
  126. }
  127. //array does need to grow, so create larger array
  128. DWORD dwNewSize=GetArraySize(dw);
  129. T * pNewData=new T[dwNewSize];
  130. if (!pNewData)
  131. return FALSE;
  132. if (m_pData)
  133. {
  134. //copy across block of elements below the
  135. //block we've got to move
  136. for (dw=0; dw<dwIndex; dw++)
  137. pNewData[dw]=m_pData[dw];
  138. //move the block of elements we were originally
  139. //asked to move
  140. for (dw=0; dw<dwNumElements; dw++)
  141. pNewData[dwNewIndex+dw]=m_pData[dwIndex+dw];
  142. //if we were asked to use copy type semantics
  143. //then copy across the portion of the moved block
  144. //that isn't being overwritten in its new position
  145. if (bCopySemantics)
  146. {
  147. for (dw=dwIndex; dw<dwNewIndex; dw++)
  148. pNewData[dw]=m_pData[dw];
  149. }
  150. //move elements above the block we were originally asked
  151. //to move. This copy needs to be clipped against the bottom
  152. //of the moved element block.
  153. if (dwNewIndex<m_dwSize)
  154. m_dwSize=dwNewIndex;
  155. for (dw=dwIndex+dwNumElements; dw<m_dwSize; dw++)
  156. pNewData[dw]=m_pData[dw];
  157. //release the old array memory
  158. delete[] m_pData;
  159. }
  160. m_pData=pNewData;
  161. m_dwSize=dwNewSize;
  162. return TRUE;
  163. }