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

模拟服务器

开发平台:

C/C++

  1. #include "IOBuffer.h"
  2. #include "Exception.h"
  3. #include "Utils.h"
  4. #include <assert.h>
  5. /*
  6.  * namespace OnlineGameLib::Win32
  7.  */
  8. namespace OnlineGameLib {
  9. namespace Win32 {
  10. CIOBuffer::CIOBuffer( Allocator &allocator, size_t size )
  11.    : m_operation(0),
  12.      m_allocator(allocator),
  13.      m_ref(1),
  14.      m_size(size), 
  15.      m_used(0)
  16. {
  17. memset( this, 0, sizeof( OVERLAPPED ) );
  18. Empty();
  19. }
  20. WSABUF *CIOBuffer::GetWSABUF() const
  21. {
  22. return const_cast<WSABUF *>( &m_wsabuf );
  23. }
  24. size_t CIOBuffer::GetUsed() const
  25. {
  26. return m_used;
  27. }
  28. size_t CIOBuffer::GetSize() const
  29. {
  30. return m_size;
  31. }
  32. const BYTE *CIOBuffer::GetBuffer() const
  33. {
  34.    return &m_buffer[0];
  35. }
  36. void CIOBuffer::Empty()
  37. {
  38. m_wsabuf.buf = reinterpret_cast<char *>( m_buffer );
  39. m_wsabuf.len = m_size;
  40. m_used = 0;
  41. }
  42. void *CIOBuffer::operator new( size_t objectSize, size_t bufferSize )
  43. {
  44. void *pMem = new char[objectSize + bufferSize];
  45. return pMem;
  46. }
  47. void CIOBuffer::operator delete( void *pObject, size_t /* bufferSize*/ )
  48. {
  49. delete [] pObject;
  50. }  
  51. void CIOBuffer::Use( size_t dataUsed )
  52. {
  53. m_used += dataUsed;
  54. }
  55. CIOBuffer *CIOBuffer::SplitBuffer( size_t bytesToRemove )
  56. {
  57. CIOBuffer *pNewBuffer = m_allocator.Allocate();
  58. pNewBuffer->AddData( m_buffer, bytesToRemove );
  59. assert( m_used > bytesToRemove );
  60. m_used -= bytesToRemove;
  61. memmove( m_buffer, m_buffer + bytesToRemove, m_used );
  62. return pNewBuffer;
  63. }
  64. CIOBuffer *CIOBuffer::AllocateNewBuffer() const
  65. {
  66. return m_allocator.Allocate();
  67. }
  68. void CIOBuffer::ConsumeAndRemove( size_t bytesToRemove )
  69. {
  70. m_used -= bytesToRemove;
  71. memmove( m_buffer, m_buffer + bytesToRemove, m_used );
  72. }
  73. void CIOBuffer::SetupRead()
  74. {
  75. if ( 0 == m_used )
  76. {
  77. m_wsabuf.buf = reinterpret_cast<char *>( m_buffer );
  78. m_wsabuf.len = m_size;
  79. }
  80. else
  81. {
  82. m_wsabuf.buf = reinterpret_cast<char *>( m_buffer ) + m_used;
  83. m_wsabuf.len = m_size - m_used; 
  84. }
  85. }
  86. void CIOBuffer::SetupWrite()
  87. {
  88. m_wsabuf.buf = reinterpret_cast<char *>( m_buffer );
  89. m_wsabuf.len = m_used;
  90. m_used = 0;
  91. }
  92. void CIOBuffer::AddData( const char * const pData, size_t dataLength )
  93. {
  94. /* if ( dataLength > m_size - m_used )
  95. {
  96. throw CException( _T("CIOBuffer::AddData"), _T("Not enough space in buffer") );
  97. }
  98. */
  99. assert( dataLength <= m_size - m_used );
  100. memcpy( m_buffer + m_used, pData, dataLength );
  101. m_used += dataLength;
  102. }
  103. void CIOBuffer::AddData( const BYTE * const pData, size_t dataLength )
  104. {
  105. AddData( reinterpret_cast<const char*>( pData ), dataLength );
  106. }
  107. void CIOBuffer::AddData( BYTE data )
  108. {
  109. AddData( &data, 1 );
  110. }
  111. void CIOBuffer::AddRef()
  112. {
  113. ::InterlockedIncrement( &m_ref );
  114. }
  115. void CIOBuffer::Release()
  116. {
  117. if ( 0 == ::InterlockedDecrement( &m_ref ) )
  118. {
  119. m_allocator.Release( this );
  120. }
  121. }
  122. size_t CIOBuffer::GetOperation() const
  123. {
  124. return m_operation;
  125. }
  126.       
  127. void CIOBuffer::SetOperation( size_t operation )
  128. {
  129. m_operation = operation;
  130. }
  131. /*
  132.  * CIOBuffer::Allocator
  133.  */
  134. CIOBuffer::Allocator::Allocator( size_t bufferSize, size_t maxFreeBuffers )
  135.    : m_bufferSize(bufferSize), m_maxFreeBuffers(maxFreeBuffers)
  136. {
  137.    /*
  138.     * TODO : share this code with the socket pool
  139. */
  140. }
  141. CIOBuffer::Allocator::~Allocator()
  142. {
  143. try
  144. {
  145. Flush();
  146. }
  147. catch(...)
  148. {
  149. }
  150. }
  151. CIOBuffer *CIOBuffer::Allocator::Allocate()
  152. {
  153. CCriticalSection::Owner lock( m_criticalSection );
  154. CIOBuffer *pBuffer = 0;
  155. if ( !m_freeList.Empty() )
  156. {
  157. pBuffer = m_freeList.PopNode();
  158. pBuffer->AddRef();
  159. }
  160. else
  161. {
  162. pBuffer = new( m_bufferSize )CIOBuffer( *this, m_bufferSize );
  163. if ( !pBuffer )
  164. {
  165. throw CException( _T("CIOBuffer::Allocator::Allocate()"),_T("Out of memory") );
  166. }
  167. /*
  168.  * Call to unqualified virtual function
  169.  */
  170. OnBufferCreated();
  171. }
  172. m_activeList.PushNode( pBuffer );
  173. /*
  174.  * call to unqualified virtual function
  175.  */
  176. OnBufferAllocated();
  177. return pBuffer;
  178. }
  179. void CIOBuffer::Allocator::Release( CIOBuffer *pBuffer )
  180. {
  181. if ( !pBuffer )
  182. {
  183. throw CException( _T("CIOBuffer::Allocator::Release()"), _T("pBuffer is null") );
  184. }
  185. CCriticalSection::Owner lock( m_criticalSection );
  186. /*
  187.  * Call to unqualified virtual function
  188.  */
  189. OnBufferReleased();
  190. /*
  191.  * unlink from the in use list
  192.  */
  193. pBuffer->RemoveFromList();
  194. if ( m_maxFreeBuffers == 0 || m_freeList.Count() < m_maxFreeBuffers )
  195. {
  196. pBuffer->Empty();           
  197. /*
  198.  * Add to the free list
  199.  */
  200. m_freeList.PushNode( pBuffer );
  201. }
  202. else
  203. {
  204. DestroyBuffer( pBuffer );
  205. }
  206. }
  207. void CIOBuffer::Allocator::Flush()
  208. {
  209. CCriticalSection::Owner lock( m_criticalSection );
  210. while ( !m_activeList.Empty() )
  211. {
  212. /*
  213.  * Call to unqualified virtual function
  214.  */
  215. OnBufferReleased();
  216. DestroyBuffer( m_activeList.PopNode() );
  217. }
  218. while ( !m_freeList.Empty() )
  219. {
  220. DestroyBuffer( m_freeList.PopNode() );
  221. }
  222. }
  223. void CIOBuffer::Allocator::DestroyBuffer( CIOBuffer *pBuffer )
  224. {
  225. delete pBuffer;
  226. /*
  227.  * Call to unqualified virtual function
  228.  */
  229. OnBufferDestroyed();
  230. }
  231. } // End of namespace OnlineGameLib
  232. } // End of namespace Win32