Buffer.h
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:6k
源码类别:

模拟服务器

开发平台:

C/C++

  1. /********************************************************************
  2. created: 2003/04/26
  3. file base: Buffer
  4. file ext: h
  5. author: liupeng
  6. purpose:
  7. *********************************************************************/
  8. #ifndef __INCLUDE_ONLINEGAMELIB_WIN32_BUFFER_H__
  9. #define __INCLUDE_ONLINEGAMELIB_WIN32_BUFFER_H__
  10. #if defined (_MSC_VER) && (_MSC_VER >= 1020)
  11. #pragma once
  12. #endif
  13. #ifndef _WINDOWS_
  14. #define WIN32_LEAN_AND_MEAN
  15. #include <windows.h>
  16. #undef WIN32_LEAN_AND_MEAN
  17. #endif
  18. /*
  19.  * Identifier was truncated to '255' characters 
  20.  * in the debug information
  21.  */
  22. #pragma warning(disable : 4786)
  23. #include "CriticalSection.h"
  24. #include "NodeList.h"
  25. #include "OpaqueUserData.h"
  26. #include "Utils.h"
  27. #include "Macro.h"
  28. #include <map>
  29. /*
  30.  * Nonstandard extension used : zero-sized array in struct/union
  31.  */
  32. #pragma warning(disable: 4200)
  33. /*
  34.  * namespace OnlineGameLib::Win32
  35.  */
  36. namespace OnlineGameLib {
  37. namespace Win32 {
  38. /*
  39.  * CBuffer class
  40.  */
  41. class CBuffer : public CNodeList::Node, public COpaqueUserData
  42. {
  43. public:
  44. class Allocator;
  45. friend class Allocator;
  46. size_t GetUsed() const { return m_used; };
  47. size_t GetSize() const { return m_size; };
  48. const BYTE *GetBuffer() const { return m_buffer_ptr; };
  49. CBuffer *GetHeadPack( size_t packLength );
  50. CBuffer *GetNextPack();
  51. bool  HaveNextPack() { return ( m_offsetNextPack < m_used ) ? true : false; };
  52. void AddData( const char * const pData, size_t dataLength );
  53. void AddData( const BYTE * const pData, size_t dataLength );
  54. void AddData( BYTE data );
  55. void Use( size_t dataUsed ) { m_used += dataUsed; };
  56. CBuffer *SplitBuffer( size_t bytesToRemove );
  57. CBuffer *AllocateNewBuffer() const;
  58. void ConsumeAndRemove( size_t bytesToRemove );
  59. void Empty() { m_used = 0; };
  60. void AddRef() { ::InterlockedIncrement( &m_ref ); };
  61. void Release();
  62. private:
  63. Allocator &m_allocator;
  64. long m_ref;
  65. const size_t m_size;
  66. size_t m_used;
  67. size_t m_packLength;
  68. size_t m_offsetNextPack;
  69. /*
  70.  * start of the actual buffer, must remain the last
  71.  * data member in the class.
  72.  */
  73. BYTE *m_buffer_ptr; // four bytes aligned
  74. //BYTE m_buffer_base_addr[0];
  75. private:
  76. static void *operator new( size_t objSize, size_t bufferSize );
  77. static void operator delete( void *pObj, size_t bufferSize );
  78.       
  79. CBuffer( Allocator &allocator, size_t size );
  80. ~CBuffer();
  81. /*
  82.  * No copies do not implement
  83.  */
  84. CBuffer( const CBuffer &rhs );
  85. CBuffer &operator=( const CBuffer &rhs );
  86. };
  87. /*
  88.  * CBuffer::Allocator class
  89.  */
  90. class CBuffer::Allocator
  91. {
  92. public:
  93. friend class CBuffer;
  94. explicit Allocator( size_t bufferSize, size_t maxFreeBuffers );
  95. virtual ~Allocator();
  96. CBuffer *Allocate();
  97. size_t GetBufferSize() const { return m_bufferSize; };
  98. bool ReSet( size_t bufferSize, size_t maxFreeBuffers );
  99. protected:
  100. void Flush();
  101. private:
  102. void Release( CBuffer *pBuffer );
  103. virtual void OnBufferCreated() {}
  104. virtual void OnBufferAllocated() {}
  105. virtual void OnBufferReleased() {}
  106. void DestroyBuffer( CBuffer *pBuffer );
  107. const size_t m_bufferSize;
  108. typedef TNodeList< CBuffer > BufferList;
  109. BufferList m_freeList;
  110. BufferList m_activeList;
  111. const size_t m_maxFreeBuffers;
  112. CCriticalSection m_criticalSection;
  113.     /*
  114.  * No copies do not implement
  115.  */
  116. Allocator( const Allocator &rhs );
  117. Allocator &operator=( const Allocator &rhs );
  118. };
  119. /*
  120.  * class CPackager
  121.  */
  122. class CPackager
  123. {
  124. public:
  125. CPackager( size_t bufferSize = 65536 /* 1024*64 */, size_t maxFreeBuffers = 16 );
  126. virtual ~CPackager();
  127. /*
  128.  * Send
  129.  */
  130. CBuffer *GetHeadPack( BYTE cID, size_t packLength = 512 );
  131. CBuffer *GetNextPack( BYTE cID );
  132. void AddData( BYTE cID, const char * const pData, size_t dataLength, unsigned long lnUserData = 0 );
  133. void AddData( BYTE cID, const BYTE * const pData, size_t dataLength, unsigned long lnUserData = 0 );
  134. void DelData( BYTE cID );
  135. /*
  136.  * Recv
  137.  */
  138. CBuffer *PackUp( const void *pData, size_t dataLength );
  139. /*
  140.  * Common
  141.  */
  142. bool ReSet( size_t bufferSize, size_t maxFreeBuffers ) { return m_theAllocator.ReSet( bufferSize, maxFreeBuffers ); }
  143. void Empty();
  144. static BYTE Peek( const void *pData, size_t index = 0 ) { 
  145. if ( !pData )
  146. return 0; 
  147. return *( ( const BYTE * )pData + index ); 
  148. }
  149. private:
  150. CCriticalSection m_csSend;
  151. CCriticalSection m_csRecv;
  152. CBuffer::Allocator m_theAllocator;
  153. typedef std::map< BYTE, CBuffer * > BUFFER_MAP;
  154. BUFFER_MAP m_theSend;
  155. BUFFER_MAP m_theRecv;
  156. /*
  157.  * +-----+-----+-----+-----+
  158.  * | 8 7 | 6 5 | 4 3 | 2 1 |  <==> enumPackFlag, sizeof( BYTE )
  159.  * +-----+-----+-----+-----+
  160.  *    A     B     C     D
  161. */
  162. enum enumPackFlag
  163. {
  164. enumPackHeader = 0xc0, // A segment
  165. enumPackMiddle = 0x30, // B segment
  166. enumPackTail = 0xc, // C segment
  167. enumPackErr = 0x3 // D segment
  168. };
  169. bool _Header( BYTE cFlag ) { return ToBool<int>( cFlag & enumPackHeader ); }
  170. bool _Middle( BYTE cFlag ) { return ToBool<int>( cFlag & enumPackMiddle ); }
  171. bool _Tail( BYTE cFlag ) { return ToBool<int>( cFlag & enumPackTail ); }
  172. bool _Error( BYTE cFlag ) { return ToBool<int>( cFlag & enumPackErr ); }
  173. };
  174. inline void CBuffer::ConsumeAndRemove( size_t bytesToRemove )
  175. {
  176. m_used -= bytesToRemove;
  177. memmove( m_buffer_ptr, m_buffer_ptr + bytesToRemove, m_used );
  178. }
  179. inline bool CBuffer::Allocator::ReSet( size_t bufferSize, size_t maxFreeBuffers )
  180. {
  181. memcpy( const_cast< size_t * >( &m_bufferSize ), &bufferSize, sizeof( size_t ) );
  182. memcpy( const_cast< size_t * >( &m_maxFreeBuffers ), &maxFreeBuffers, sizeof( size_t ) );
  183. return true;
  184. }
  185. inline void CBuffer::Allocator::DestroyBuffer( CBuffer *pBuffer )
  186. {
  187. SAFE_DELETE( pBuffer );
  188. }
  189. } // End of namespace OnlineGameLib
  190. } // End of namespace Win32
  191. #endif //__INCLUDE_ONLINEGAMELIB_WIN32_BUFFER_H__