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.

394 lines
12 KiB

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Filename : VarBuff.h
  4. // Purpose : To hold the definition for the variable length buffer.
  5. // One should remember not to take pointers into the buffer
  6. // since it can be reallocated automatically.
  7. // Errors are reported via exceptions (CMemoryException()).
  8. //
  9. // Project : FTFS
  10. // Component:
  11. //
  12. // Author : urib
  13. //
  14. // Log:
  15. // Feb 2 1997 urib Creation
  16. // Feb 25 1997 urib Fix compilation error in constructor.
  17. // Jan 26 1999 urib Allow zero initial size.
  18. // May 1 2000 urib Allow specification of allocated size.
  19. // May 14 2000 urib Add support for embedded initial array.
  20. //
  21. ////////////////////////////////////////////////////////////////////////////////
  22. #ifndef VARBUFF_H
  23. #define VARBUFF_H
  24. #include "Excption.h"
  25. #include "AutoPtr.h"
  26. ////////////////////////////////////////////////////////////////////////////////
  27. //
  28. // CVarBuffer class definition
  29. //
  30. ////////////////////////////////////////////////////////////////////////////////
  31. template<class T, ULONG ulInitialEmbeddedSizeInItems = 1>
  32. class CVarBuffer
  33. {
  34. public:
  35. // Constructor
  36. CVarBuffer(ULONG ulInitialSizeInItems = 0,
  37. ULONG ulInitialAllocatedSizeInItems = 10);
  38. // Concatenates the given buffer to this buffer.
  39. void Cat(ULONG ulItems, T* pMemory);
  40. // Copies the given buffer to this buffer.
  41. void Cpy(ULONG ulItems, T* pMemory);
  42. // Return the buffer's memory.
  43. T* GetBuffer();
  44. // Returns the buffer's size. The size is set by the initial value given to
  45. // the constructor, Cat, Cpy, operations beyond the current size or Calls
  46. // to the SetSize function.
  47. ULONG GetSize();
  48. // Set the buffer minimal size.
  49. void SetSize(ULONG ulNewSizeInItems);
  50. // Act as a buffer.
  51. operator T*();
  52. protected:
  53. // This function enlarges the array.
  54. void Double();
  55. bool IsAllocated();
  56. T* GetEmbeddedArray();
  57. // A pointer to the buffer
  58. CAutoMallocPointer<T> m_aptBuffer;
  59. // An embedded initial buffer
  60. byte m_rbEmbeddedBuffer[ulInitialEmbeddedSizeInItems * sizeof(T)];
  61. // The used portion of the buffer.
  62. ULONG m_ulSizeInItems;
  63. // The allocated portion of the buffer.
  64. ULONG m_ulAllocatedInItems;
  65. };
  66. //////////////////////////////////////////////////////////////////////////////*/
  67. //
  68. // CVarBuffer class implementation
  69. //
  70. //////////////////////////////////////////////////////////////////////////////*/
  71. ////////////////////////////////////////////////////////////////////////////////
  72. //
  73. // Name : CVarBuffer<T, ulInitialEmbeddedSizeInItems>::CVarBuffer
  74. // Purpose : Initialize the buffer, allocate memory.
  75. // Set the used buffer size to be ulInitialSizeInItems.
  76. // May throw a CMemoryException on low memory.
  77. //
  78. // Parameters:
  79. // [in] ULONG ulInitialSizeInItems
  80. //
  81. // Returns : [N/A]
  82. //
  83. // Log:
  84. // Feb 25 1997 urib Creation
  85. // Jan 28 1999 urib Allow 0 size buffers.
  86. // May 1 2000 urib Allow specification of allocated size.
  87. //
  88. ////////////////////////////////////////////////////////////////////////////////
  89. template<class T, ULONG ulInitialEmbeddedSizeInItems>
  90. inline
  91. CVarBuffer<T, ulInitialEmbeddedSizeInItems>::CVarBuffer(
  92. ULONG ulInitialSizeInItems,
  93. ULONG ulInitialAllocatedSizeInItems)
  94. :m_aptBuffer(GetEmbeddedArray(), false)
  95. ,m_ulSizeInItems(ulInitialSizeInItems)
  96. ,m_ulAllocatedInItems(ulInitialEmbeddedSizeInItems)
  97. {
  98. //
  99. // Allocation cannot be smaller than size.
  100. //
  101. if (ulInitialAllocatedSizeInItems < ulInitialSizeInItems)
  102. {
  103. ulInitialAllocatedSizeInItems = ulInitialSizeInItems;
  104. }
  105. //
  106. // Allocate if needed.
  107. //
  108. if (m_ulAllocatedInItems < ulInitialAllocatedSizeInItems)
  109. {
  110. m_aptBuffer = (T*) malloc (sizeof(T) * ulInitialAllocatedSizeInItems);
  111. if(!m_aptBuffer.IsValid())
  112. {
  113. THROW_MEMORY_EXCEPTION();
  114. }
  115. m_ulAllocatedInItems = ulInitialAllocatedSizeInItems;
  116. }
  117. }
  118. /*//////////////////////////////////////////////////////////////////////////////
  119. //
  120. // Name : CVarBuffer<T, ulInitialEmbeddedSizeInItems>::Cat
  121. // Purpose : Concatenate this memory to the buffer's end. Reallocates
  122. // if needed. Sets the size to the size before the
  123. // call + ulItems.
  124. // May throw a CMemoryException on low memory.
  125. //
  126. // Parameters:
  127. // [in] ULONG ulItems
  128. // [in] T* ptMemory
  129. //
  130. // Returns : [N/A]
  131. //
  132. // Log:
  133. // Feb 25 1997 urib Creation
  134. //
  135. //////////////////////////////////////////////////////////////////////////////*/
  136. template<class T, ULONG ulInitialEmbeddedSizeInItems>
  137. inline
  138. void
  139. CVarBuffer<T, ulInitialEmbeddedSizeInItems>::Cat(ULONG ulItems, T* ptMemory)
  140. {
  141. // Remember the size before changing it
  142. ULONG ulLastSize = m_ulSizeInItems;
  143. // Change the size - allocate if needed
  144. SetSize(m_ulSizeInItems + ulItems);
  145. // Copy the new data to the buffer
  146. memcpy(GetBuffer() + ulLastSize, ptMemory, ulItems * sizeof(T));
  147. }
  148. /*//////////////////////////////////////////////////////////////////////////////
  149. //
  150. // Name : CVarBuffer<T, ulInitialEmbeddedSizeInItems>::Cpy
  151. // Purpose : Copy this memory to the buffer (from the beginning).
  152. // Set the used buffer size to be ulItems.
  153. // May throw a CMemoryException on low memory.
  154. //
  155. // Parameters:
  156. // [in] ULONG ulItems
  157. // [in] T* ptMemory
  158. //
  159. // Returns : [N/A]
  160. //
  161. // Log:
  162. // Feb 25 1997 urib Creation
  163. //
  164. //////////////////////////////////////////////////////////////////////////////*/
  165. template<class T, ULONG ulInitialEmbeddedSizeInItems>
  166. inline
  167. void
  168. CVarBuffer<T, ulInitialEmbeddedSizeInItems>::Cpy(ULONG ulItems, T* ptMemory)
  169. {
  170. m_ulSizeInItems = 0;
  171. Cat(ulItems, ptMemory);
  172. }
  173. /*//////////////////////////////////////////////////////////////////////////////
  174. //
  175. // Name : CVarBuffer<T, ulInitialEmbeddedSizeInItems>::GetBuffer
  176. // Purpose : Return the actual memory. Don't save the return value in a
  177. // pointer since the buffer may reallocate. Save the offset.
  178. //
  179. // Parameters:
  180. // [N/A]
  181. //
  182. // Returns : T* - the buffer.
  183. //
  184. // Log:
  185. // Feb 25 1997 urib Creation
  186. //
  187. //////////////////////////////////////////////////////////////////////////////*/
  188. template<class T, ULONG ulInitialEmbeddedSizeInItems>
  189. inline
  190. T*
  191. CVarBuffer<T, ulInitialEmbeddedSizeInItems>::GetBuffer()
  192. {
  193. return m_aptBuffer.Get();
  194. }
  195. /*//////////////////////////////////////////////////////////////////////////////
  196. //
  197. // Name : CVarBuffer<T, ulInitialEmbeddedSizeInItems>::GetSize
  198. // Purpose : Return the size of the buffer. The return value of this
  199. // function is set by SetSize, Cpy, Cat, and the size
  200. // specified in the constructor.
  201. //
  202. // Parameters:
  203. // [N/A]
  204. //
  205. // Returns : ULONG
  206. //
  207. // Log:
  208. // Feb 25 1997 urib Creation
  209. //
  210. //////////////////////////////////////////////////////////////////////////////*/
  211. template<class T, ULONG ulInitialEmbeddedSizeInItems>
  212. inline
  213. ULONG
  214. CVarBuffer<T, ulInitialEmbeddedSizeInItems>::GetSize()
  215. {
  216. return m_ulSizeInItems;
  217. }
  218. /*//////////////////////////////////////////////////////////////////////////////
  219. //
  220. // Name : CVarBuffer<T, ulInitialEmbeddedSizeInItems>::SetSize
  221. // Purpose : Sets the size in items to be ulNewSizeInItems.
  222. // May throw a CMemoryException on low memory.
  223. //
  224. // Parameters:
  225. // [in] ULONG ulNewSizeInItems
  226. //
  227. // Returns : [N/A]
  228. //
  229. // Log:
  230. // Feb 25 1997 urib Creation
  231. //
  232. //////////////////////////////////////////////////////////////////////////////*/
  233. template<class T, ULONG ulInitialEmbeddedSizeInItems>
  234. inline
  235. void
  236. CVarBuffer<T, ulInitialEmbeddedSizeInItems>::SetSize(ULONG ulNewSizeInItems)
  237. {
  238. // While the buffer is not in the proper size keep growing.
  239. while (ulNewSizeInItems > m_ulAllocatedInItems)
  240. Double();
  241. // OK. We're big. Set the size.
  242. m_ulSizeInItems = ulNewSizeInItems;
  243. }
  244. /*//////////////////////////////////////////////////////////////////////////////
  245. //
  246. // Name : CVarBuffer<T, ulInitialEmbeddedSizeInItems>::operator void*()
  247. // Purpose : To return a pointer to the buffer.
  248. //
  249. // Parameters:
  250. // [N/A]
  251. //
  252. // Returns : T*
  253. //
  254. // Log:
  255. // Feb 25 1997 urib Creation
  256. //
  257. //////////////////////////////////////////////////////////////////////////////*/
  258. template<class T, ULONG ulInitialEmbeddedSizeInItems>
  259. inline
  260. CVarBuffer<T, ulInitialEmbeddedSizeInItems>::operator T*()
  261. {
  262. return GetBuffer();
  263. }
  264. /*//////////////////////////////////////////////////////////////////////////////
  265. //
  266. // Name : CVarBuffer<T, ulInitialEmbeddedSizeInItems>::Double
  267. // Purpose : Double the alocated memory size. Not the used size.
  268. // May throw a CMemoryException on low memory.
  269. //
  270. // Parameters:
  271. // [N/A]
  272. //
  273. // Returns : [N/A]
  274. //
  275. // Log:
  276. // Feb 25 1997 urib Creation
  277. //
  278. //////////////////////////////////////////////////////////////////////////////*/
  279. template<class T, ULONG ulInitialEmbeddedSizeInItems>
  280. inline
  281. void
  282. CVarBuffer<T, ulInitialEmbeddedSizeInItems>::Double()
  283. {
  284. ULONG ulNewAllocatedSizeInItems = 2 * m_ulAllocatedInItems;
  285. T* ptTemp;
  286. if (!IsAllocated())
  287. {
  288. ptTemp = (T*)malloc(ulNewAllocatedSizeInItems * sizeof(T));
  289. if (!ptTemp)
  290. {
  291. THROW_MEMORY_EXCEPTION();
  292. }
  293. memcpy(ptTemp, m_aptBuffer.Get(), m_ulSizeInItems * sizeof(T));
  294. }
  295. else
  296. {
  297. ptTemp = (T*)realloc(m_aptBuffer.Get(),
  298. ulNewAllocatedSizeInItems * sizeof(T));
  299. if (!ptTemp)
  300. {
  301. THROW_MEMORY_EXCEPTION();
  302. }
  303. m_aptBuffer.Detach();
  304. }
  305. m_aptBuffer = ptTemp;
  306. m_ulAllocatedInItems = ulNewAllocatedSizeInItems;
  307. }
  308. ////////////////////////////////////////////////////////////////////////////////
  309. //
  310. // Name : CVarBuffer<T, ulInitialEmbeddedSizeInItems>::::IsAllocated()
  311. // Purpose : A predicate to easily test if we still use the embedded
  312. // array or not.
  313. //
  314. // Parameters:
  315. // [N/A]
  316. //
  317. // Returns : bool - true - an alternative array was allocated.
  318. //
  319. // Log:
  320. // May 14 2000 urib Creation
  321. //
  322. ////////////////////////////////////////////////////////////////////////////////
  323. template<class T, ULONG ulInitialEmbeddedSizeInItems>
  324. inline
  325. bool
  326. CVarBuffer<T, ulInitialEmbeddedSizeInItems>::IsAllocated()
  327. {
  328. return m_aptBuffer.Get() != GetEmbeddedArray();
  329. }
  330. ////////////////////////////////////////////////////////////////////////////////
  331. //
  332. // Name : CVarBuffer<T, ulIni...zeInItems>::GetEmbeddedArray()
  333. // Purpose : Return the embedded array.
  334. //
  335. // Parameters:
  336. // [N/A]
  337. //
  338. // Returns : [N/A]
  339. //
  340. // Log:
  341. // May 14 2000 urib Creation
  342. //
  343. ////////////////////////////////////////////////////////////////////////////////
  344. template<class T, ULONG ulInitialEmbeddedSizeInItems>
  345. inline
  346. T*
  347. CVarBuffer<T, ulInitialEmbeddedSizeInItems>::GetEmbeddedArray()
  348. {
  349. return (T*) m_rbEmbeddedBuffer;
  350. }
  351. #endif /* VARBUFF_H */