flatbuffers01

flatbuffers¸¦ ÀÌ¿ëÇØ ¸Þ¸ð¸® Àб⠾²±â¸¦ ±¸Çö Çغ»´Ù.
FlatBuffers(Ç÷§¹öÆÛ)´Â ±¸±Û¿¡¼­ °³¹ßµÈ Å©·Î½º Ç÷¿Æû Á÷·ÄÈ­(Serialization) ¶óÀ̺귯¸®ÀÌ´Ù.

flatbuffersÀÇ ÀåÁ¡¿¡ ´ëÇؼ­ ¾Ë¾Æº¸ÀÚ.
  • Å©·¡½ºÇ÷§Æû, ¾ð¾î¿¡ »ó°ü¾øÀÌ »ç¿ë ÇÒ¼ö ÀÖ´Ù.
  • ¸Þ¸ð¸®, ÆÄÀϷεùÀÌ ºü¸£´Ù.
  • »ç¿ëÀÌ ÆíÇÏ´Ù.

´Ù¿î·Îµå

ÃֽŹöÀü : https://github.com/google/flatbuffers
À©µµ¿ì ¹öÀüÀÇ ¼Ò½º¿Í ¹ÙÀ̳ʸ® ÆÄÀÏ https://github.com/google/flatbuffers/releases

FlatBuffer Schema ÀÛ¼º

fbs ÆÄÀÏÀ» ÀÛ¼ºÇؼ­ flatc.exe·Î ºôµåÇÑ´Ù.
flatc.exe ÆÄÀÏÀº ¹ÙÀ̳ʸ® ÆÄÀÏ¿¡ ÀÖ´Ù.

player.fbs
table Player
{
    name : string;
    level : int;
}

root_type Player;

ºôµå Çϸé personList_generated.h ÆÄÀÏÀÌ ¸¸µé¾îÁø´Ù.
flatc.exe -c player.fbs

ÆÄÀÏ º¹»ç

- »ý¼ºµÈ player_generated.h ÆÄÀÏÀ» º¹»çÇÑ´Ù.
- flatbuffers-2.0.0/include/flatbuffers Æú´õ¸¦ ÇÁ·ÎÁ§Æ®¿¡ º¹»çÇÑ´Ù.

¸Þ¸ð¸®¿¡¼­ ¾²°í Àбâ

ºô´õ °´Ã¼ ¼±¾ðÀ» ÇÏ°í Finish ÇÔ¼ö·Î ¸Þ¸ð¸®¿¡ ¾²±â¸¦ ÇÒ¼ö ÀÖ´Ù.
GetBufferPointer·Î ¹öÆÛ¸¦ °¡Á®¿Â´Ù.

¹öÆÛ¿¡¼­ °ªÀ» ¾ò¾î ¿Ã·Á¸é ´ÙÀ½°ú °°ÀÌ ÇÑ´Ù.

Get+ "Å×À̺í À̸§"  = GetPlayer(data)

player_generated.h ÆÄÀÏ¿¡ GetPlayer°¡ ¸¸µé¾îÁ® ÀÖ´Ù.

#include <iostream>
#include "flatbuffers/flatbuffers.h"
#include "player_generated.h"

void Sample1()
{
    //flatbuffer ºô´õ °´Ã¼ ¼±¾ð
    flatbuffers::FlatBufferBuilder builder;

    //Á÷·ÄÈ­ serialize
    auto name = builder.CreateString("ÃÖ°­°Ë");
    auto level = 50;
    builder.Finish(CreatePlayer(builder, name, level));

    //¹öÆÛ ÀúÀå
    auto data = builder.GetBufferPointer();

    //¿ªÁ÷·ÄÈ­ deserialize
    auto player = GetPlayer(data);
    std::cout << "À̸§ : " << player->name()->c_str() << std::endl;
    std::cout << "·¹º§ : " << player->level() << std::endl;
}

ÆÄÀÏ ¾²±â

