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.

249 lines
6.5 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. buffer.hxx
  5. Abstract:
  6. This file contains declaration of BUFFER and BUFFER_CHAIN classes.
  7. Author:
  8. Murali R. Krishnan (MuraliK) 9-July-1996 Recreated from old buffer.hxx
  9. Revision History:
  10. --*/
  11. #ifndef _BUFFER_HXX_
  12. #define _BUFFER_HXX_
  13. extern "C"
  14. {
  15. # include <nt.h>
  16. # include <ntrtl.h>
  17. # include <nturtl.h>
  18. # include <windows.h>
  19. # include <irtlmisc.h>
  20. };
  21. /*************************************************************************
  22. NAME: BUFFER (buf)
  23. SYNOPSIS: A resizable object which lives in the application heap.
  24. It uses a local inlined buffer object to cache the commonly
  25. used allocation units and allows storage of
  26. INLINED_BUFFER_LEN bytes.
  27. Upon construction, the buffer takes a requested size in
  28. bytes; it allocates storage sufficient to hold that size.
  29. The client can later change this size with Resize, Trim,
  30. and FillOut. QuerySize returns the current size of
  31. the buffer; QueryPtr returns a pointer to its storage.
  32. Note that a buffer may have size 0, in which case it
  33. keeps no allocated storage.
  34. INTERFACE: BUFFER() - Constructor, naming initial size in bytes
  35. QuerySize() - return size in bytes
  36. QueryPtr() - return pointer to data buffer
  37. Resize() - resize the object to the given number
  38. of bytes. Returns TRUE if the resize was
  39. successful; otherwise returns FALSE (use
  40. GetLastError for error code)
  41. **************************************************************************/
  42. /*
  43. I picked up the INLINED_BUFFER_LEN based on following factors
  44. 1) W3svc was using buffers of length < 16 bytes for 70% of transactions
  45. 2) A cache line is usually 32 bytes or multiples thereof and
  46. it may have subblocking of about 16/32 bytes.
  47. Choice of 16 bytes allows the BUFFER & STR objects to fit into
  48. even a conservative L1 cache line
  49. August 1999: upped from 16 to 32
  50. */
  51. # define INLINED_BUFFER_LEN (32)
  52. class IRTL_DLLEXP BUFFER {
  53. private:
  54. //
  55. // Lots of code uses BUFFER class to store a bunch of different
  56. // structures, so m_rgb needs to be 8 byte aligned, so put it as the
  57. // first member
  58. //
  59. BYTE m_rgb[INLINED_BUFFER_LEN]; // the default buffer object
  60. BYTE * m_pb; // pointer to storage
  61. UINT m_cb; // size of storage, as requested by client
  62. DWORD m_fIsDynAlloced : 1; // is m_pb dynamically allocated ?
  63. DWORD m_fValid : 1; // is this object valid
  64. BOOL GetNewStorage( UINT cbRequested );
  65. BOOL ReallocStorage( UINT cbNewlyRequested );
  66. VOID VerifyState(VOID) const;
  67. BOOL IsDynAlloced(VOID) const { return ( m_fIsDynAlloced); }
  68. public:
  69. BUFFER( UINT cbRequested = 0 )
  70. : m_pb (m_rgb),
  71. m_cb (INLINED_BUFFER_LEN),
  72. m_fIsDynAlloced (0),
  73. m_fValid (1)
  74. {
  75. m_rgb[0] = '\0';
  76. if ( cbRequested > INLINED_BUFFER_LEN ) {
  77. GetNewStorage(cbRequested);
  78. }
  79. }
  80. // This constructor is used for most scratch BUFFER objects on stack
  81. // BUFFER does not free this pbInit on its own.
  82. BUFFER( BYTE * pbInit, UINT cbInit)
  83. : m_pb (pbInit),
  84. m_cb (cbInit),
  85. m_fIsDynAlloced (0),
  86. m_fValid (1)
  87. {
  88. m_pb[0] = '\0';
  89. }
  90. ~BUFFER(void) {
  91. if ( IsDynAlloced()) {
  92. ::LocalFree( (HANDLE) m_pb );
  93. }
  94. }
  95. VOID * QueryPtr() const { return ( (VOID * ) m_pb); }
  96. UINT QuerySize() const { return m_cb; }
  97. //
  98. // If a resize is needed, added cbSlop to it
  99. //
  100. BOOL Resize( UINT cbNewSize )
  101. {
  102. if ( cbNewSize <= QuerySize() )
  103. {
  104. return TRUE;
  105. }
  106. return ReallocStorage( cbNewSize );
  107. }
  108. BOOL Resize( UINT cbNewSize,
  109. UINT cbSlop )
  110. {
  111. if ( cbNewSize <= QuerySize() )
  112. {
  113. return TRUE;
  114. }
  115. return ReallocStorage( cbNewSize + cbSlop );
  116. }
  117. VOID FreeMemory( VOID );
  118. VOID SetValid( BOOL fValid) { m_fValid = ((fValid) ? 1 : 0); }
  119. BOOL IsValid( VOID) const { return ( m_fValid); }
  120. private:
  121. BOOL ResizeAux( UINT cbNewReqestedSize,
  122. UINT cbSlop);
  123. }; // class BUFFER
  124. //
  125. // Quick macro for declaring a BUFFER that will use stack memory of <size>
  126. // bytes. If the buffer overflows then a heap buffer will be allocated
  127. //
  128. #define STACK_BUFFER(name, size) BYTE __ach##name[size]; \
  129. BUFFER name(__ach##name, sizeof(__ach##name))
  130. //
  131. // NYI: This should be probably moved over to ODBC which is the only user.
  132. // BUFFER_CHAIN_ITEM is a single item in a chain of buffers
  133. //
  134. class IRTL_DLLEXP BUFFER_CHAIN_ITEM : public BUFFER
  135. {
  136. friend class BUFFER_CHAIN;
  137. public:
  138. BUFFER_CHAIN_ITEM( UINT cbReq = 0 )
  139. : BUFFER( cbReq ),
  140. _cbUsed( 0 )
  141. { _ListEntry.Flink = NULL; }
  142. ~BUFFER_CHAIN_ITEM()
  143. { if ( _ListEntry.Flink )
  144. RemoveEntryList( &_ListEntry );
  145. }
  146. DWORD QueryUsed( VOID ) const
  147. { return _cbUsed; }
  148. VOID SetUsed( DWORD cbUsed )
  149. { _cbUsed = cbUsed; }
  150. private:
  151. LIST_ENTRY _ListEntry;
  152. DWORD _cbUsed; // Bytes of valid data in this buffer
  153. VOID VerifyState() const;
  154. }; // class BUFFER_CHAIN_ITEM
  155. class IRTL_DLLEXP BUFFER_CHAIN
  156. {
  157. public:
  158. BUFFER_CHAIN()
  159. { InitializeListHead( &_ListHead ); }
  160. ~BUFFER_CHAIN()
  161. { DeleteChain(); }
  162. BOOL AppendBuffer( BUFFER_CHAIN_ITEM * pBCI );
  163. //
  164. // Returns total number of bytes freed by deleting all of the buffer
  165. // chain items
  166. //
  167. DWORD DeleteChain();
  168. //
  169. // Enums buffer chain. Pass pBCI as NULL on first call, pass return
  170. // value till NULL on subsequent calls
  171. //
  172. BUFFER_CHAIN_ITEM * NextBuffer( BUFFER_CHAIN_ITEM * pBCI );
  173. //
  174. // Gives back total number of bytes allocated by chain (includes unused
  175. // bytes)
  176. //
  177. DWORD CalcTotalSize( BOOL fUsed = FALSE ) const;
  178. private:
  179. LIST_ENTRY _ListHead;
  180. }; // class BUFFER_CHAIN
  181. #endif // _BUFFER_HXX_