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.

312 lines
5.7 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. BOOL bReallocSuccess = FALSE;
  102. if (NO_ERROR == ReallocStorage(_cb))
  103. {
  104. bReallocSuccess = TRUE;
  105. }
  106. else
  107. {
  108. bReallocSuccess = FALSE;
  109. }
  110. /*
  111. * (This should not fail, since we are reallocating to less
  112. * than current storage.)
  113. */
  114. REQUIRE( bReallocSuccess );
  115. }
  116. BOOL
  117. BUFFER_CHAIN::AppendBuffer(
  118. BUFFER_CHAIN_ITEM * pBCI
  119. )
  120. /*++
  121. Routine Description:
  122. Adds a new buffer chain item to the end of the buffer chain
  123. Arguments:
  124. pBCI - Chain item to append
  125. Return Value:
  126. TRUE if successful, FALSE on error
  127. --*/
  128. {
  129. ASSERT( pBCI );
  130. ASSERT( pBCI->_ListEntry.Flink == NULL );
  131. InsertTailList( &_ListHead,
  132. &pBCI->_ListEntry );
  133. return TRUE;
  134. }
  135. DWORD
  136. BUFFER_CHAIN::DeleteChain(
  137. VOID
  138. )
  139. /*++
  140. Routine Description:
  141. Deletes all of the buffers in this chain
  142. Return Value:
  143. Total number of allocated bytes freed by this call
  144. --*/
  145. {
  146. BUFFER_CHAIN_ITEM * pBCI;
  147. DWORD cbFreed = 0;
  148. while ( !IsListEmpty( &_ListHead ))
  149. {
  150. pBCI = CONTAINING_RECORD( _ListHead.Flink,
  151. BUFFER_CHAIN_ITEM,
  152. _ListEntry );
  153. ASSERT( pBCI->_ListEntry.Flink != NULL );
  154. RemoveEntryList( &pBCI->_ListEntry );
  155. cbFreed += pBCI->QuerySize();
  156. delete pBCI;
  157. }
  158. return cbFreed;
  159. }
  160. BUFFER_CHAIN_ITEM *
  161. BUFFER_CHAIN::NextBuffer(
  162. BUFFER_CHAIN_ITEM * pBCI
  163. )
  164. /*++
  165. Routine Description:
  166. Returns the next buffer in the chain. Start the enumeration by
  167. passing pBCI as NULL. Continue it by passing the return value
  168. Arguments:
  169. pBCI - Previous item in enumeration
  170. Return Value:
  171. Pointer to next item in chain, NULL when done
  172. --*/
  173. {
  174. if ( pBCI != NULL )
  175. {
  176. if ( pBCI->_ListEntry.Flink != &_ListHead )
  177. {
  178. return CONTAINING_RECORD( pBCI->_ListEntry.Flink,
  179. BUFFER_CHAIN_ITEM,
  180. _ListEntry );
  181. }
  182. else
  183. {
  184. return NULL;
  185. }
  186. }
  187. if ( !IsListEmpty( &_ListHead ))
  188. {
  189. return CONTAINING_RECORD( _ListHead.Flink,
  190. BUFFER_CHAIN_ITEM,
  191. _ListEntry );
  192. }
  193. return NULL;
  194. }
  195. DWORD
  196. BUFFER_CHAIN::CalcTotalSize(
  197. BOOL fUsed
  198. ) const
  199. /*++
  200. Routine Description:
  201. Returns the total amount of memory allocated by this buffer chain
  202. excluding the size of the structures themselves
  203. Arguments:
  204. fUsed - If FALSE, returns total allocated by chain, if TRUE returns
  205. total used by chain
  206. Return Value:
  207. Total bytes allocated or total bytes used
  208. --*/
  209. {
  210. LIST_ENTRY * pEntry;
  211. BUFFER_CHAIN_ITEM * pBCI;
  212. DWORD cbRet = 0;
  213. for ( pEntry = _ListHead.Flink;
  214. pEntry != &_ListHead;
  215. pEntry = pEntry->Flink )
  216. {
  217. pBCI = CONTAINING_RECORD( pEntry, BUFFER_CHAIN_ITEM, _ListEntry );
  218. if ( fUsed == FALSE )
  219. cbRet += pBCI->QuerySize();
  220. else
  221. cbRet += pBCI->QueryUsed();
  222. }
  223. return cbRet;
  224. }