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.

300 lines
5.3 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. string.cpp
  5. Abstract:
  6. Author:
  7. Vlad Sadovsky (vlads) 26-Jan-1997
  8. Revision History:
  9. 26-Jan-1997 VladS created
  10. --*/
  11. //
  12. // Normal includes only for this module
  13. //
  14. #include "cplusinc.h"
  15. #include "sticomm.h"
  16. BOOL BUFFER::GetNewStorage( UINT cbRequested )
  17. {
  18. _pb = (BYTE *) ::LocalAlloc( LPTR , cbRequested );
  19. if ( !_pb ) {
  20. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  21. return FALSE;
  22. }
  23. _cb = cbRequested;
  24. return TRUE;
  25. }
  26. BOOL BUFFER::ReallocStorage( UINT cbNewRequested )
  27. {
  28. HANDLE hNewMem = ::LocalReAlloc( _pb, cbNewRequested, 0 );
  29. if (hNewMem == 0) {
  30. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  31. return FALSE;
  32. }
  33. _pb = (BYTE *) hNewMem;
  34. ASSERT( _pb != NULL );
  35. _cb = cbNewRequested;
  36. return TRUE;
  37. }
  38. VOID BUFFER::VerifyState() const
  39. {
  40. ASSERT(( _pb == NULL && _cb == 0 ) ||
  41. ( _pb != NULL && _cb != 0 ));
  42. }
  43. BOOL BUFFER::Resize( UINT cbNewRequested,
  44. UINT cbSlop )
  45. {
  46. #if DBG
  47. VerifyState();
  48. #endif
  49. if ( cbNewRequested != 0 ) {
  50. if ( _pb != 0 ) {
  51. if ( cbNewRequested > QuerySize() ) {
  52. /*
  53. * The requested memory exceeds the currently allocated memory.
  54. * A reallocation is in order.
  55. */
  56. return ReallocStorage(cbNewRequested + cbSlop);
  57. }
  58. return TRUE;
  59. }
  60. else {
  61. /*
  62. * There is no memory handle. Previous size of buffer
  63. * must have been 0.
  64. *
  65. * The new memory request is allocated.
  66. */
  67. return GetNewStorage( cbNewRequested );
  68. }
  69. }
  70. else {
  71. /*
  72. * The requested memory size is 0. This will always work.
  73. */
  74. if ( _pb )
  75. ::LocalFree( (HANDLE)_pb );
  76. _pb = NULL;
  77. _cb = 0;
  78. return TRUE;
  79. }
  80. return TRUE;
  81. }
  82. VOID BUFFER::Trim()
  83. {
  84. #if DBG
  85. VerifyState();
  86. #endif
  87. if ( _pb == 0 ) {
  88. /*
  89. * No memory is allocated.
  90. */
  91. ASSERT( _pb == NULL && _cb == 0 );
  92. return;
  93. }
  94. if ( _cb == 0 ) {
  95. /*
  96. * The requested size is 0. Free the allocated memory.
  97. */
  98. ASSERT( _pb == NULL );
  99. return;
  100. }
  101. /*
  102. * (This should not fail, since we are reallocating to less
  103. * than current storage.)
  104. */
  105. REQUIRE( NO_ERROR == ReallocStorage(_cb) );
  106. }
  107. BOOL
  108. BUFFER_CHAIN::AppendBuffer(
  109. BUFFER_CHAIN_ITEM * pBCI
  110. )
  111. /*++
  112. Routine Description:
  113. Adds a new buffer chain item to the end of the buffer chain
  114. Arguments:
  115. pBCI - Chain item to append
  116. Return Value:
  117. TRUE if successful, FALSE on error
  118. --*/
  119. {
  120. ASSERT( pBCI );
  121. ASSERT( pBCI->_ListEntry.Flink == NULL );
  122. InsertTailList( &_ListHead,
  123. &pBCI->_ListEntry );
  124. return TRUE;
  125. }
  126. DWORD
  127. BUFFER_CHAIN::DeleteChain(
  128. VOID
  129. )
  130. /*++
  131. Routine Description:
  132. Deletes all of the buffers in this chain
  133. Return Value:
  134. Total number of allocated bytes freed by this call
  135. --*/
  136. {
  137. BUFFER_CHAIN_ITEM * pBCI;
  138. DWORD cbFreed = 0;
  139. while ( !IsListEmpty( &_ListHead ))
  140. {
  141. pBCI = CONTAINING_RECORD( _ListHead.Flink,
  142. BUFFER_CHAIN_ITEM,
  143. _ListEntry );
  144. ASSERT( pBCI->_ListEntry.Flink != NULL );
  145. RemoveEntryList( &pBCI->_ListEntry );
  146. cbFreed += pBCI->QuerySize();
  147. delete pBCI;
  148. }
  149. return cbFreed;
  150. }
  151. BUFFER_CHAIN_ITEM *
  152. BUFFER_CHAIN::NextBuffer(
  153. BUFFER_CHAIN_ITEM * pBCI
  154. )
  155. /*++
  156. Routine Description:
  157. Returns the next buffer in the chain. Start the enumeration by
  158. passing pBCI as NULL. Continue it by passing the return value
  159. Arguments:
  160. pBCI - Previous item in enumeration
  161. Return Value:
  162. Pointer to next item in chain, NULL when done
  163. --*/
  164. {
  165. if ( pBCI != NULL )
  166. {
  167. if ( pBCI->_ListEntry.Flink != &_ListHead )
  168. {
  169. return CONTAINING_RECORD( pBCI->_ListEntry.Flink,
  170. BUFFER_CHAIN_ITEM,
  171. _ListEntry );
  172. }
  173. else
  174. {
  175. return NULL;
  176. }
  177. }
  178. if ( !IsListEmpty( &_ListHead ))
  179. {
  180. return CONTAINING_RECORD( _ListHead.Flink,
  181. BUFFER_CHAIN_ITEM,
  182. _ListEntry );
  183. }
  184. return NULL;
  185. }
  186. DWORD
  187. BUFFER_CHAIN::CalcTotalSize(
  188. BOOL fUsed
  189. ) const
  190. /*++
  191. Routine Description:
  192. Returns the total amount of memory allocated by this buffer chain
  193. excluding the size of the structures themselves
  194. Arguments:
  195. fUsed - If FALSE, returns total allocated by chain, if TRUE returns
  196. total used by chain
  197. Return Value:
  198. Total bytes allocated or total bytes used
  199. --*/
  200. {
  201. LIST_ENTRY * pEntry;
  202. BUFFER_CHAIN_ITEM * pBCI;
  203. DWORD cbRet = 0;
  204. for ( pEntry = _ListHead.Flink;
  205. pEntry != &_ListHead;
  206. pEntry = pEntry->Flink )
  207. {
  208. pBCI = CONTAINING_RECORD( pEntry, BUFFER_CHAIN_ITEM, _ListEntry );
  209. if ( fUsed == FALSE )
  210. cbRet += pBCI->QuerySize();
  211. else
  212. cbRet += pBCI->QueryUsed();
  213. }
  214. return cbRet;
  215. }