C++中将FlatBuffers序列化为JSON

​FlatBuffers是google发布的一个高效的序列化库,最近需要将系统中的flatbuffer的二进制数据转换为JSON以便其他系统使用,发现flatbuffer原生支持与JSON结构之间的转换。

方法一:使用GenerateText()函数

加载schema文件内容构造flatbuffers::Parser解析器,最后通过GenerateText()函数解析为JSON字符串。stackoverflow中有一段代码贴来,示例如下:

复制代码
bool MyFBSchemaWrapper::asJson(std::string& jsonOutput)
{
    //**This is the section I don't like having to do
    std::string schemaFile;
    if (flatbuffers::LoadFile((std::string(getenv("FBS_FILE_PATH")) + "MyFBSchema.fbs").c_str(), false, &schemaFile))
    {
        flatbuffers::Parser parser;
        const char *includePaths[] = { getenv("FBS_FILE_PATH");
        parser.Parse(schemaFile.c_str(), includePaths);
    //**End bad section
        parser.opts.strict_json = true;

        flatbuffers::FlatBufferBuilder fbBuilder;
        auto testItem1 = fbBuilder.CreateString("test1");
        auto testItem2 = fbBuilder.CreateString("test2");

        MyFBSchemaBuilder myBuilder(fbBuilder);

        myBuilder.add_item1(testItem1);
        myBuilder.add_item2(testItem2);
        FinishMyFBSchemaBuffer(fbBuilder, myBuilder.finish());

        auto result = GenerateText(parser, fbBuilder.GetBufferPointer(), &jsonOutput);
        return true;
    }
    return false;
}

其中:Parser和GenerateText都定义在在flatbuferrs/idl.h中,如下:

复制代码
  // Parse the string containing either schema or JSON data, which will
  // populate the SymbolTable's or the FlatBufferBuilder above.
  // include_paths is used to resolve any include statements, and typically
  // should at least include the project path (where you loaded source_ from).
  // include_paths must be nullptr terminated if specified.
  // If include_paths is nullptr, it will attempt to load from the current
  // directory.
  // If the source was loaded from a file and isn't an include file,
  // supply its name in source_filename.
  // All paths specified in this call must be in posix format, if you accept
  // paths from user input, please call PosixPath on them first.
  bool Parse(const char* _source, const char** include_paths = nullptr,
             const char* source_filename = nullptr);

// Generate text (JSON) from a given FlatBuffer, and a given Parser
// object that has been populated with the corresponding schema.
// If ident_step is 0, no indentation will be generated. Additionally,
// if it is less than 0, no linefeeds will be generated either.
// See idl_gen_text.cpp.
// strict_json adds "quotes" around field names if true.
// These functions return nullptr on success, or an error string,
// which may happen if the flatbuffer cannot be encoded in JSON (e.g.,
// it contains non-UTF-8 byte arrays in String values).
extern bool GenerateTextFromTable(const Parser& parser, const void* table,
                                  const std::string& tablename,
                                  std::string* text);
extern const char* GenerateText(const Parser& parser, const void* flatbuffer,
                                std::string* text);
extern const char* GenerateTextFile(const Parser& parser,
                                    const std::string& path,
                                    const std::string& file_name);

方法二:使用FlatBuffers中提供的mini reflection机制

这种方法要加上参数(--reflect-types)重新编译头文件,如:

复制代码
# 将原来的命令(flatc -o ./ -cpp *.fbs)加上--reflect-types
flatc -o ./ --reflect-types -cpp *.fbs

使用FlatBufferToString函数

FlatBufferToString()函数定义在flatbuferrs/minireflect.h中,如下:

复制代码
inline std::string FlatBufferToString(const uint8_t* buffer,
                                      const TypeTable* type_table,
                                      bool multi_line = false,
                                      bool vector_delimited = true,
                                      const std::string& indent = "",
                                      bool quotes = false) {
  ToStringVisitor tostring_visitor(multi_line ? "\n" : " ", quotes, indent,
                                   vector_delimited);
  IterateFlatBuffer(buffer, type_table, &tostring_visitor);
  return tostring_visitor.s;
}

REF.

  1. https://github.com/google/flatbuffers/tree/master
  2. https://stackoverflow.com/questions/60176212/serializing-a-flatbuffer-object-to-json-without-its-schema-file
  3. https://dbaileychess.github.io/flatbuffers/flatbuffers_guide_using_schema_compiler.html
  4. https://flatbuffers.dev/languages/cpp/#mini-reflection
相关推荐
趣知岛16 小时前
Java反射和设计模式
java·开发语言·设计模式·反射
Hello eveybody16 小时前
C++四级考试要点
开发语言·c++
夏幻灵16 小时前
obj 文件
c++
期待のcode16 小时前
Java中的this关键字
java·开发语言
异界蜉蝣16 小时前
Proxy vs Object.defineProperty:Vue3响应式原理的深度革命
开发语言·前端·javascript
谅望者16 小时前
数据分析笔记15:Python模块、包与异常处理
开发语言·人工智能·python
黎雁·泠崖16 小时前
C 语言联合体与枚举:共用内存 + 常量枚举 + 实战
c语言·开发语言·python
yousuotu16 小时前
基于Python实现亚马逊销售数据分析与预测
开发语言·python·数据分析
L Jiawen16 小时前
【Golang基础】基础知识(上)
开发语言·后端·golang