직렬화 버퍼는 구조화된 데이터를 바이트 스트림으로 변환하거나, 반대로 바이트 스트림을 구조화된 데이터로 변환 하기 위해 사용하는 버퍼를 말한다.
📦 사용 목적
- 네트워크 전송: 구조체 -> 바이트 스트림으로 만들어서 전송
- 파일 저장: 바이너리 형태로 저장하기 위해 직렬화 필요
- 패킷 시스템: 커스텀 패킷 포맷 구성 시 필수
구조체 데이터나 일반 데이터를 바이트 스트림으로 패킷에 담아서 전송해야하기 때문에 직렬화 버퍼가 필요하다.
직렬화 버퍼를 담당하는 클래스를 만들어서 사용한다.
#pragma once
#ifdef PACKET
#define PACKET_DLL __declspec(dllexport)
#else
#define PACKET_DLL __declspec(dllimport)
#endif
#define PACKET_BUFFER_DEFAULT_SIZE 100000
// 패킷 클래스
class PACKET_DLL Packet
{
public:
#pragma pack(push,1)
// 패킷 헤더
struct EncodeHeader
{
unsigned char packetCode;
unsigned short packetLen;
unsigned char randXORCode;
unsigned char checkSum;
};
#pragma pack(pop)
protected:
char _packetBuffer[PACKET_BUFFER_DEFAULT_SIZE];
unsigned int _header;
unsigned int _front;
unsigned int _rear;
unsigned int _bufferSize;
unsigned int _useBufferSize;
unsigned char _key;
public:
Packet();
~Packet();
void Clear(void);
unsigned int GetBufferSize(void);
unsigned int GetUseBufferSize(void);
void MoveRearPosition(int size);
void MoveFrontPosition(int size);
// 데이터 넣기
Packet& operator = (Packet& packet);
template<typename T>
Packet& operator<<(T& value);
template<typename T>
Packet& operator<<(const std::pair<T, int>& value);
// 데이터 빼기
template<typename T>
Packet& operator>>(T& value);
template<typename T>
Packet& operator>>(const std::pair<T, int>& value);
int GetData(char* dest, int size);
int GetData(wchar_t* dest, int size);
// 헤더 설정
void SetHeader(char* header, char size);
// 패킷 인코딩
bool Encode(void);
// 패킷 디코딩
bool Decode(void);
};
template<typename T>
Packet& Packet::operator<<(T& value)
{
memcpy(&_packetBuffer[_rear], &value, sizeof(T));
_rear += sizeof(T);
_useBufferSize += sizeof(T);
return *(this);
}
template<typename T>
Packet& Packet::operator<<(const std::pair<T, int>& value)
{
*this << value.second;
memcpy(&_packetBuffer[_rear], value.first, value.second);
_rear += value.second;
_useBufferSize += value.second;
return *(this);
}
template<typename T>
Packet& Packet::operator>>(T& value)
{
memcpy(&value, &_packetBuffer[_front], sizeof(T));
_front += sizeof(T);
_useBufferSize -= sizeof(T);
return *(this);
}
template<typename T>
Packet& Packet::operator>>(const std::pair<T, int>& value)
{
memcpy(value.first, &_packetBuffer[_front], value.second);
_front += value.second;
_useBufferSize -= value.second;
return *(this);
}
연산자 <<를 오버로딩해서 데이터를 쉽게 직렬화버퍼에 담을 수 있도록 한다.
Encode를 통해 직렬화버퍼 안에 있는 데이터를 암호화하고 Decode를 통해 복호화한다.
Packet* newPacket = new Packet();
char* stringData = new char[10];
int data = 10;
*newPacket << data;
*newPacket << make_pair(stringData, 10);
위와 같이 사용하면 된다.