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.

291 lines
6.3 KiB

  1. //+------------------------------------------------------------
  2. //
  3. // Copyright (C) 1998, Microsoft Corporation
  4. //
  5. // File: simparray.cpp
  6. //
  7. // Contents: Simple growable array class
  8. //
  9. // Classes: CSimpArray
  10. //
  11. // Functions:
  12. //
  13. // History:
  14. // jstamerj 1998/07/14 11:37:25: Created.
  15. //
  16. //-------------------------------------------------------------
  17. #include "precomp.h"
  18. #include "simparray.h"
  19. //+------------------------------------------------------------
  20. //
  21. // Function: CSimpArray::Initialize
  22. //
  23. // Synopsis: Initializes array to a specified size. Only necessary to
  24. // call if you wish to optimize usage by starting with a specified
  25. // array size.
  26. //
  27. // Arguments:
  28. // dwSize: Initial array size
  29. //
  30. // Returns:
  31. // S_OK: Success
  32. // E_OUTOFMEMORY
  33. //
  34. // History:
  35. // jstamerj 1998/07/14 12:22:01: Created.
  36. //
  37. //-------------------------------------------------------------
  38. template <class T> HRESULT CSimpArray<T>::Initialize(
  39. DWORD dwSize)
  40. {
  41. _ASSERT(m_dwArrayAllocSize == 0);
  42. _ASSERT(m_dwArrayClaimedSize == 0);
  43. _ASSERT(m_dwArrayValidSize == 0);
  44. _ASSERT(m_rgData == NULL);
  45. m_rgData = new T [dwSize];
  46. if(m_rgData == NULL) {
  47. return E_OUTOFMEMORY;
  48. } else {
  49. m_dwArrayAllocSize = dwSize;
  50. return S_OK;
  51. }
  52. }
  53. //+------------------------------------------------------------
  54. //
  55. // Function: CSimpArray::Add
  56. //
  57. // Synopsis: Adds one element to the array
  58. //
  59. // Arguments:
  60. // Data: Value to add to the array
  61. //
  62. // Returns:
  63. // S_OK: Success
  64. // E_OUTOFMEMORY
  65. //
  66. // History:
  67. // jstamerj 1998/07/14 15:50:00: Created.
  68. //
  69. //-------------------------------------------------------------
  70. template <class T> HRESULT CSimpArray<T>::Add(
  71. T Data)
  72. {
  73. //
  74. // Same functionality as AddArray except this is an array with
  75. // only one element
  76. //
  77. return AddArray(1, &Data);
  78. }
  79. //+------------------------------------------------------------
  80. //
  81. // Function: CSimpArray::AddArray
  82. //
  83. // Synopsis: Adds an array of T's to our array
  84. //
  85. // Arguments:
  86. // dwSize: size of passed in array
  87. // pData: pointer to array data
  88. //
  89. // Returns:
  90. // S_OK: Success
  91. // E_OUTOFMEMORY
  92. //
  93. // History:
  94. // jstamerj 1998/07/14 12:27:18: Created.
  95. //
  96. //-------------------------------------------------------------
  97. template <class T> HRESULT CSimpArray<T>::AddArray(
  98. DWORD dwSize,
  99. T * pData)
  100. {
  101. HRESULT hr;
  102. DWORD dwCopyIndex;
  103. _ASSERT(dwSize);
  104. _ASSERT(pData);
  105. hr = AllocArrayRange(dwSize, &dwCopyIndex);
  106. if(FAILED(hr))
  107. return hr;
  108. //
  109. // Copy the memory from one array to another
  110. //
  111. CopyMemory(&(m_rgData[dwCopyIndex]), pData, sizeof(T) * dwSize);
  112. //
  113. // Increment array element counter
  114. //NOTE: This really isn't thread safe in the sense that if
  115. //we're in this call and someone is reading the array,
  116. //m_dwArrayValidSize could be invalid.
  117. //
  118. InterlockedExchangeAdd((PLONG) &m_dwArrayValidSize, dwSize);
  119. return S_OK;
  120. }
  121. //+------------------------------------------------------------
  122. //
  123. // Function: AllocArrayRange
  124. //
  125. // Synopsis: Allocates a range on the array for the caller (of unused T's)
  126. //
  127. // Arguments:
  128. // dwSize: Size of the range you'd like
  129. // pdwIndex: On success, starting index of your allocated range
  130. //
  131. // Returns:
  132. // S_OK: Success
  133. // E_OUTOFMEMORY
  134. //
  135. // History:
  136. // jstamerj 1998/07/14 12:37:54: Created.
  137. //
  138. //-------------------------------------------------------------
  139. template <class T> HRESULT CSimpArray<T>::AllocArrayRange(
  140. DWORD dwSize,
  141. PDWORD pdwIndex)
  142. {
  143. HRESULT hr;
  144. _ASSERT(dwSize);
  145. _ASSERT(pdwIndex);
  146. AcquireSpinLock(&m_slAllocate);
  147. hr = ReAllocArrayIfNecessary(m_dwArrayClaimedSize + dwSize);
  148. if(SUCCEEDED(hr)) {
  149. *pdwIndex = m_dwArrayClaimedSize;
  150. m_dwArrayClaimedSize += dwSize;
  151. }
  152. ReleaseSpinLock(&m_slAllocate);
  153. return hr;
  154. }
  155. //+------------------------------------------------------------
  156. //
  157. // Function: CSimpArray::ReAllocArrayIfNecessary
  158. //
  159. // Synopsis: Grow the array size if necessary
  160. // Not thread safe; locking must be done outside
  161. //
  162. // Arguments:
  163. // dwSize: New size desired
  164. //
  165. // Returns:
  166. // S_OK: Success, array grown
  167. // S_FALSE: Success, not necessary to grow array
  168. // E_OUTOFMEMORY
  169. //
  170. // History:
  171. // jstamerj 1998/07/14 13:56:16: Created.
  172. //
  173. //-------------------------------------------------------------
  174. template <class T> HRESULT CSimpArray<T>::ReAllocArrayIfNecessary(
  175. DWORD dwSize)
  176. {
  177. DWORD dwNewSize;
  178. T *pNewArray;
  179. T *pOldArray;
  180. if(dwSize <= m_dwArrayAllocSize)
  181. return S_FALSE;
  182. //
  183. // Calculate new size desired
  184. //
  185. #ifdef CSIMPARRAY_DOUBLE
  186. if(m_dwArrayAllocSize == 0) {
  187. dwNewSize = CSIMPARRAY_DEFAULT_INITIAL_SIZE;
  188. } else {
  189. dwNewSize = m_dwArrayAllocSize;
  190. }
  191. while(dwNewSize < dwSize)
  192. dwNewSize *= 2;
  193. #else
  194. dwNewSize = dwSize;
  195. #endif
  196. _ASSERT(dwNewSize >= dwSize);
  197. pNewArray = new T [dwNewSize];
  198. if(pNewArray == NULL)
  199. return E_OUTOFMEMORY;
  200. CopyMemory(pNewArray, m_rgData, sizeof(T) * m_dwArrayAllocSize);
  201. //
  202. // pNewArray is valid. Make the switch now.
  203. //
  204. pOldArray = m_rgData;
  205. m_rgData = pNewArray;
  206. m_dwArrayAllocSize = dwNewSize;
  207. //
  208. // Release old array memory
  209. //
  210. delete pOldArray;
  211. return S_OK;
  212. }
  213. #ifdef NEVER
  214. //+------------------------------------------------------------
  215. //
  216. // Function: Cat_NeverCalled_SimpArrayTemplateDummy
  217. //
  218. // Synopsis: Dummy function that is never called but forces compiler
  219. // to generate code for desired types
  220. //
  221. // Arguments: NONE
  222. //
  223. // Returns: NOTHING
  224. //
  225. // History:
  226. // jstamerj 1998/07/16 15:28:37: Created.
  227. //
  228. //-------------------------------------------------------------
  229. #include "smtpevent.h"
  230. VOID Cat_NeverCalled_SimpArrayTemplateDummy()
  231. {
  232. _ASSERT(0 && "Never call this function!");
  233. CSimpArray<ICategorizerItem *> csaItem;
  234. CSimpArray<ICategorizerItemAttributes *> csaItemAttributes;
  235. csaItem.Initialize(0);
  236. csaItemAttributes.Initialize(0);
  237. csaItem.Add(NULL);
  238. csaItemAttributes.Add(NULL);
  239. csaItem.AddArray(0, NULL);
  240. csaItemAttributes.AddArray(0, NULL);
  241. }
  242. #endif //NEVER