DragonNest/Common/NetworkLib/DoubleBuffer.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

220 lines
5.5 KiB
C++

#include "StdAfx.h"
#include "../Protocol/DNPacket.h"
#include "SocketContext.h"
#include "DoubleBuffer.h"
//==================================================================================================================================================//
// Class CDoubleBuffer
//==================================================================================================================================================//
CDoubleBuffer::CDoubleBuffer( const UINT uiSize )
: m_uiActiveBufferIndex(0)
{
for( int i=0 ; i<2 ; ++i )
{
m_pBuffer[i] = new (std::nothrow) char[uiSize];
m_uiBufferOffset[i] = 0;
m_uiBufferSize[i] = uiSize;
}
}
CDoubleBuffer::~CDoubleBuffer()
{
for( int i=0 ; i<2 ; ++i )
{
if( m_pBuffer[i] )
{
delete[] m_pBuffer[i];
m_pBuffer[i] = NULL;
}
}
}
void CDoubleBuffer::Clear()
{
ScopeLock<CSyncLock> Lock( m_Lock );
for( int i=0 ; i<2 ; ++i )
m_uiBufferOffset[i] = 0;
}
int CDoubleBuffer::Switch( char*& pReturnBuffer, UINT& uiReturnSize )
{
ScopeLock<CSyncLock> Lock( m_Lock );
pReturnBuffer = m_pBuffer[m_uiActiveBufferIndex];
uiReturnSize = m_uiBufferOffset[m_uiActiveBufferIndex];
m_uiActiveBufferIndex ^= 1;
m_uiBufferOffset[m_uiActiveBufferIndex] = 0;
return 0;
}
#if defined( _DB )
int CDoubleBuffer::Pop( char* pDest, UINT& uiReturnSize )
{
ScopeLock<CSyncLock> Lock( m_Lock );
if( m_uiBufferOffset[m_uiActiveBufferIndex] > PROCESSBUFFERLENMAX )
return -1;
memcpy( pDest, m_pBuffer[m_uiActiveBufferIndex], m_uiBufferOffset[m_uiActiveBufferIndex] );
uiReturnSize = m_uiBufferOffset[m_uiActiveBufferIndex];
m_uiBufferOffset[m_uiActiveBufferIndex] = 0;
return 0;
}
#endif
int CDoubleBuffer::Resize( const UINT32 uiSize )
{
// 상위에서 동기화 되는 함수
_ASSERT( m_uiBufferSize[m_uiActiveBufferIndex] < uiSize );
char* pResizeBuffer = new (std::nothrow) char[uiSize];
if( pResizeBuffer == NULL )
return -1;
if( m_uiBufferOffset[m_uiActiveBufferIndex] )
memcpy( pResizeBuffer, m_pBuffer[m_uiActiveBufferIndex], m_uiBufferOffset[m_uiActiveBufferIndex] );
delete[] m_pBuffer[m_uiActiveBufferIndex];
m_pBuffer[m_uiActiveBufferIndex] = pResizeBuffer;
m_uiBufferSize[m_uiActiveBufferIndex] = uiSize;
return 0;
}
int CDoubleBuffer::RawPush( const void* pSrc, const UINT uiLen )
{
// 상위에서 동기화 되는 함수
if( m_uiBufferOffset[m_uiActiveBufferIndex] + uiLen > m_uiBufferSize[m_uiActiveBufferIndex] )
{
if( Resize( m_uiBufferSize[m_uiActiveBufferIndex]*2 ) < 0 )
return -1;
// Buffer Resize 해도 모자란다면 에러처리한다.
// Buffer 를 다시 Resize 해도 되지만 정상적인 경우 발생할 수 없는 경우이기 때문에 따로 예외처리 하지 않는다.
if( m_uiBufferOffset[m_uiActiveBufferIndex] + uiLen > m_uiBufferSize[m_uiActiveBufferIndex] )
return -1;
}
char* pBuffer = m_pBuffer[m_uiActiveBufferIndex] + m_uiBufferOffset[m_uiActiveBufferIndex];
memcpy( pBuffer, pSrc, uiLen );
m_uiBufferOffset[m_uiActiveBufferIndex] += uiLen;
return 0;
}
//==================================================================================================================================================//
// Class CTcpRecvBuffer
//==================================================================================================================================================//
CTcpRecvBuffer::CTcpRecvBuffer( const UINT uiSize )
: CDoubleBuffer( uiSize )
{
}
CTcpRecvBuffer::~CTcpRecvBuffer()
{
}
int CTcpRecvBuffer::Push( CSocketContext *pSocketContext )
{
ScopeLock<CSyncLock> Lock( m_Lock );
int iPushCount = 0;
const char* pRecvBuffer = pSocketContext->m_RecvIO.buffer;
UINT uiRecvBufferLen = pSocketContext->m_RecvIO.Len;
while( uiRecvBufferLen )
{
UINT uiPacketLen = GetCompletePacketLength( pRecvBuffer, uiRecvBufferLen );
if( uiPacketLen <= 0 )
break;
if( RawPush( pRecvBuffer, uiPacketLen ) < 0 )
return -1;
pRecvBuffer += uiPacketLen;
uiRecvBufferLen -= uiPacketLen;
++iPushCount;
}
if( iPushCount > 0 )
{
pSocketContext->m_RecvIO.Len = uiRecvBufferLen;
if( uiRecvBufferLen )
memmove( &pSocketContext->m_RecvIO.buffer, pRecvBuffer, uiRecvBufferLen );
}
return iPushCount;
}
int CTcpRecvBuffer::Push( const DNTPacket& Packet )
{
ScopeLock<CSyncLock> Lock( m_Lock );
return RawPush( &Packet, Packet.iLen );
}
UINT CTcpRecvBuffer::GetCompletePacketLength( const void* pBuffer, const UINT uiLen ) const
{
// 상위에서 동기화 되는 함수
// iLen + cMainCmd + cSubCmd
static const UINT uiTcpPacketHeaderSize = sizeof(USHORT)+sizeof(UCHAR)+sizeof(UCHAR);
if( uiLen < uiTcpPacketHeaderSize )
return 0;
const DNTPacket* pPacket = static_cast<const DNTPacket*>(pBuffer);
return (pPacket->iLen <= uiLen) ? pPacket->iLen : 0;
}
//==================================================================================================================================================//
// Class CRawBuffer
//==================================================================================================================================================//
CRawBuffer::CRawBuffer( const UINT uiSize )
: CDoubleBuffer( uiSize ), m_bIsLock( false )
{
}
CRawBuffer::~CRawBuffer()
{
}
int CRawBuffer::Push( const void* pSrc, const UINT uiLen )
{
_ASSERT( m_bIsLock == true );
// 상위에서 LOCK 걸어줘야 함
if( RawPush( pSrc, uiLen ) < 0 )
return -1;
return uiLen;
}
void CRawBuffer::Lock()
{
m_Lock.Lock();
m_bIsLock = true;
}
void CRawBuffer::UnLock()
{
m_Lock.UnLock();
m_bIsLock = false;
}
UINT CRawBuffer::GetCompletePacketLength( const void* pBuffer, const UINT uiLen ) const
{
return uiLen;
}