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
相关推荐
智者知已应修善业2 小时前
【c语言蓝桥杯计算卡片题】2023-2-12
c语言·c++·经验分享·笔记·算法·蓝桥杯
hansang_IR2 小时前
【题解】洛谷 P2330 [SCOI2005] 繁忙的都市 [生成树]
c++·算法·最小生成树
一晌小贪欢2 小时前
【Python办公】处理 CSV和Excel 文件操作指南
开发语言·python·excel·excel操作·python办公·csv操作
清风与日月2 小时前
c# 集成激光雷达(以思岚A1为例)
开发语言·c#
是苏浙3 小时前
零基础入门C语言之贪吃蛇的实现
c语言·开发语言·数据结构
化作星辰3 小时前
java 给鉴权kafka2.7(sasl)发送消息权限异常处理
java·大数据·开发语言·kafka
无极小卒3 小时前
如何在三维空间中生成任意方向的矩形内部点位坐标
开发语言·算法·c#
FMRbpm3 小时前
链表中出现的问题
数据结构·c++·算法·链表·新手入门
克里斯蒂亚诺更新3 小时前
微信小程序 点击某个marker改变其大小
开发语言·前端·javascript