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

模拟服务器

开发平台:

C/C++

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