260 lines
9.5 KiB
C++
260 lines
9.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;
|
||
}
|
||
|