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.

513 lines
9.4 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. buffers
  5. Abstract:
  6. This header file provides dynamic buffer and string classes for general use.
  7. Author:
  8. Doug Barlow (dbarlow) 10/5/1995
  9. Environment:
  10. Win32
  11. Notes:
  12. --*/
  13. #ifndef _BUFFERS_H_
  14. #define _BUFFERS_H_
  15. #include <string.h>
  16. #include "memCheck.h"
  17. //
  18. //==============================================================================
  19. //
  20. // CBuffer
  21. //
  22. class CBuffer
  23. {
  24. public:
  25. // Constructors & Destructor
  26. CBuffer() // Default Initializer
  27. { Initialize(); };
  28. CBuffer( // Initialize with starting length.
  29. IN DWORD cbLength)
  30. { Initialize();
  31. Presize(cbLength, FALSE); };
  32. CBuffer( // Initialize with starting data.
  33. IN const BYTE * const pbSource,
  34. IN DWORD cbLength)
  35. { Initialize();
  36. Set(pbSource, cbLength); };
  37. virtual ~CBuffer() // Tear down.
  38. { Clear(); };
  39. // Properties
  40. // Methods
  41. void
  42. Clear(void); // Free up any allocated memory.
  43. LPBYTE
  44. Reset(void); // Return to default state (don't loose memory.)
  45. LPBYTE
  46. Presize( // Make sure the buffer is big enough.
  47. IN DWORD cbLength,
  48. IN BOOL fPreserve = FALSE);
  49. LPBYTE
  50. Resize( // Make sure the buffer & length are the right size.
  51. DWORD cbLength,
  52. BOOL fPreserve = FALSE);
  53. LPBYTE
  54. Set( // Load a value.
  55. IN const BYTE * const pbSource,
  56. IN DWORD cbLength);
  57. LPBYTE
  58. Append( // Append more data to the existing data.
  59. IN const BYTE * const pbSource,
  60. IN DWORD cbLength);
  61. DWORD
  62. Length( // Return the length of the data.
  63. void) const
  64. { return m_cbDataLength; };
  65. LPBYTE
  66. Access( // Return the data, starting at an offset.
  67. DWORD offset = 0)
  68. const
  69. { if (m_cbDataLength <= offset) return NULL;
  70. else return &m_pbBuffer[offset]; };
  71. int
  72. Compare(
  73. const CBuffer &bfSource)
  74. const;
  75. // Operators
  76. CBuffer &
  77. operator=(
  78. IN const CBuffer &bfSource)
  79. { Set(bfSource.m_pbBuffer, bfSource.m_cbDataLength);
  80. return *this; };
  81. CBuffer &
  82. operator+=(
  83. IN const CBuffer &bfSource)
  84. { Append(bfSource.m_pbBuffer, bfSource.m_cbDataLength);
  85. return *this; };
  86. BYTE &
  87. operator[](
  88. DWORD offset)
  89. const
  90. { return *Access(offset); };
  91. int
  92. operator==(
  93. IN const CBuffer &bfSource)
  94. const
  95. { return 0 == Compare(bfSource); };
  96. int
  97. operator!=(
  98. IN const CBuffer &bfSource)
  99. const
  100. { return 0 != Compare(bfSource); };
  101. protected:
  102. // Properties
  103. LPBYTE m_pbBuffer;
  104. DWORD m_cbDataLength;
  105. DWORD m_cbBufferLength;
  106. // Methods
  107. void
  108. Initialize(void)
  109. {
  110. m_pbBuffer = NULL;
  111. m_cbDataLength = 0;
  112. m_cbBufferLength = 0;
  113. };
  114. CBuffer( // Object assignment constructor.
  115. IN const CBuffer &bfSourceOne,
  116. IN const CBuffer &bfSourceTwo)
  117. {
  118. Initialize();
  119. Presize(bfSourceOne.m_cbDataLength + bfSourceTwo.m_cbDataLength);
  120. Set(bfSourceOne.m_pbBuffer, bfSourceOne.m_cbDataLength);
  121. Append(bfSourceTwo.m_pbBuffer, bfSourceTwo.m_cbDataLength);
  122. };
  123. friend
  124. CBuffer
  125. operator+(
  126. IN const CBuffer &bfSourceOne,
  127. IN const CBuffer &bfSourceTwo);
  128. };
  129. /*++
  130. Clear:
  131. This routine resets a CBuffer to it's initial state, freeing any allocated
  132. memory.
  133. Arguments:
  134. None
  135. Return Value:
  136. None
  137. Author:
  138. Doug Barlow (dbarlow) 10/5/1995
  139. --*/
  140. inline void
  141. CBuffer::Clear(
  142. void)
  143. {
  144. if (NULL != m_pbBuffer)
  145. delete[] m_pbBuffer;
  146. Initialize();
  147. }
  148. /*++
  149. Reset:
  150. This routine logically empties the CBuffer without actually deallocating
  151. memory. It's data lengh goes to zero.
  152. Arguments:
  153. None
  154. Return Value:
  155. The address of the buffer.
  156. Author:
  157. Doug Barlow (dbarlow) 10/5/1995
  158. --*/
  159. inline LPBYTE
  160. CBuffer::Reset(
  161. void)
  162. {
  163. m_cbDataLength = 0;
  164. return m_pbBuffer;
  165. }
  166. /*++
  167. Presize:
  168. This is the primary workhorse of the CBuffer class. It ensures that the
  169. size of the buffer is of the proper size. Data in the buffer may optionally
  170. be preserved, in which case the data length doesn't change. If the buffer
  171. is not preserved, then the data length is reset to zero.
  172. Arguments:
  173. cbLength supplies the desired length of the buffer.
  174. fPreserve supplies a flag indicating whether or not to preserve the current
  175. contents of the buffer.
  176. Return Value:
  177. The address of the properly sized buffer.
  178. Author:
  179. Doug Barlow (dbarlow) 10/5/1995
  180. --*/
  181. inline LPBYTE
  182. CBuffer::Presize(
  183. IN DWORD cbLength,
  184. IN BOOL fPreserve)
  185. {
  186. LPBYTE pbNewBuf = NULL;
  187. if (fPreserve && (0 < m_cbDataLength))
  188. {
  189. //
  190. // Increase the buffer length, and preserve the existing data.
  191. //
  192. if (m_cbBufferLength < cbLength)
  193. {
  194. NEWReason("Buffer contents")
  195. pbNewBuf = new BYTE[cbLength];
  196. if (NULL == pbNewBuf)
  197. goto ErrorExit;
  198. memcpy(pbNewBuf, m_pbBuffer, m_cbDataLength);
  199. delete[] m_pbBuffer;
  200. m_pbBuffer = pbNewBuf;
  201. pbNewBuf = NULL;
  202. m_cbBufferLength = cbLength;
  203. }
  204. }
  205. else
  206. {
  207. //
  208. // Increase the buffer length, but lose any existing data.
  209. //
  210. if (m_cbBufferLength < cbLength)
  211. {
  212. NEWReason("Buffer contents")
  213. pbNewBuf = new BYTE[cbLength];
  214. if (NULL == pbNewBuf)
  215. goto ErrorExit;
  216. if (NULL != m_pbBuffer)
  217. delete[] m_pbBuffer;
  218. m_pbBuffer = pbNewBuf;
  219. pbNewBuf = NULL;
  220. m_cbBufferLength = cbLength;
  221. }
  222. m_cbDataLength = 0;
  223. }
  224. return m_pbBuffer;
  225. ErrorExit:
  226. if (NULL != pbNewBuf)
  227. delete[] pbNewBuf;
  228. return NULL;
  229. }
  230. /*++
  231. Resize:
  232. This method sets the length of the data to the given size. If the buffer
  233. isn't big enough to support that data length, it is enlarged.
  234. Arguments:
  235. cbLength supplies the new length of the data.
  236. fPreserve supplies a flag indicating whether or not to preserve existing
  237. data.
  238. Return Value:
  239. The address of the buffer.
  240. Author:
  241. Doug Barlow (dbarlow) 10/5/1995
  242. --*/
  243. inline LPBYTE
  244. CBuffer::Resize(
  245. DWORD cbLength,
  246. BOOL fPreserve)
  247. {
  248. LPBYTE pb = Presize(cbLength, fPreserve);
  249. if (NULL != pb)
  250. m_cbDataLength = cbLength;
  251. return pb;
  252. }
  253. /*++
  254. Set:
  255. This method sets the contents of the data to the given value. If the buffer
  256. isn't big enough to hold the given data, it is enlarged.
  257. Arguments:
  258. pbSource supplies the data to place in the data buffer.
  259. cbLength supplies the length of that data, in bytes.
  260. Return Value:
  261. The address of the buffer.
  262. Author:
  263. Doug Barlow (dbarlow) 10/5/1995
  264. --*/
  265. inline LPBYTE
  266. CBuffer::Set(
  267. IN const BYTE * const pbSource,
  268. IN DWORD cbLength)
  269. {
  270. LPBYTE pb = Presize(cbLength, FALSE);
  271. if (NULL != pb)
  272. {
  273. if (0 < cbLength)
  274. memcpy(pb, pbSource, cbLength);
  275. m_cbDataLength = cbLength;
  276. }
  277. return pb;
  278. }
  279. /*++
  280. CBuffer::Append:
  281. This method appends the supplied data onto the end of the existing data,
  282. enlarging the buffer if necessary.
  283. Arguments:
  284. pbSource supplies the data to be appended.
  285. cbLength supplies the length of the data to be appended, in bytes.
  286. Return Value:
  287. The address of the buffer.
  288. Author:
  289. Doug Barlow (dbarlow) 10/5/1995
  290. --*/
  291. inline LPBYTE
  292. CBuffer::Append(
  293. IN const BYTE * const pbSource,
  294. IN DWORD cbLength)
  295. {
  296. LPBYTE pb = m_pbBuffer;
  297. if (0 < cbLength)
  298. {
  299. pb = Presize(m_cbDataLength + cbLength, TRUE);
  300. if (NULL != pb)
  301. {
  302. memcpy(&pb[m_cbDataLength], pbSource, cbLength);
  303. m_cbDataLength += cbLength;
  304. }
  305. }
  306. return pb;
  307. }
  308. /*++
  309. CBuffer::Compare:
  310. This method compares the contents of another CBuffer to this one, and
  311. returns a value indicating a comparative value.
  312. Arguments:
  313. bfSource supplies the other buffer.
  314. Return Value:
  315. < 0 - The other buffer is less than this one.
  316. = 0 - The other buffer is identical to this one.
  317. > 0 - The other buffer is greater than this one.
  318. Author:
  319. Doug Barlow (dbarlow) 10/5/1995
  320. --*/
  321. inline int
  322. CBuffer::Compare(
  323. const CBuffer &bfSource)
  324. const
  325. {
  326. if (m_cbDataLength < bfSource.m_cbDataLength)
  327. return *(bfSource.m_pbBuffer + m_cbDataLength);
  328. else if (m_cbDataLength > bfSource.m_cbDataLength)
  329. return *(m_pbBuffer + bfSource.m_cbDataLength);
  330. else if (0 < m_cbDataLength)
  331. return memcmp(m_pbBuffer, bfSource.m_pbBuffer, m_cbDataLength);
  332. else
  333. return 0;
  334. }
  335. /*++
  336. operator+:
  337. This routine is a special operator that allows addition of two CBuffers to
  338. produce a third, a la bfThree = bfOne + bfTwo. It calls the special
  339. protected constructor of CBuffer.
  340. Arguments:
  341. bfSourceOne supplies the first buffer
  342. bfSourceTwo supplies the second buffer
  343. Return Value:
  344. A reference to a temporary CBuffer that is the concatenation of the two
  345. provided buffers.
  346. Author:
  347. Doug Barlow (dbarlow) 10/5/1995
  348. --*/
  349. inline CBuffer
  350. operator+(
  351. IN const CBuffer &bfSourceOne,
  352. IN const CBuffer &bfSourceTwo)
  353. {
  354. return CBuffer(bfSourceOne, bfSourceTwo);
  355. }
  356. #endif // _BUFFERS_H_