Files
2022-10-26 12:25:11 +08:00

233 lines
6.2 KiB
C++

#ifndef __VAR_PACKET_H__
#define __VAR_PACKET_H__
#pragma once
#include <windows.h>
#include <assert.h>
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 가변 패킷을 편리하기 사용하기 위한 클래스 그 두번째
//
/**
@author
Waverix < waverix@webzen.co.kr >
@since
2007. 09. 10
@remarks
- Packet Broadcaster 제작을 위해 고안된 VarMsg2 개량형
- 1..n 용 Broadcast용 패킷 구현이 용이
- n..1 용 Unicast용 패킷 구현이 용이 (VarMsg, VarPacket 대체용도)
@example
- typedef VARMSG_EX<VARMSG_T01, MSG_AG_CONNECTION_PACKET_BROADCASTER_ONEtoN_SYN>
MSG_ONEtoN_BROADCASTER;
*/
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
enum eVARMSGEX_T
{
VARMSG_T00 ,
VARMSG_T01 , //MSG_AG_CONNECTION_PACKET_BROADCASTER_ONEtoN_SYN
VARMSG_T02 ,
VARMSG_T03 ,
VARMSG_T04 , //VARMSG_ASSEMBLER0
VARMSG_T05 , //VARMSG_ASSEMBLER1
VARMSG_T06 , //VARMSG_ASSEMBLER2
VARMSG_T07 , //VARMSG_ASSEMBLER3
VARMSG_T08 , //VARMSG_ASSEMBLER4
VARMSG_T09 ,
VARMSG_T10 ,
VARMSG_T11 ,
VARMSG_T12 ,
VARMSG_T13 ,
VARMSG_T14 ,
VARMSG_T15 ,
VARMSG_T16 ,
VARMSG_T17 ,
VARMSG_T18 ,
VARMSG_T19 ,
VARMSG_T20 ,
};
template<typename eVARMSGEX_T _VMET, typename _BASETYPE>
struct VARMSG_EX
{
static const INT BUFFER_SIZE = (INT) ((WORD)-1); // 65535
VARMSG_EX() { Clear(); MSG_STREAM[0] = 0; }
// VARMSG_EX의 시작을 알리는 경종소리...
inline static _BASETYPE& InstanceOfBase()
{
MSG_STREAM_OFFSET = 0;
//ZeroMemory( MSG_STREAM, sizeof(_BASETYPE) ); <- (WAVERIX)(080829) REMOVE
return *(new (MSG_STREAM) _BASETYPE);
}
inline static VOID Clear() { SetTotalSize(0); }
inline static VOID ClearStream( INT iClearSize )
{
INT iClearSizeCalced = (iClearSize && iClearSize < BUFFER_SIZE) ? iClearSize : (INT)sizeof(MSG_STREAM) ;
ZeroMemory( MSG_STREAM, iClearSizeCalced );
}
inline static _BASETYPE* GetFirstPacketPtr() { return (_BASETYPE*)MSG_STREAM; }
inline static VOID SetTotalSize( INT iTotalSize ) { MSG_STREAM_OFFSET = iTotalSize; }
inline static INT GetTotalSize() { return MSG_STREAM_OFFSET; }
inline static INT AddOffset( INT iSize ) { MSG_STREAM_OFFSET += iSize; return MSG_STREAM_OFFSET; }
inline static INT ControlOffset( BOOL bIsPlus, SIZE_T szSize )
{
INT iOffset = bIsPlus ? (INT)szSize : -((INT)szSize);
MSG_STREAM_OFFSET += iOffset;
return MSG_STREAM_OFFSET;
}
// 세부 타입에 관련된 처리 루틴
// - 가변 패킷으로서 뒤이어 들어올 타입을 선언해 주면, 그것의 기본 생성자를 호출하면서 객체 반환
// { NEXT_TYPE& rNT = VARMSG_EX_T::InstanceOf<NEXT_TYPE>(); }
template<typename _TYPE>
inline static _TYPE& InstanceOf()
{
BYTE* pPTR = &MSG_STREAM[MSG_STREAM_OFFSET];
ZeroMemory( pPTR, sizeof(_TYPE) );
return *(new (pPTR) _TYPE);
}
// 세부 타입에 관련된 처리 루틴
// - 가변 패킷으로서 뒤이어 들어올 타입을 선언해 주면, 그것의 객체 반환 (초기화 없음)
// { NEXT_TYPE& rNT = VARMSG_EX_T::InstanceOf<NEXT_TYPE>(); }
template<typename _TYPE>
inline static _TYPE& TypeOf()
{
BYTE* pPTR = &MSG_STREAM[MSG_STREAM_OFFSET];
return *(_TYPE*)pPTR;
}
static DWORD MSG_STREAM_OFFSET;
static BYTE MSG_STREAM[BUFFER_SIZE];
};
template<typename eVARMSGEX_T _VMET, typename _BASETYPE>
DWORD VARMSG_EX<_VMET, _BASETYPE>::MSG_STREAM_OFFSET = 0;
template<typename eVARMSGEX_T _VMET, typename _BASETYPE>
BYTE VARMSG_EX<_VMET, _BASETYPE>::MSG_STREAM[BUFFER_SIZE];
//=======================================================================================================================
/// 가변 패킷을 편리하게 사용하기 위한 클래스
/**
@author
Kim Min Wook < taiyo@webzen.co.kr >
@since
2004. 11. 30
@remarks
- 템플릿으로 만들어서 가변적인 버퍼 사이즈를 줄 수 있게 했다.
- buffer overrun error처리를 할 수 있다.
@note
- 보내는 패킷과 받는 패킷의 처리방법이 다르므로 사용법에 주의한다.
@Usage
- 보낼때
VarPacket<100> varpack;
varpack.SetShort(2344);
varpack.SetStream("스트링이거나버퍼다", strlen("스트링이거나버퍼다"));
- 받을때
short data1 = 0;
char data2[128]; // 충분히 할당
pPacket = VarPacket<>::GetShort( pPacket, data1 );
pPacket = VarPacket<>::GetStream( pPacket, data2 );
*/
//=======================================================================================================================
template <WORD BUFFER_SIZE = 1>
class VarPacket
{
public:
VarPacket() : m_wSize( 0 ) {}
~VarPacket() {}
static BYTE * GetChar( BYTE * pPacket, char & cChar )
{
cChar = *(char*)pPacket;
return ( pPacket + 1 );
}
static BYTE * GetShort( BYTE * pPacket, short & sShort )
{
sShort = *(short *)pPacket;
return ( pPacket + 2 );
}
static BYTE * GetInteger( BYTE * pPacket, int & iInteger )
{
iInteger = *(int *)pPacket;
return ( pPacket + 4 );
}
static BYTE * GetBigInteger( BYTE * pPacket, __int64 & i64BigInteger )
{
i64BigInteger = *(__int64 *)pPacket;
return ( pPacket + 8 );
}
static BYTE * GetStream( BYTE * pPacket, BYTE * pBuffer )
{
short size = 0;
pPacket = GetShort( pPacket, size );
memcpy( pBuffer, pPacket, size );
return pPacket + size;
}
VOID SetChar( char cChar )
{
m_pPacketBuffer[m_wSize] = cChar;
m_wSize += 1;
assert( m_wSize < BUFFER_SIZE );
}
VOID SetShort( short sShort )
{
*(short*)&m_pPacketBuffer[m_wSize] = sShort;
m_wSize += 2;
assert( m_wSize < BUFFER_SIZE );
}
VOID SetInteger( int iInteger )
{
*(int*)&m_pPacketBuffer[m_wSize] = iInteger;
m_wSize += 4;
assert( m_wSize < BUFFER_SIZE );
}
VOID SetBigInteger( __int64 i64BigInteger )
{
*(__int64*)&m_pPacketBuffer[m_wSize] = i64BigInteger;
m_wSize += 8;
assert( m_wSize < BUFFER_SIZE );
}
VOID SetStream( BYTE * pBuffer, short sSize )
{
SetShort( sSize );
memcpy( &m_pPacketBuffer[m_wSize], pBuffer, sSize );
m_wSize += sSize;
assert( m_wSize < BUFFER_SIZE );
}
/*
// 타입별로 만들어 줘야 한다!
VOID operator << ( int data ){}
VOID operator >> ( int data ){}
*/
BYTE * GetBufferPointer() { return &m_pPacketBuffer[m_wSize]; }
WORD GetSize() { return m_wSize; }
BYTE * GetPtr() { return &m_pPacketBuffer[0]; }
VOID Reset() { m_wSize = 0; }
private:
BYTE m_pPacketBuffer[BUFFER_SIZE];
WORD m_wSize;
};
#endif // __VAR_PACKET_H__