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

260 lines
4.5 KiB
C++

#include "StdAfx.h"
#include "Buffer.h"
#include "Log.h"
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
CBuffer::CBuffer(const int nSize): m_Head(0), m_Tail(0), m_Count(0), m_MaxSize(0)
{
m_MaxSize = nSize;
m_pBuffer = new char[nSize];
memset(m_pBuffer, 0, sizeof(char)*nSize);
}
CBuffer::~CBuffer(void)
{
SAFE_DELETEA(m_pBuffer);
}
int CBuffer::GetCount()
{
m_Lock.Lock();
int nCount = m_Count;
m_Lock.UnLock();
return nCount;
}
void CBuffer::Clear(bool bBufferClear)
{
m_Lock.Lock();
m_Head = m_Tail = m_Count = 0;
if (bBufferClear) memset(m_pBuffer, 0, sizeof(char)*m_MaxSize);
m_Lock.UnLock();
}
int CBuffer::Push(const char *pData, int nSize, bool bIsUserSession/*=false*/, bool bIncreaseBuffer/*=false*/ )
{
m_Lock.Lock();
if (nSize <= 0)
{
m_Lock.UnLock();
return -1;
}
// 버퍼 늘리기
if (m_Count + nSize > m_MaxSize){
int NewSize = m_MaxSize * 2;
if (NewSize < m_Count + nSize) NewSize = m_Count + nSize;
if( (bIsUserSession&&!bIncreaseBuffer) || NewSize > 10000000 )
{
m_Lock.UnLock();
return -2; // buffer 부족
}
char *pNewBuffer = new char [NewSize];
View(pNewBuffer, m_Count);
m_Head = 0;
m_Tail = m_Count;
m_MaxSize = NewSize;
delete []m_pBuffer;
m_pBuffer = pNewBuffer;
}
if (m_Tail + nSize <= m_MaxSize)
{
memcpy(m_pBuffer + m_Tail, pData, nSize);
m_Tail += nSize;
}
else {
int Temp = m_MaxSize - m_Tail;
memcpy(m_pBuffer + m_Tail, pData, Temp);
memcpy(m_pBuffer, pData + Temp, nSize - Temp);
m_Tail = (m_Tail + nSize) % m_MaxSize;
}
m_Count += nSize;
m_Lock.UnLock();
return 0;
}
int CBuffer::Insert( const char *pData, int nSize )
{
m_Lock.Lock();
if (nSize <= 0)
{
m_Lock.UnLock();
return -1;
}
// 버퍼 늘리기
if (m_Count + nSize > m_MaxSize) {
int NewSize = m_MaxSize * 2;
if (NewSize < m_Count + nSize) NewSize = m_Count + nSize;
if( NewSize > 10000000 )
{
m_Lock.UnLock();
return -1;
}
char *pNewBuffer = new char [NewSize];
memcpy( pNewBuffer, pData, nSize );
View(pNewBuffer + nSize, m_Count);
m_Head = 0;
m_Tail = m_Count + nSize;
m_MaxSize = NewSize;
delete []m_pBuffer;
m_pBuffer = pNewBuffer;
}
else {
if (m_Head - nSize < 0)
{
int Temp = nSize - m_Head;
memcpy(m_pBuffer, pData + nSize - m_Head, m_Head);
memcpy(m_pBuffer + m_MaxSize - Temp, pData, Temp);
m_Head = m_MaxSize - Temp;
}
else {
memcpy( m_pBuffer + m_Head - nSize, pData, nSize );
m_Head -= nSize;
}
}
m_Count += nSize;
m_Lock.UnLock();
return 0;
}
int CBuffer::Pop(char *pData, const int nSize)
{
m_Lock.Lock();
if ((nSize <= 0) || (m_Count < nSize)){
m_Lock.UnLock();
return -1;
}
if (m_Head + nSize < m_MaxSize){
memcpy(pData, m_pBuffer + m_Head, nSize);
m_Head += nSize;
}
else {
int Temp = m_MaxSize - m_Head;
memcpy(pData, m_pBuffer + m_Head, Temp);
memcpy(pData + Temp, m_pBuffer, nSize - Temp);
m_Head = (m_Head + nSize) % m_MaxSize;
}
m_Count -= nSize;
m_Lock.UnLock();
return 0;
}
int CBuffer::View(char *pData, const int nSize)
{
m_Lock.Lock();
if ((nSize <= 0) || (m_Count < nSize)){
m_Lock.UnLock();
return -1;
}
if (m_Head + nSize < m_MaxSize){
memcpy(pData, m_pBuffer + m_Head, nSize);
}
else {
int Temp = m_MaxSize - m_Head;
memcpy(pData, m_pBuffer + m_Head, Temp);
memcpy(pData + Temp, m_pBuffer, nSize - Temp);
}
m_Lock.UnLock();
return 0;
}
int CBuffer::Skip(const int nSize)
{
m_Lock.Lock();
if ((nSize <= 0) || (m_Count < nSize)){
m_Lock.UnLock();
return -1;
}
if (m_Head + nSize < m_MaxSize){
m_Head += nSize;
}
else {
m_Head = (m_Head + nSize) % m_MaxSize;
}
m_Count -= nSize;
m_Lock.UnLock();
return 0;
}
bool CBuffer::IsComplete() // SendBuffer용
{
USHORT SendSize = 0;
m_Lock.Lock();
if (m_Count >= (int)sizeof(USHORT)){
View((char*)&SendSize, sizeof(USHORT));
if (m_Count >= SendSize){
m_Lock.UnLock();
return true;
}
}
m_Lock.UnLock();
return false;
}
int CBuffer::IsComplete(bool boServer) // RecvBuffer용
{
USHORT RecvSize = 0;
m_Lock.Lock();
if (m_Count >= (int)sizeof(USHORT)){
View((char*)&RecvSize, sizeof(USHORT));
if (RecvSize == 0 || (!boServer && RecvSize > 4096) || (boServer && RecvSize > 51200)){
m_Lock.UnLock();
return SIZEERR;
}
if (m_Count >= RecvSize){
m_Lock.UnLock();
return COMPLETE;
}
}
m_Lock.UnLock();
return NONE;
}
USHORT CBuffer::GetComplete(char *pData) // 완료패킷가져오기
{
USHORT Recv = 0;
m_Lock.Lock();
View((char*)&Recv, sizeof(USHORT));
if (Pop(pData, Recv) < 0){
m_Lock.UnLock();
return 0;
}
m_Lock.UnLock();
return Recv;
}