Source code of Windows XP (NT5)
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.

184 lines
5.0 KiB

  1. #ifndef __VPTRARRAY_HPP
  2. #define __VPTRARRAY_HPP
  3. #include "vStandard.h"
  4. #define VPTRARRAY_ELEMENT ULONG_PTR
  5. // <VDOC<CLASS=VPtrArray><DESC=Collection of unknown 4 byte types (FAR pointers)><FAMILY=Collections><AUTHOR=Todd Osborne ([email protected])>VDOC>
  6. class VPtrArray
  7. {
  8. public:
  9. VPtrArray()
  10. { m_lpData = NULL; m_nSize = 0; }
  11. virtual ~VPtrArray()
  12. { RemoveAll(); }
  13. // Same as At(nIndex)
  14. LPVOID operator [] (int nIndex)
  15. { return At(nIndex); }
  16. // Same as Add()
  17. int operator + (LPVOID lpData)
  18. { return Add(lpData); }
  19. // Same as FindAndRemove()
  20. int operator - (LPVOID lpData)
  21. { return FindAndRemove(lpData); }
  22. // Add a new element at the end of the array. Returns index into array on success, -1 on failure
  23. int Add(LPVOID lpData)
  24. {
  25. if ( AllocCopy(m_nSize + 1, -1, -1) )
  26. {
  27. m_lpData[m_nSize - 1] = (VPTRARRAY_ELEMENT)lpData;
  28. return m_nSize - 1;
  29. }
  30. return -1;
  31. }
  32. // Return element at given index
  33. LPVOID At(int nIndex)
  34. { assert(nIndex >= 0 && nIndex < m_nSize); return (LPVOID)m_lpData[nIndex]; }
  35. // Set element at given index. This does not allocate memory, that must already have been done by Add(), Size(), or +
  36. void At(int nIndex, LPVOID lpData)
  37. { assert(nIndex >= 0 && nIndex < m_nSize); m_lpData[nIndex] = (VPTRARRAY_ELEMENT)lpData; }
  38. // Return the index into array for first occurence of lpData, or -1 if not found
  39. int Find(LPVOID lpData)
  40. {
  41. int nResult = -1;
  42. for ( int i = 0; i < m_nSize; i++ )
  43. {
  44. if ( m_lpData[i] == (VPTRARRAY_ELEMENT)lpData )
  45. {
  46. nResult = i;
  47. break;
  48. }
  49. }
  50. return nResult;
  51. }
  52. // Find and remove element from array. Returns TRUE on success, FALSE on failure
  53. BOOL FindAndRemove(LPVOID lpData)
  54. { int nIndex = Find(lpData); return (nIndex != -1) ? RemoveAt(nIndex) : FALSE; }
  55. // Insert a new element into the array at specified index, moving everything after
  56. // it further into the array. Returns index on success, -1 on failure
  57. int InsertAt(int nIndex, LPVOID lpData)
  58. {
  59. assert(nIndex <= m_nSize);
  60. // Add item first to end
  61. if ( Add(lpData) != - 1 )
  62. {
  63. if ( nIndex < m_nSize - 1 )
  64. {
  65. // Shift memory up in array
  66. MoveMemory( &m_lpData[nIndex + 1],
  67. &m_lpData[nIndex],
  68. sizeof(VPTRARRAY_ELEMENT) * (m_nSize - nIndex - 1));
  69. // Set lpData where told to
  70. m_lpData[nIndex] = (VPTRARRAY_ELEMENT)lpData;
  71. }
  72. return nIndex;
  73. }
  74. return -1;
  75. }
  76. // Remove all elements from array
  77. void RemoveAll()
  78. { delete [] m_lpData; m_lpData = NULL; m_nSize = 0; }
  79. // Remove a single element from the array. All other elements will be shifted down one slot
  80. BOOL RemoveAt(int nIndex)
  81. { return RemoveRange(nIndex, nIndex); }
  82. // Remove multiple elements from the array. All other elements will be shifted down by the number of elements removed
  83. BOOL RemoveRange(int nIndexStart, int nIndexEnd)
  84. {
  85. assert(nIndexStart >= 0 && nIndexStart < m_nSize && nIndexEnd >= nIndexStart);
  86. int nSize = m_nSize;
  87. return (AllocCopy(m_nSize - ((nIndexEnd - nIndexStart) + 1), nIndexStart, nIndexEnd) && m_nSize != nSize) ? TRUE : FALSE;
  88. }
  89. // Get / Set the size of the array (number of elements). Returns TRUE on success, FALSE on failure
  90. // Elements currently in array will be preserved, unless array is skrinking, in which
  91. // case element(s) at the end of the current array will be truncated
  92. BOOL Size(int nSize)
  93. { assert(nSize >= 0); return AllocCopy(nSize , -1, -1); }
  94. int Size()
  95. { return m_nSize; }
  96. protected:
  97. // Internal function to work with private data
  98. BOOL AllocCopy(int nNewSize, int nSkipIndexStart, int nSkipIndexEnd)
  99. {
  100. VPTRARRAY_ELEMENT* lpNewData = (nNewSize) ? new VPTRARRAY_ELEMENT[nNewSize] : NULL;
  101. // If memory allocation was required and did not succeed, exit now with error
  102. if ( nNewSize && !lpNewData )
  103. return FALSE;
  104. if ( lpNewData )
  105. {
  106. #ifdef _DEBUG
  107. // Data but no size!
  108. if ( m_lpData )
  109. assert(m_nSize);
  110. #endif
  111. // Clear new memory
  112. ZeroMemory(lpNewData, nNewSize * sizeof(VPTRARRAY_ELEMENT));
  113. // Copy any previous memory
  114. if ( m_nSize )
  115. {
  116. // There must be data!
  117. assert(m_lpData);
  118. // If either skip index is -1, we will copy everything
  119. // -1 is used internally as a flag to indicate no exclusions
  120. if ( nSkipIndexStart == -1 || nSkipIndexEnd == -1 )
  121. CopyMemory(lpNewData, m_lpData, min(m_nSize, nNewSize) * sizeof(VPTRARRAY_ELEMENT));
  122. else
  123. {
  124. // Copy up to nSkipIndexStart
  125. if ( nSkipIndexStart )
  126. CopyMemory(&lpNewData[0], &m_lpData[0], nSkipIndexStart * sizeof(VPTRARRAY_ELEMENT));
  127. // Copy from nSkipIndexEnd + 1 to end
  128. CopyMemory( &lpNewData [nSkipIndexStart],
  129. &m_lpData [nSkipIndexEnd + 1],
  130. (m_nSize * sizeof(VPTRARRAY_ELEMENT)) - ((nSkipIndexEnd + 1) * sizeof(VPTRARRAY_ELEMENT)));
  131. }
  132. }
  133. }
  134. // Kill any current memory
  135. delete [] m_lpData;
  136. // Make new assignments
  137. m_lpData = lpNewData;
  138. m_nSize = nNewSize;
  139. return TRUE;
  140. }
  141. private:
  142. // Embedded Members
  143. VPTRARRAY_ELEMENT* m_lpData;
  144. int m_nSize;
  145. };
  146. #endif // __VPTRARRAY_HPP