ÆÄÀÏ·Î ÀúÀåÇϱâ À§Çؼ­´Â flatbuffers-2.0.0\src Æú´õ¿¡¼­ util.cpp ÆÄÀÏÀ» º¹»çÇؼ­ ÇÁ·ÎÁ§Æ®¿¡ Ãß°¡ÇÑ´Ù.
±×¸®°í util.h ÆÄÀÏÀ» Æ÷ÇÔ ½ÃŲ´Ù.
SaveFile ÇÔ¼ö·Î ÆÄÀÏ ¾²±â¸¦ ÇÑ´Ù.

flatbuffers::SaveFile("player.bin", reinterpret_cast<char*>(data), builder.GetSize(), true);

#include <iostream>
#include "flatbuffers/flatbuffers.h"
#include "player_generated.h"
#include "flatbuffers/util.h"   //flatbuffers::SaveFile »ç¿ëÀ» À§ÇØ

void Sample2()
{
    //flatbuffer ºô´õ °´Ã¼ ¼±¾ð
    flatbuffers::FlatBufferBuilder builder;

    //Á÷·ÄÈ­
    auto name = builder.CreateString("ÃÖ°­°Ë");
    auto level = 50;
    builder.Finish(CreatePlayer(builder, name, level));

    //¹öÆÛ ÀúÀå
    auto data = builder.GetBufferPointer();

    //ÆÄÀÏ ÀúÀå
    flatbuffers::SaveFile("player.bin", reinterpret_cast<char*>(data), builder.GetSize(), true);
}

ÆÄÀÏ Àбâ

flatbuffers::LoadFile ÇÔ¼ö·Î ÆÄÀÏÀ» Àд´Ù.
PushBytes¿¡ ·ÎµùÇÑ ÆÄÀÏÀÇ ¹öÆÛ¸¦ Ãß°¡ÇÑ´Ù.
GetPlayer¿¡¼­ GetCurrentBufferPointerÀÇ ¹öÆÛ¸¦ ÀÌ¿ëÇؼ­ °ªÀ» ÀÐ¾î ¿Â´Ù.

¿¹¿Ü󸮸¦ Ãß°¡ÇÏ°í ½Í´Ù¸é verify ºÎºÐÀÇ ÁÖ¼®À» ÇØÁ¦ÇÑ´Ù.

bool VerifyLayer_FbBuffer(flatbuffers::Verifier &verifier)
{
    return verifier.VerifyBuffer<Player>(nullptr);
}

void Sample3()
{
    std::string binaryfile;
    bool ok = flatbuffers::LoadFile("player.bin", false, &binaryfile);
    if (!ok)
    {
        return;
    }

    flatbuffers::FlatBufferBuilder builder;
    builder.PushBytes(reinterpret_cast<unsigned char*>(const_cast<char*>(binaryfile.c_str())), binaryfile.size());
    std::cout << "deserialize size:" << builder.GetSize() << std::endl;

    // verify
    /*
    flatbuffers::Verifier layer_verify(builder.GetCurrentBufferPointer(), builder.GetSize());
    bool verify_flag = VerifyLayer_FbBuffer(layer_verify);
    if (!verify_flag)
    {
        return;
    }
    */

    // read
    auto player = GetPlayer(builder.GetCurrentBufferPointer());

    std::cout << "À̸§ : " << player->name()->c_str() << std::endl;
    std::cout << "·¹º§ : " << player->level() << std::endl;
}

¹è¿­ »ç¿ë¹ý

¹è¿­ ¿¹Á¦¸¦ ¸¸µé±â À§ÇØ ½ºÅ°¸¶ personList.fbs ÆÄÀÏÀ» ÀÛ¼ºÇÑ´Ù.

personList.fbs ÆÄÀÏ
table Person
{
    name : string;
    age : int;
}

table PersonTable
{
    person_list : [Person];
}

root_type PersonTable;

´ÙÀ½°ú °°ÀÌ ºôµåÇÑ´Ù.
flatc.exe -c personList.fbs

