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.

383 lines
6.7 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1995 - 1999
  3. Module Name:
  4. buffers
  5. Abstract:
  6. This module provides the run time code to support the CBuffer object.
  7. Author:
  8. Doug Barlow (dbarlow) 11/7/1995
  9. Environment:
  10. Win32, C++ w/ Exceptions
  11. Notes:
  12. None
  13. --*/
  14. #ifndef WIN32_LEAN_AND_MEAN
  15. #define WIN32_LEAN_AND_MEAN
  16. #endif
  17. #include <windows.h>
  18. #include <SCardLib.h>
  19. /*++
  20. CBuffer:
  21. This constructor is a special case for use explicitly with the operator+
  22. routine. It builds a CBuffer out of the other two with only a single
  23. allocation.
  24. Arguments:
  25. bfSourceOne supplies the first part of the new buffer
  26. bfSourceTwo supplies the second part of the new buffer.
  27. Return Value:
  28. None
  29. Author:
  30. Doug Barlow (dbarlow) 11/7/1995
  31. --*/
  32. CBuffer::CBuffer( // Object assignment constructor.
  33. IN const CBuffer &bfSourceOne,
  34. IN const CBuffer &bfSourceTwo)
  35. {
  36. Initialize();
  37. Presize(bfSourceOne.m_cbDataLength + bfSourceTwo.m_cbDataLength);
  38. Set(bfSourceOne.m_pbBuffer, bfSourceOne.m_cbDataLength);
  39. Append(bfSourceTwo.m_pbBuffer, bfSourceTwo.m_cbDataLength);
  40. }
  41. /*++
  42. Clear:
  43. This routine resets a CBuffer to it's initial state, freeing any allocated
  44. memory.
  45. Arguments:
  46. None
  47. Return Value:
  48. None
  49. Author:
  50. Doug Barlow (dbarlow) 10/5/1995
  51. --*/
  52. void
  53. CBuffer::Clear(
  54. void)
  55. {
  56. if (NULL != m_pbBuffer)
  57. delete[] m_pbBuffer;
  58. Initialize();
  59. }
  60. /*++
  61. Reset:
  62. This routine logically empties the CBuffer without actually deallocating
  63. memory. It's data lengh goes to zero.
  64. Arguments:
  65. None
  66. Return Value:
  67. The address of the buffer.
  68. Author:
  69. Doug Barlow (dbarlow) 10/5/1995
  70. --*/
  71. LPBYTE
  72. CBuffer::Reset(
  73. void)
  74. {
  75. m_cbDataLength = 0;
  76. return m_pbBuffer;
  77. }
  78. /*++
  79. Presize:
  80. This is the primary workhorse of the CBuffer class. It ensures that the
  81. size of the buffer is of the proper size. Data in the buffer may optionally
  82. be preserved, in which case the data length doesn't change. If the buffer
  83. is not preserved, then the data length is reset to zero.
  84. Arguments:
  85. cbLength supplies the desired length of the buffer.
  86. fPreserve supplies a flag indicating whether or not to preserve the current
  87. contents of the buffer.
  88. Return Value:
  89. The address of the properly sized buffer.
  90. Author:
  91. Doug Barlow (dbarlow) 10/5/1995
  92. --*/
  93. LPBYTE
  94. CBuffer::Presize(
  95. IN DWORD cbLength,
  96. IN BOOL fPreserve)
  97. {
  98. LPBYTE pbNewBuf = NULL;
  99. if (fPreserve && (0 < m_cbDataLength))
  100. {
  101. //
  102. // Increase the buffer length, and preserve the existing data.
  103. //
  104. if (m_cbBufferLength < cbLength)
  105. {
  106. pbNewBuf = new BYTE[cbLength];
  107. if (NULL == pbNewBuf)
  108. throw (DWORD)ERROR_OUTOFMEMORY;
  109. memcpy(pbNewBuf, m_pbBuffer, m_cbDataLength);
  110. delete[] m_pbBuffer;
  111. m_pbBuffer = pbNewBuf;
  112. m_cbBufferLength = cbLength;
  113. }
  114. }
  115. else
  116. {
  117. //
  118. // Increase the buffer length, but lose any existing data.
  119. //
  120. if (m_cbBufferLength < cbLength)
  121. {
  122. pbNewBuf = new BYTE[cbLength];
  123. if (NULL == pbNewBuf)
  124. throw (DWORD)ERROR_OUTOFMEMORY;
  125. if (NULL != m_pbBuffer)
  126. delete[] m_pbBuffer;
  127. m_pbBuffer = pbNewBuf;
  128. m_cbBufferLength = cbLength;
  129. }
  130. m_cbDataLength = 0;
  131. }
  132. return m_pbBuffer;
  133. }
  134. /*++
  135. Resize:
  136. This method sets the length of the data to the given size. If the buffer
  137. isn't big enough to support that data length, it is enlarged.
  138. Arguments:
  139. cbLength supplies the new length of the data.
  140. fPreserve supplies a flag indicating whether or not to preserve existing
  141. data.
  142. Return Value:
  143. The address of the buffer.
  144. Author:
  145. Doug Barlow (dbarlow) 10/5/1995
  146. --*/
  147. LPBYTE
  148. CBuffer::Resize(
  149. DWORD cbLength,
  150. BOOL fPreserve)
  151. {
  152. LPBYTE pb = Presize(cbLength, fPreserve);
  153. m_cbDataLength = cbLength;
  154. return pb;
  155. }
  156. /*++
  157. Set:
  158. This method sets the contents of the data to the given value. If the buffer
  159. isn't big enough to hold the given data, it is enlarged.
  160. Arguments:
  161. pbSource supplies the data to place in the data buffer.
  162. cbLength supplies the length of that data, in bytes.
  163. Return Value:
  164. The address of the buffer.
  165. Author:
  166. Doug Barlow (dbarlow) 10/5/1995
  167. --*/
  168. LPBYTE
  169. CBuffer::Set(
  170. IN const BYTE * const pbSource,
  171. IN DWORD cbLength)
  172. {
  173. LPBYTE pb = Presize(cbLength, FALSE);
  174. if (0 < cbLength)
  175. memcpy(pb, pbSource, cbLength);
  176. m_cbDataLength = cbLength;
  177. return pb;
  178. }
  179. /*++
  180. CBuffer::Append:
  181. This method appends the supplied data onto the end of the existing data,
  182. enlarging the buffer if necessary.
  183. Arguments:
  184. pbSource supplies the data to be appended.
  185. cbLength supplies the length of the data to be appended, in bytes.
  186. Return Value:
  187. The address of the buffer.
  188. Author:
  189. Doug Barlow (dbarlow) 10/5/1995
  190. --*/
  191. LPBYTE
  192. CBuffer::Append(
  193. IN const BYTE * const pbSource,
  194. IN DWORD cbLength)
  195. {
  196. LPBYTE pb = m_pbBuffer;
  197. if (0 < cbLength)
  198. {
  199. pb = Presize(m_cbDataLength + cbLength, TRUE);
  200. memcpy(&pb[m_cbDataLength], pbSource, cbLength);
  201. m_cbDataLength += cbLength;
  202. }
  203. return pb;
  204. }
  205. /*++
  206. CBuffer::Compare:
  207. This method compares the contents of another CBuffer to this one, and
  208. returns a value indicating a comparative value.
  209. Arguments:
  210. bfSource supplies the other buffer.
  211. Return Value:
  212. < 0 - The other buffer is less than this one.
  213. = 0 - The other buffer is identical to this one.
  214. > 0 - The other buffer is greater than this one.
  215. Author:
  216. Doug Barlow (dbarlow) 10/5/1995
  217. --*/
  218. int
  219. CBuffer::Compare(
  220. const CBuffer &bfSource)
  221. const
  222. {
  223. if (m_cbDataLength < bfSource.m_cbDataLength)
  224. return -1;
  225. else if (m_cbDataLength > bfSource.m_cbDataLength)
  226. return 1;
  227. else if (0 < m_cbDataLength)
  228. return memcmp(m_pbBuffer, bfSource.m_pbBuffer, m_cbDataLength);
  229. else
  230. return 0;
  231. }
  232. /*++
  233. operator+:
  234. This routine is a special operator that allows addition of two CBuffers to
  235. produce a third, a la bfThree = bfOne + bfTwo. It calls the special
  236. protected constructor of CBuffer.
  237. Arguments:
  238. bfSourceOne supplies the first buffer
  239. bfSourceTwo supplies the second buffer
  240. Return Value:
  241. A reference to a temporary CBuffer that is the concatenation of the two
  242. provided buffers.
  243. Author:
  244. Doug Barlow (dbarlow) 10/5/1995
  245. --*/
  246. #pragma warning (disable : 4172)
  247. CBuffer &
  248. operator+(
  249. IN const CBuffer &bfSourceOne,
  250. IN const CBuffer &bfSourceTwo)
  251. {
  252. return CBuffer(bfSourceOne, bfSourceTwo);
  253. }
  254. #pragma warning (default : 4172)