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

模拟服务器

开发平台:

C/C++

  1. #include "stdafx.h"
  2. #include "Buffer.h"
  3. #include "Exception.h"
  4. #include "Utils.h"
  5. /*
  6.  * namespace OnlineGameLib::Win32
  7.  */
  8. namespace OnlineGameLib {
  9. namespace Win32 {
  10. CBuffer::CBuffer( Allocator &allocator, size_t size )
  11. : m_allocator( allocator )
  12. , m_ref( 1 )
  13. , m_size( size )
  14. , m_used( 0 )
  15. , m_packLength( 0 )
  16. , m_offsetNextPack( 0 )
  17. {
  18. //( ( BYTE * )( ( DWORD )( pMemory + 3 ) & ( ~3 ) ) )
  19. m_buffer_ptr = new BYTE[ size ];
  20. Empty();
  21. }
  22. CBuffer::~CBuffer()
  23. {
  24. SAFE_DELETE_ARRAY( m_buffer_ptr );
  25. }
  26. CBuffer *CBuffer::GetHeadPack( size_t packLength )
  27. {
  28. if ( 0 == m_used || 0 == packLength )
  29. {
  30. return NULL;
  31. }
  32. m_packLength = packLength;
  33. CBuffer *pNewBuffer = m_allocator.Allocate();
  34. size_t canused = ( m_packLength > m_used ) ? m_used : m_packLength;
  35. pNewBuffer->AddData( m_buffer_ptr, canused );
  36. m_offsetNextPack = canused;
  37. return pNewBuffer;
  38. }
  39. CBuffer *CBuffer::GetNextPack()
  40. {
  41. if ( m_offsetNextPack < m_used )
  42. {
  43. CBuffer *pNewBuffer = m_allocator.Allocate();
  44. size_t canused = ( m_offsetNextPack + m_packLength > m_used ) ? ( m_used - m_offsetNextPack ) : m_packLength;
  45. pNewBuffer->AddData( m_buffer_ptr + m_offsetNextPack, canused );
  46. m_offsetNextPack += canused;
  47. return pNewBuffer;
  48. }
  49. return NULL;
  50. }
  51. void CBuffer::AddData( const char * const pData, size_t dataLength )
  52. {
  53. if ( dataLength > m_size - m_used )
  54. {
  55. DEBUG_ONLY( Message( "CBuffer::AddData - Not enough space in buffer!" ) );
  56. throw CException( _T("CBuffer::AddData"), _T("Not enough space in buffer") );
  57. }
  58. memcpy( m_buffer_ptr + m_used, pData, dataLength );
  59. m_used += dataLength;
  60. }
  61. void CBuffer::AddData( const BYTE * const pData, size_t dataLength )
  62. {
  63. AddData( reinterpret_cast< const char * >( pData ), dataLength );
  64. }
  65. void CBuffer::AddData( BYTE data )
  66. {
  67. AddData( &data, 1 );
  68. }
  69. CBuffer *CBuffer::SplitBuffer( size_t bytesToRemove )
  70. {
  71. CBuffer *pNewBuffer = m_allocator.Allocate();
  72. pNewBuffer->AddData( m_buffer_ptr, bytesToRemove );
  73. m_used -= bytesToRemove;
  74. memmove( m_buffer_ptr, m_buffer_ptr + bytesToRemove, m_used );
  75. return pNewBuffer;
  76. }
  77. CBuffer *CBuffer::AllocateNewBuffer() const
  78. {
  79. return m_allocator.Allocate();
  80. }
  81. void CBuffer::Release()
  82. {
  83. if ( m_ref == 0 )
  84. {
  85. throw CException( _T("CBuffer::Release()"), _T("m_ref is already zero") );
  86. }
  87. if ( 0 == ::InterlockedDecrement( &m_ref ) )
  88. {
  89. m_used = 0;
  90. m_allocator.Release( this );
  91. }
  92. }
  93. void *CBuffer::operator new( size_t objectSize, size_t /* bufferSize */ )
  94. {
  95. /*
  96.  * ASSERT( sizeof( DWORD ) == 4 );
  97.  *
  98.  * For four bytes aligned base on win32 system
  99.  */
  100. void *pMem = new char[ objectSize ]; //+ bufferSize + 4 ];
  101. return pMem;
  102. }
  103. void CBuffer::operator delete( void *pObject, size_t /* bufferSize */ )
  104. {
  105. SAFE_DELETE_ARRAY( pObject );
  106. }
  107. /*
  108.  * CBuffer::Allocator class
  109.  */
  110. CBuffer::Allocator::Allocator( size_t bufferSize, size_t maxFreeBuffers )
  111. : m_bufferSize( bufferSize )
  112. , m_maxFreeBuffers( maxFreeBuffers )
  113. {
  114. }
  115. CBuffer::Allocator::~Allocator()
  116. {
  117. try
  118. {
  119. Flush();
  120. }
  121. catch(...)
  122. {
  123. TRACE( "CBuffer::Allocator::~Allocator exception!" );
  124. }
  125. }
  126. CBuffer *CBuffer::Allocator::Allocate()
  127. {
  128. CCriticalSection::Owner lock( m_criticalSection );
  129. CBuffer *pBuffer = 0;
  130. if ( !m_freeList.Empty() )
  131. {
  132. pBuffer = m_freeList.PopNode();
  133. pBuffer->AddRef();
  134. }
  135. else
  136. {
  137. pBuffer = new( m_bufferSize )CBuffer( *this, m_bufferSize );
  138. if ( !pBuffer )
  139. {
  140. throw CException( _T("CBuffer::Allocator::Allocate()"), _T("Out of memory") );
  141. }
  142. OnBufferCreated();
  143. }
  144. m_activeList.PushNode( pBuffer );
  145. OnBufferAllocated();
  146. return pBuffer;
  147. }
  148. void CBuffer::Allocator::Flush()
  149. {
  150. CCriticalSection::Owner lock( m_criticalSection );
  151. while ( !m_activeList.Empty() )
  152. {
  153. OnBufferReleased();
  154. DestroyBuffer( m_activeList.PopNode() );
  155. }
  156. while ( !m_freeList.Empty() )
  157. {
  158. DestroyBuffer( m_freeList.PopNode() );
  159. }
  160. }
  161. void CBuffer::Allocator::Release( CBuffer *pBuffer )
  162. {
  163. if ( !pBuffer )
  164. {
  165. throw CException( _T("CBuffer::Allocator::Release()"), _T("pBuffer is null") );
  166. }
  167. CCriticalSection::Owner lock( m_criticalSection );
  168. OnBufferReleased();
  169. /*
  170.  * unlink from the in use list
  171.  */
  172. pBuffer->RemoveFromList();
  173. if ( m_maxFreeBuffers == 0 || m_freeList.Count() < m_maxFreeBuffers )
  174. {
  175. pBuffer->Empty();           
  176. /*
  177.  * add to the free list
  178.  */
  179. m_freeList.PushNode( pBuffer );
  180. }
  181. else
  182. {
  183. DestroyBuffer( pBuffer );
  184. }
  185. }
  186. CPackager::CPackager( size_t bufferSize /* = 65536  */, size_t maxFreeBuffers /* = 16  */ )
  187. : m_theAllocator( bufferSize, maxFreeBuffers )
  188. {
  189. }
  190. CPackager::~CPackager()
  191. {
  192. Empty();
  193. }
  194. void CPackager::AddData( BYTE cID, const char * const pData, size_t dataLength, unsigned long lnUserData /* = 0 */ )
  195. {
  196. CCriticalSection::Owner lock( m_csSend );
  197. BUFFER_MAP::iterator it;
  198. if ( m_theSend.end() != ( it = m_theSend.find( cID ) ) )
  199. {
  200. CBuffer *pBuffer = m_theSend[cID];
  201. ASSERT( pBuffer );
  202. pBuffer->SetUserData( lnUserData );
  203. pBuffer->AddData( pData, dataLength );
  204. }
  205. else
  206. {
  207. CBuffer *pBuffer = m_theAllocator.Allocate();
  208. ASSERT( pBuffer );
  209. pBuffer->SetUserData( lnUserData );
  210. pBuffer->AddData( pData, dataLength );
  211. m_theSend[cID] = pBuffer;
  212. }
  213. }
  214. void CPackager::AddData( BYTE cID, const BYTE * const pData, size_t dataLength, unsigned long lnUserData /* = 0 */ )
  215. {
  216. AddData( cID, reinterpret_cast< const char * >( pData ), dataLength, lnUserData );
  217. }
  218. void CPackager::DelData( BYTE cID )
  219. {
  220. CCriticalSection::Owner lock( m_csSend );
  221. BUFFER_MAP::iterator it;
  222. if ( m_theSend.end() != ( it = m_theSend.find( cID ) ) )
  223. {
  224. CBuffer *pBuffer = m_theSend[cID];
  225. SAFE_RELEASE( pBuffer );
  226. m_theSend.erase( cID );
  227. }
  228. }
  229. CBuffer *CPackager::GetHeadPack( BYTE cID, size_t packLength /* = 512 */ )
  230. {
  231. CCriticalSection::Owner lock( m_csSend );
  232. BUFFER_MAP::iterator it;
  233. if ( m_theSend.end() != ( it = m_theSend.find( cID ) ) )
  234. {
  235. CBuffer *pBuffer = m_theSend[cID];
  236. CBuffer *pPack = pBuffer->GetHeadPack( packLength - 2 /* enumPackHeader + cID */);
  237. if ( NULL == pPack )
  238. {
  239. return NULL;
  240. }
  241. if ( 0 == pPack->GetUsed() )
  242. {
  243. pPack->Release();
  244. return NULL;
  245. }
  246. CBuffer *pNewBufer = m_theAllocator.Allocate();
  247. /*
  248.  * Add a prototype
  249.  */
  250. pNewBufer->AddData( cID );
  251. /*
  252.  * Add a flag
  253.  */
  254. BYTE cFlag = enumPackHeader;
  255. if ( !pBuffer->HaveNextPack() )
  256. {
  257. cFlag |= enumPackTail;
  258. }
  259. pNewBufer->AddData( cFlag );
  260. /*
  261.  * Add a user data into this buffer
  262.  */
  263. unsigned long lnUserData = pBuffer->GetUserData();
  264. pNewBufer->AddData( ( const char * )( &lnUserData ), sizeof( unsigned long ) );
  265. /*
  266.  * Add some data into this buffer
  267.  */
  268. pNewBufer->AddData( pPack->GetBuffer(), pPack->GetUsed() );
  269. pPack->Release();
  270. return pNewBufer;
  271. }
  272. return NULL;
  273. }
  274. CBuffer *CPackager::GetNextPack( BYTE cID )
  275. {
  276. CCriticalSection::Owner lock( m_csSend );
  277. BUFFER_MAP::iterator it;
  278. if ( m_theSend.end() != ( it = m_theSend.find( cID ) ) )
  279. {
  280. CBuffer *pBuffer = m_theSend[cID];
  281. CBuffer *pPack = pBuffer->GetNextPack();
  282. if ( NULL == pPack )
  283. {
  284. return NULL;
  285. }
  286. if ( 0 == pPack->GetUsed() )
  287. {
  288. pPack->Release();
  289. return NULL;
  290. }
  291. CBuffer *pNewBufer = m_theAllocator.Allocate();
  292. pNewBufer->AddData( cID );
  293. BYTE cFlag = enumPackMiddle;
  294. if ( !pBuffer->HaveNextPack() )
  295. {
  296. cFlag |= enumPackTail;
  297. }
  298. pNewBufer->AddData( cFlag );
  299. /*
  300.  * Add a user data into this buffer
  301.  */
  302. unsigned long lnUserData = pBuffer->GetUserData();
  303. pNewBufer->AddData( ( const char * )( &lnUserData ), sizeof( unsigned long ) );
  304. /*
  305.  * Add some data into this buffer
  306.  */
  307. pNewBufer->AddData( pPack->GetBuffer(), pPack->GetUsed() );
  308. pPack->Release();
  309. return pNewBufer;
  310. }
  311. return NULL;
  312. }
  313. CBuffer *CPackager::PackUp( const void *pData, size_t dataLength )
  314. {
  315. CCriticalSection::Owner lock( m_csRecv );
  316. if ( NULL == pData || dataLength < 3 /* cID + cPackFlag + ... */ )
  317. {
  318. return NULL;
  319. }
  320. BYTE cID = CPackager::Peek( pData );
  321. BUFFER_MAP::iterator it;
  322. if ( m_theRecv.end() == ( it = m_theRecv.find( cID ) ) )
  323. {
  324. CBuffer *pPack = m_theAllocator.Allocate();
  325. m_theRecv[cID] = pPack;
  326. }
  327. CBuffer *pBuffer = m_theRecv[cID];
  328. ASSERT( pBuffer );
  329. BYTE cFlag = CPackager::Peek( pData, 1 );
  330. const size_t nDataBegin = 1 + 1 + sizeof( unsigned long );
  331. if ( _Header( cFlag ) )
  332. {
  333. pBuffer->Empty();
  334. pBuffer->AddData( ( ( const char * )pData + nDataBegin ), dataLength - nDataBegin );
  335. }
  336. if ( _Middle( cFlag ) )
  337. {
  338. pBuffer->AddData( ( ( const char * )pData + nDataBegin ), dataLength - nDataBegin );
  339. }
  340. if ( _Tail( cFlag ) )
  341. {
  342. unsigned long lnUserData = *( const unsigned long * )( ( const char * )pData + 2 );
  343. pBuffer->SetUserData( lnUserData );
  344. pBuffer->AddRef();
  345. return pBuffer;
  346. }
  347. if ( _Error( cFlag ) )
  348. {
  349. ASSERT( NULL && "CPackager::PackUp - Invalid package!" );
  350. }
  351. return NULL;
  352. }
  353. void CPackager::Empty()
  354. {
  355. /*
  356.  * Send
  357.  */
  358. {
  359. CCriticalSection::Owner lock( m_csSend );
  360. BUFFER_MAP::iterator it;
  361. for ( it = m_theSend.begin(); it != m_theSend.end(); it ++ )
  362. {
  363. CBuffer *pBuffer = (*it).second;
  364. SAFE_RELEASE( pBuffer );
  365. }
  366. m_theSend.erase( m_theSend.begin(), m_theSend.end() );
  367. }
  368. /*
  369.  * Recv
  370.  */
  371. {
  372. CCriticalSection::Owner lock( m_csRecv );
  373. BUFFER_MAP::iterator it;
  374. for ( it = m_theRecv.begin(); it != m_theRecv.end(); it ++ )
  375. {
  376. CBuffer *pBuffer = (*it).second;
  377. SAFE_RELEASE( pBuffer );
  378. }
  379. m_theRecv.erase( m_theRecv.begin(), m_theRecv.end() );
  380. }
  381. }
  382. } // End of namespace OnlineGameLib
  383. } // End of namespace Win32