root_typeÀÌ PersonTableÀ̹ǷΠCreatePersonTable·Î ·çÆ® ¿ÀÇÁ¼ÂÀ» ¸¸µç´Ù.
builder.Finish¿¡ ·çÆ® ¿ÀÇÁ¼ÂÀ» ³Ñ°Ü¼­ ¸Þ¸ð¸®¿¡ ¾´´Ù.

¿ªÁ÷·ÄÈ­´Â ¹è¿­ À妽º¸¦ »ç¿ëÇÏ´Â ¹æ¹ý°ú ¹Ýº¹ÀÚ¸¦ »ç¿ëÇÏ´Â ¹æ¹ýÀÌ ÀÖ´Ù.
·çÆ® À̸§ÀÌ PersonTableÀ̱⠶§¹®¿¡ GetPersonTable¿¡ GetCurrentBufferPointerÀÇ Æ÷ÀÎÅ͸¦ ³Ñ°ÜÁØ´Ù.

void Sample4()
{
    flatbuffers::FlatBufferBuilder builder;

    //Á÷·ÄÈ­
    auto p1 = CreatePerson(builder, builder.CreateString("È«±æµ¿"), 20);
    auto p2 = CreatePerson(builder, builder.CreateString("±èö¼ö"), 10);
    auto p3 = CreatePerson(builder, builder.CreateString("ÀÌ¿µÈñ"), 10);

    std::vector<flatbuffers::Offset<Person>> personList;
    personList.push_back(p1);
    personList.push_back(p2);
    personList.push_back(p3);

    auto persons = builder.CreateVector(personList);
    auto root = CreatePersonTable(builder, persons);
    builder.Finish(root);

    //¹öÆÛ ÀúÀå
    char buffer[1024] = { 0 };
    memcpy(buffer, builder.GetBufferPointer(), builder.GetSize());

    //¿ªÁ÷·ÄÈ­
    flatbuffers::FlatBufferBuilder builderOut;
    builderOut.PushBytes((const uint8_t*)buffer, 1024);
    auto table = GetPersonTable(builderOut.GetCurrentBufferPointer());

#if 0
    for (int i = 0; i < (int)table->person_list()->Length(); ++i)
    {
        std::string name = table->person_list()->Get(i)->name()->str();
        int age = table->person_list()->Get(i)->age();
        std::cout << "Person " << i << "  : " << name << " :  " << age << std::endl;
    }
#else
    auto players = table->person_list();
    for (auto iter = players->begin(); iter != players->end(); ++iter)
    {
        std::string name = iter->name()->str();
        int age = iter->age();
        std::cout << "Person " << "  : " << name << " :  " << age << std::endl;
    }
#endif
}

½ÇÇà °á°ú

---------------------------- Sample1 : memory read write ----------------------------
À̸§ : ÃÖ°­°Ë
·¹º§ : 50
---------------------------- Sample2 : save file ----------------------------
save player.bin.
---------------------------- Sample3 : load file ----------------------------
deserialize size:36
À̸§ : ÃÖ°­°Ë
·¹º§ : 50
---------------------------- Sample4 : flatbuffer array  ----------------------------
Person   : È«±æµ¿ :  20
Person   : ±èö¼ö :  10
Person   : ÀÌ¿µÈñ :  10

´Ù¿î·Îµå : flatbuffer_test.cpp

Âü°í)
flatbuffers ¸Þ¸ð¸® Àб⠾²±â
https://copynull.tistory.com/408

flatbuffers¿¡¼­ ¹è¿­ »ç¿ë
https://m.blog.naver.com/njh0602/220975255274
pengshengli ´Ô ½ÎÀÌÆ®

flatbuffers ÆÄÀÏ ¾²±â Àбâ
https://www.jianshu.com/p/db357e2eabc3

guotianqing ´Ô ½ÎÀÌÆ®·Î flatbuffers¿¡ ´ëÇØ ÀÚ¼¼ÇÑ ¼³¸íÀÌ ÀÖÀ½

flatbuffer jsonÀ» C °³Ã¼·Î º¯È¯