Skip to content

CGLabs/CGDK.buffer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

271 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CGDK::buffer란

CGDK::buffer는 메시지 직렬화 버퍼 시스템
C++버전은 CGDK::buffer (https://github.com/CGLabs/CGDK.buffer/tree/master/C%2B%2B) 이며
C# 버전은 CGDK.buffer (https://github.com/CGLabs/CGDK.buffer/tree/master/C%23)

자세한 소개 (https://github.com/CGLabs/CGDK.buffer/blob/master/C%2B%2B/document/intruduce_CGDK.buffer.pptx)

CGD::buffer

  • C++ 버전
  • 매우 간단합니다.(사실상 append/extract/front가 전부...)
  • 초고성능 (c++ 버전은 tmp로 구현되어 압도적 최강의 성능을 자랑합니다.)
  • 작고 가볍습니다.
  • 자료형에 따라 그에 맞는 직렬화를 수행합니다.
  • Schemaless와 Schema(구조체 직렬화)를 모두 지원합니다.
  • 설정이나 스크립트(IDL)없이 구조체를 그대로 Schema로 사용 가능합니다.
  • C++11 Template Meta Programming을 사용해 구현해 100% template이므로 Include만으로 사용 가능합니다.
  • 지원되는 자료형은
    • 기본 자료형(char,int32_t, ... float, double)
    • enum
    • 문자열(char*, wchar_t*, std::string, std::wstring, std_string_view, ...)
    • 배열(T[N], std::array<T,N>)
    • 컨테이너(std::vector, std::list, std::set,std::map<K,V>, ...)
    • 시간(chrono::time_point, chrono::duration, ...)
    • 포인터(std::shared_ptr, std::unique_ptr)
    • buffer (CGDK::buffer_veiew, CGDK::buffer,CGDK::shared_buffer)
    • struct
    • Ibuffer_serialzable
    • 기타...

CGD.buffer

  • C#버전
  • 직렬화/역직렬화 방법은 C++과 동일합니다.(append/extract)
  • C# 버전 중 최고 성능을 자랑합니다. (Message Pack, Memory Pack 이상!)
  • reflection과 Roslyn + Source Generation을 사용하여 구현하였습니다.
  • C++ 버전과 호환됩니다.


buffer 클래스 종류

[C++]
3종류의 buffer를 제공하고 있으며 모두 상속 관계를 가집니다.

  • CGDK::buffer_view
    data_와 size_만 가진 buffer로 읽기나 덥어쓰기만 가능합니다.
    'extract' 함수(읽어내기)
    'front' 함수(읽기와 덥어 쓰기)

  • CGDK::buffer
    CGDK::buffer_view를 상속받아 경계정보(boung_info)를 추가한 버퍼 클래스입니다.
    'append'함수로 직렬화가 가능합니다.

  • CGDK::shared_buffer
    CGDK::buffer를 상속 받아 스마트 포인터 기능을 더한 버퍼 클래스
    할당된 원본 버퍼를 스마트포인터로 관리합니다.
    alloc_shared_buffer(SIZE) 혹은 make_shared_buffer를 사용해 버퍼를 할당 받을 수 있습니다.

[C#]
하나의 버퍼 클라스만 존재합니다.
(C#은 shared_buffer가 필요하지 않습니다.)

  • CGDK.buffer


CGD::buffer 사용하기

1. 직렬화하기(Schemaless)

버퍼에 데이터를 버퍼에 쓰기는 간단히 append()로 가능합니다.
(TYPE를 생략할 경우 입력되는 값의 자료형으로 간주합니다.)

  buf.append<[TYPE]>([value]);

[C++]

CGDK::shard_buffer bufTemp = alloc_shard_buffer(256);
       
bufTemp.append<uint8_t>(10);
bufTemp.append<char>(20);
bufTemp.append<int>(-100);
bufTemp.append<uint32_t>(1000);
bufTemp.append<std::string>("Test String"); // 문자열도 가능

[C#]

CGDK.buffer bufTemp = new CGDK.buffer(new byte[256]);
       
bufTemp.Append<byte>(10);
bufTemp.Append<sbyte>(20);
bufTemp.Append<int>(-100);
bufTemp.Append<uint>(1000);
bufTemp.Append<string>("Test String");	// 문자열도 가능



2. 역직렬화하기(Schemaless)

  [value] buf.extract<[TYPE]>();

extract() 함수로 간단히 역직렬화를 할 수 있습니다.

[C++]

auto temp1 = bufTemp.extract<uint8_t>();
auto temp2 = bufTemp.extract<char>();
auto temp3 = bufTemp.extract<int>();
auto temp4 = bufTemp.extract<uint32_t>();
auto temp5 = bufTemp.extract<std::string>();

[C#]

var temp1 = bufTemp.Extract<byte>();
var temp2 = bufTemp.Extract<SByte>();
var temp3 = bufTemp.Extract<int>();
var temp4 = bufTemp.Extract<uint>();
var temp5 = bufTemp.Extract<string>();

복합형 데이터의 직렬화/역직렬화도 가능
C++의 vector, list, set, map ....
C#의 List, Dictionary<K,V> ...

[C++]

std::vector<int>                  listTest = { ...};
std::list<std::string>            listStringTest = { ...};
std::map<std::string, int>        mapTemp = { ...};
std::map<int, list<std::string>>  maplistTemp = { ...};
	    
auto bufTemp = CGDK::alloc_shared_buffer(256));
	    
bufTemp.append(listTest);
bufTemp.append(listStringTest);
bufTemp.append(mapTemp);
bufTemp.append(maplistTemp);
	    
.................
// 역직렬화
auto temp1 = bufTemp.extract<std::vector<int>>();
auto temp2 = bufTemp.extract<std::list<std::string>>();
auto temp3 = bufTemp.extract<std::map<int, std::string>>();
auto temp4 = bufTemp.extract<std::map<int, std::list<std::string>>>();

[C#]

List<int>                      listTest = new ...;
List<string>                   listStringTest = new ...;
Dictionary<string, int>        dicTest = new ...;
Dictionary<int, List<string>>  dicListTest = new ...;
       
CGD.buffer bufTemp = new CGD.buffer(new byte[256]);
       
bufTemp.Append(listTest);
bufTemp.Append(listStringTest);
bufTemp.Append(dicTest);
bufTemp.Append(dicListTest);
       
.................
// 역직렬화
var temp1 = bufTemp.Extract<List<int>> ();
var temp2 = bufTemp.Extract<List<string>> ();
var temp3 = bufTemp.Extract<Dictionary<string,int>> ();
var temp4 = bufTemp.Extract<Dictionary<string,List<int>>> ();

bufTemp.append(maplistTemp);

3. 직렬화에 필요한 메모리 크기 구하기

데이터를 직렬화 했을 때의 메모리 크기를 CGDK::get_size_of()르 사용해 얻을 수 있습니다.

[C++]

auto size = CGDK::get_size_of(maplistTemp);

4. 동적 메모리 할당 받기

CGDK::alloc_shared_buffer([SIZE])를 사용해 메모리를 동적 할당 가능합니다.
CGDK::shared_buffer로 할당 받은 버퍼를 받을 수 있으며 스마트 포인터로 관리되므로 참조가 모두 끝나면 자동 할당 해제 됩니다.

[C++]

// 1000byte 메모리를 동적 할당 받는다.
auto temp1 = CGDK::alloc_shared_buffer(1000);

// maplistTemp를 직렬화할 만큼의 메모리를 할당받는다.
auto temp2 = CGDK::alloc_shared_buffer(CGDK::get_size_of(maplistTemp));

5. 정적 메모리 사용하기

CGDK::bufer는 배열이나 std::array를 임시 버퍼로 사용할 수 있습니다.
지역 변수에 직렬화/역직렬화를 하면 성능에 유리할 수 있습니다.

[C++]

// 지역 변수
char temp_memory[256];

// 지역변수를 메모리 버퍼로 활용합니다.
CGDK::buffer bufTemp(temp_memory);

bufTemp.append<int>(10);
bufTemp.append<int>(100);

6. 구조체 직렬화

'구조체 직렬화'를 원하는 구조체에 'ENABLE_STRUCT_SERIALIZABLE'을 추가해 주면 Schema로 사용 가능합니다.

[C++]

struct TEST
{
    ENABLE_STRUCT_SERIALIZABLE

    int       x;
    float     y;
    string    z;
    std::vector<int> w;
};
	    
struct TEST2
{
    ENABLE_STRUCT_SERIALIZABLE

    int       a;
    std::vector<int> b;
    TEST      c;
};

이렇게 정의한 후

[C++]

TEST2  tempData;
	    
auto bufTemp = alloc_shared_buffer(get_size_of(tempData));

// 직렬화	    
bufTemp.append<TEST2>(tempData);
	    
.................
// 역직렬화
var temp1 = bufTemp.extract<TEST2>();

[C#]

TEST2  tempData;

var bufTemp = new CGDK.buffer(CGDK.buffer.GetSizeOf(tempData));

// 직렬화
bufTemp.Append<TEST2>(tempData);

.................
// 역직렬화
var temp1 = bufTemp.Extract<TEST2>();

이렇게 직렬화/역직렬화를 수행가능합니다.
주의) C++의 경우 생성자와 virtaul 함수를 가져서는 안됩니다.


7. 읽기(peek)만 하기

front 함수를 사용하여 읽어내기만 가능합니다.
front 함수를 사용할 경우 읽을 위치(offset)를 지정하여야 합니다. (읽을 위치를 생략하면 0으로 간주합니다.)
c#의 경우 ref set_front와 get_front 함수가 분리 되어 있습니다.

[C++]

bufTemp.append<byte>(10);
bufTemp.append<sbyte>(20);
bufTemp.append<int>(-100);
bufTemp.append<uint>(1000);
bufTemp.append<std::string>("Test String");	// 문자열도 가능

// - front를 사용해 값을 읽을 수 있습니다.
auto value1 = bufTemp.front<uint8_t>(); //
auto value2 = bufTemp.front<char>(1); //
auto value3 = bufTemp.front<int>(2); //
auto value4 = bufTemp.front<uint32_t>(10); // 
auto value5 = bufTemp.front<std::string>(14); // 

[C#]

bufTemp.Append<byte>(10);
bufTemp.Append<sbyte>(20);
bufTemp.Append<int>(-100);
bufTemp.Append<uint>(1000);
bufTemp.Append<string>("Test String");	// 문자열도 가능

// - get_front를 사용해 값을 읽을 수 있습니다.
var value1 = bufTemp.get_front<byte>(); //
var value2 = bufTemp.get_front<sbyte>(1); //
var value3 = bufTemp.get_front<int>(2); //
var value4 = bufTemp.get_front<uint>(10); // 
var value5 = bufTemp.get_front<string>(14); // 

덥어 쓰기도 가능합니다.
c++은 front함수로 가능하며 C#은 set_front함수로 가능합니다.

[C++]

bufTemp.front<int>(2) = 300; // offset 2 위치에 int값 300을 덥어씁니다.

[C#]

bufTemp.SetFront<int>(2, 300); // offset 2위치에 int값 300을 덥어 씁니다.


8. 나중에 덥어 쓰기

c++은 기본 자료형의 append 수행시 참조형 변수로 위치를 받아 놓았다 나중에 그 위치에 다시 덮어 쓸 수 있습니다.
기본 자료형(char, short, int, float 등..)을 append할 경우 해당 위치의 참조형 변수를 리턴해줍니다.
즉, int를 append하면 리턴 값은 int&형이 됩니다. 이것을 사용해서 추후 업데이트가 가능합니다.
front함수를 사용할 때처럼 위치를 직접 지정해 주지 않아도 됩니다.
C#은 포인터가 없어 이러한 방법은 사용할 수 없으므로 위치(Offset값)를 저장했다 SetFront() 함수를 사용해서 업데이트 해야 합니다.

[C++]

bufTemp.append<byte>(10);
bufTemp.append<sbyte>(20);
auto& temp_pos = bufTemp.append<int>(-100); // pos 변수에 위치를 받아 놓습니다.
bufTemp.append<uint>(1000);
bufTemp.append<string>("Test String");	// 문자열도 가능

.................

// - 덥어쓰기! 이렇게만 하면 해당 위치에 덥어써져 -100값이 100으로 바뀝니다.
temp_pos = 100;

이것을 이용해서 메시지 길이를 나중에 써넣을 수 있습니다.


지원 가능

  • C+20이상
  • C# 모든 버전 지원
  • unreal3D(c++) 지원
  • unity 3D(c#) 지원

시작하기

https://github.com/CGLabs/CGDK.buffer/blob/master/C%2B%2B/document/Getting_start_CGDK.buffer.pptx

[email protected] [email protected]

About

Buffer system for message serialization

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors