• FlatBuffers 转换数据字节为JSON字符串的格式。


    flatbuffers::Parser::Parse 函数

    parser->opts.strict_json = true;  置为JSON格式

    头文件:

    1. #pragma once
    2. #include "prerequisites.h"
    3. #include "msg_define_generated.h"
    4. #include "LoggerManager.h"
    5. class MessageDefine final : private boost::noncopyable
    6. {
    7. public:
    8. MessageDefine() = default;
    9. ~MessageDefine() = default;
    10. static MessageDefine* instance();
    11. void initialize();
    12. std::shared_ptr findSchema(const std::string& name);
    13. std::shared_ptr findRequestSchema(MSG_DEFINE id);
    14. std::shared_ptr findReplySchema(MSG_DEFINE id);
    15. template<typename T>
    16. inline const T* parseRequestMessage(MSG_DEFINE id, std::string& message, size_t offset)
    17. {
    18. if (message.size() <= offset)
    19. {
    20. LOG_WARNING(default, "Schema size < offset, id[{}]", EnumNameMSG_DEFINE(id));
    21. return nullptr;
    22. }
    23. auto parser = MessageDefine::instance()->findRequestSchema(id);
    24. if (!parser)
    25. {
    26. LOG_WARNING(default, "Schema not find, id[{}]", EnumNameMSG_DEFINE(id));
    27. return nullptr;
    28. }
    29. if (!parser->Parse(message.c_str() + offset, nullptr))
    30. {
    31. LOG_WARNING(default, "Schema parse failed:{}, id[{}], error:{}", message, EnumNameMSG_DEFINE(id), parser->error_);
    32. return nullptr;
    33. }
    34. flatbuffers::Verifier verifier(parser->builder_.GetBufferPointer(), parser->builder_.GetSize());
    35. if (verifier.VerifyBuffer(nullptr))
    36. {
    37. message.resize(parser->builder_.GetSize() + offset);
    38. memcpy((char*)(message.c_str() + offset), parser->builder_.GetBufferPointer(), parser->builder_.GetSize());
    39. return flatbuffers::GetRoot(message.c_str() + offset);
    40. }
    41. return nullptr;
    42. }
    43. template<typename T>
    44. inline const T* parseReplyMessage(MSG_DEFINE id, std::string& message, size_t offset)
    45. {
    46. if (message.size() <= offset)
    47. {
    48. LOG_WARNING(default, "Schema size < offset, id[{}]", EnumNameMSG_DEFINE(id));
    49. return nullptr;
    50. }
    51. auto parser = MessageDefine::instance()->findReplySchema(id);
    52. if (!parser)
    53. {
    54. LOG_WARNING(default, "Schema not find, id[{}]", EnumNameMSG_DEFINE(id));
    55. return nullptr;
    56. }
    57. if (!parser->Parse(message.c_str() + offset, nullptr))
    58. {
    59. LOG_WARNING(default, "Schema parse failed:{}, id[{}]", message, EnumNameMSG_DEFINE(id));
    60. return nullptr;
    61. }
    62. flatbuffers::Verifier verifier(parser->builder_.GetBufferPointer(), parser->builder_.GetSize());
    63. if (verifier.VerifyBuffer(nullptr))
    64. {
    65. message.resize(parser->builder_.GetSize() + offset);
    66. memcpy((char*)(message.c_str() + offset), parser->builder_.GetBufferPointer(), parser->builder_.GetSize());
    67. return flatbuffers::GetRoot(message.c_str() + offset);
    68. }
    69. return nullptr;
    70. }
    71. protected:
    72. bool loadSchemaFile(std::string_view path, const std::string& filename, bool bStrict);
    73. protected:
    74. std::unordered_map> m_parsers;
    75. std::unordered_map m_requestIdNames;
    76. std::unordered_map m_replyIdNames;
    77. };
    78. template<typename T>
    79. inline const T* json2fb(const std::string& name, const char* message, std::string_view* outMessage)
    80. {
    81. auto parser = MessageDefine::instance()->findSchema(name);
    82. if (!parser)
    83. {
    84. LOG_WARNING(default, "Schema:{} not find", name);
    85. return nullptr;
    86. }
    87. if (!parser->Parse(message, nullptr))
    88. {
    89. LOG_WARNING(default, "Schema:{} parse failed:{}", name, message);
    90. return nullptr;
    91. }
    92. flatbuffers::Verifier verifier(parser->builder_.GetBufferPointer(), parser->builder_.GetSize());
    93. if (verifier.VerifyBuffer(nullptr))
    94. {
    95. if (outMessage)
    96. *outMessage = std::string_view(reinterpret_cast<char*>(parser->builder_.GetBufferPointer()), parser->builder_.GetSize());
    97. return flatbuffers::GetRoot(parser->builder_.GetBufferPointer());
    98. }
    99. return nullptr;
    100. }
    101. inline bool bin2json(const std::string& name, const void* message, std::string& jsongen)
    102. {
    103. auto parser = MessageDefine::instance()->findSchema(name);
    104. if (!parser)
    105. {
    106. LOG_WARNING(default, "Schema:{} not find", name);
    107. return false;
    108. }
    109. if (!GenerateText(*parser, message, &jsongen))
    110. {
    111. LOG_WARNING(default, "Schema:{} Couldn't serialize parsed data to JSON", name);
    112. return false;
    113. }
    114. return true;
    115. }

    源文件:

    1. #include "MessageDefine.h"
    2. #include "ConfigLoader.h"
    3. #include "MessageDefineConfig_generated.h"
    4. MessageDefine* MessageDefine::instance()
    5. {
    6. thread_local std::unique_ptr tl_instance;
    7. if (!tl_instance)
    8. {
    9. tl_instance = std::make_unique();
    10. tl_instance->initialize();
    11. }
    12. return tl_instance.get();
    13. }
    14. void MessageDefine::initialize()
    15. {
    16. TConfigLoader cfgMessageDefine;
    17. if (!cfgMessageDefine.parse("common/MessageDefineConfig.fbs", "config/MessageDefineConfig.json"))
    18. {
    19. return;
    20. }
    21. auto cfg = cfgMessageDefine.data;
    22. for (auto item : *cfg->items())
    23. {
    24. auto path = item->path()->string_view();
    25. if (item->names())
    26. {
    27. for (auto name : *item->names())
    28. {
    29. loadSchemaFile(path, name->str(), true);
    30. }
    31. }
    32. if (item->no_strict_names())
    33. {
    34. for (auto name : *item->no_strict_names())
    35. {
    36. loadSchemaFile(path, name->str(), false);
    37. }
    38. }
    39. }
    40. for (auto item : *cfg->request_id_names())
    41. {
    42. m_requestIdNames[item->id()] = item->name()->str();
    43. }
    44. for (auto item : *cfg->reply_id_names())
    45. {
    46. m_replyIdNames[item->id()] = item->name()->str();
    47. }
    48. }
    49. bool MessageDefine::loadSchemaFile(std::string_view path, const std::string& filename, bool bStrict)
    50. {
    51. if (m_parsers.find(filename) != m_parsers.end())
    52. return true;
    53. // load FlatBuffer schema (.fbs)
    54. std::string schemafile;
    55. std::string schemafilename = fmt::format(path, filename);
    56. bool ok = flatbuffers::LoadFile(schemafilename.c_str(), false, &schemafile);
    57. if (!ok)
    58. {
    59. LOG_ERROR(network, "couldn't load schemafilename:{}", filename);
    60. return false;
    61. }
    62. // parse schema first, so we can use it to parse the data after
    63. auto parser = std::make_shared();
    64. const char* include_directories[] = { "../../fbs", nullptr };
    65. ok = parser->Parse(schemafile.c_str(), include_directories);
    66. if (!ok)
    67. {
    68. LOG_ERROR(network, "parse schemafilename:{} failed: {}", filename, parser->error_);
    69. return false;
    70. }
    71. if (bStrict)
    72. {
    73. parser->opts.strict_json = true;
    74. }
    75. m_parsers.emplace(filename, parser);
    76. return true;
    77. }
    78. std::shared_ptr MessageDefine::findSchema(const std::string& name)
    79. {
    80. if (auto it = m_parsers.find(name); it != m_parsers.end())
    81. {
    82. it->second->builder_.Clear();
    83. return it->second;
    84. }
    85. return nullptr;
    86. }
    87. std::shared_ptr MessageDefine::findRequestSchema(MSG_DEFINE id)
    88. {
    89. if (auto it = m_requestIdNames.find(id); it != m_requestIdNames.end())
    90. {
    91. return findSchema(it->second);
    92. }
    93. return nullptr;
    94. }
    95. std::shared_ptr MessageDefine::findReplySchema(MSG_DEFINE id)
    96. {
    97. if (auto it = m_replyIdNames.find(id); it != m_replyIdNames.end())
    98. {
    99. return findSchema(it->second);
    100. }
    101. return nullptr;
    102. }

  • 相关阅读:
    美团秋招笔试——算法岗
    Linux基础指令
    C语言-指针的进阶
    PCL Super4PCS算法实现点云粗配准(版本一)
    kubeadm搭建kubernetes(k8s)
    创建comfyui自定义节点
    实战:如何编写一个 OpenTelemetry Extensions
    C进阶习题
    面试突击32:为什么创建线程池一定要用ThreadPoolExecutor?
    Linux权限管理(umask、粘滞位)
  • 原文地址:https://blog.csdn.net/liulilittle/article/details/133983004