flatbuffers::Parser::Parse 函数
parser->opts.strict_json = true; 置为JSON格式。
头文件:
- #pragma once
-
- #include "prerequisites.h"
- #include "msg_define_generated.h"
- #include "LoggerManager.h"
-
- class MessageDefine final : private boost::noncopyable
- {
- public:
- MessageDefine() = default;
-
- ~MessageDefine() = default;
-
- static MessageDefine* instance();
-
- void initialize();
-
- std::shared_ptr
findSchema(const std::string& name) ; - std::shared_ptr
findRequestSchema(MSG_DEFINE id) ; - std::shared_ptr
findReplySchema(MSG_DEFINE id) ; -
- template<typename T>
- inline const T* parseRequestMessage(MSG_DEFINE id, std::string& message, size_t offset)
- {
- if (message.size() <= offset)
- {
- LOG_WARNING(default, "Schema size < offset, id[{}]", EnumNameMSG_DEFINE(id));
- return nullptr;
- }
-
- auto parser = MessageDefine::instance()->findRequestSchema(id);
- if (!parser)
- {
- LOG_WARNING(default, "Schema not find, id[{}]", EnumNameMSG_DEFINE(id));
- return nullptr;
- }
-
- if (!parser->Parse(message.c_str() + offset, nullptr))
- {
- LOG_WARNING(default, "Schema parse failed:{}, id[{}], error:{}", message, EnumNameMSG_DEFINE(id), parser->error_);
- return nullptr;
- }
-
- flatbuffers::Verifier verifier(parser->builder_.GetBufferPointer(), parser->builder_.GetSize());
- if (verifier.VerifyBuffer
(nullptr)) - {
- message.resize(parser->builder_.GetSize() + offset);
- memcpy((char*)(message.c_str() + offset), parser->builder_.GetBufferPointer(), parser->builder_.GetSize());
- return flatbuffers::GetRoot
(message.c_str() + offset); - }
- return nullptr;
- }
-
- template<typename T>
- inline const T* parseReplyMessage(MSG_DEFINE id, std::string& message, size_t offset)
- {
- if (message.size() <= offset)
- {
- LOG_WARNING(default, "Schema size < offset, id[{}]", EnumNameMSG_DEFINE(id));
- return nullptr;
- }
-
- auto parser = MessageDefine::instance()->findReplySchema(id);
- if (!parser)
- {
- LOG_WARNING(default, "Schema not find, id[{}]", EnumNameMSG_DEFINE(id));
- return nullptr;
- }
-
- if (!parser->Parse(message.c_str() + offset, nullptr))
- {
- LOG_WARNING(default, "Schema parse failed:{}, id[{}]", message, EnumNameMSG_DEFINE(id));
- return nullptr;
- }
-
- flatbuffers::Verifier verifier(parser->builder_.GetBufferPointer(), parser->builder_.GetSize());
- if (verifier.VerifyBuffer
(nullptr)) - {
- message.resize(parser->builder_.GetSize() + offset);
- memcpy((char*)(message.c_str() + offset), parser->builder_.GetBufferPointer(), parser->builder_.GetSize());
- return flatbuffers::GetRoot
(message.c_str() + offset); - }
- return nullptr;
- }
- protected:
- bool loadSchemaFile(std::string_view path, const std::string& filename, bool bStrict);
-
- protected:
- std::unordered_map
> m_parsers; - std::unordered_map
m_requestIdNames; - std::unordered_map
m_replyIdNames; - };
-
-
- template<typename T>
- inline const T* json2fb(const std::string& name, const char* message, std::string_view* outMessage)
- {
- auto parser = MessageDefine::instance()->findSchema(name);
- if (!parser)
- {
- LOG_WARNING(default, "Schema:{} not find", name);
- return nullptr;
- }
-
- if (!parser->Parse(message, nullptr))
- {
- LOG_WARNING(default, "Schema:{} parse failed:{}", name, message);
- return nullptr;
- }
-
- flatbuffers::Verifier verifier(parser->builder_.GetBufferPointer(), parser->builder_.GetSize());
- if (verifier.VerifyBuffer
(nullptr)) - {
- if (outMessage)
- *outMessage = std::string_view(reinterpret_cast<char*>(parser->builder_.GetBufferPointer()), parser->builder_.GetSize());
- return flatbuffers::GetRoot
(parser->builder_.GetBufferPointer()); - }
- return nullptr;
- }
-
- inline bool bin2json(const std::string& name, const void* message, std::string& jsongen)
- {
- auto parser = MessageDefine::instance()->findSchema(name);
- if (!parser)
- {
- LOG_WARNING(default, "Schema:{} not find", name);
- return false;
- }
-
- if (!GenerateText(*parser, message, &jsongen))
- {
- LOG_WARNING(default, "Schema:{} Couldn't serialize parsed data to JSON", name);
- return false;
- }
- return true;
- }
源文件:
- #include "MessageDefine.h"
- #include "ConfigLoader.h"
- #include "MessageDefineConfig_generated.h"
-
- MessageDefine* MessageDefine::instance()
- {
- thread_local std::unique_ptr
tl_instance; - if (!tl_instance)
- {
- tl_instance = std::make_unique
(); - tl_instance->initialize();
- }
- return tl_instance.get();
- }
-
- void MessageDefine::initialize()
- {
- TConfigLoader
cfgMessageDefine; - if (!cfgMessageDefine.parse("common/MessageDefineConfig.fbs", "config/MessageDefineConfig.json"))
- {
- return;
- }
-
- auto cfg = cfgMessageDefine.data;
- for (auto item : *cfg->items())
- {
- auto path = item->path()->string_view();
- if (item->names())
- {
- for (auto name : *item->names())
- {
- loadSchemaFile(path, name->str(), true);
- }
- }
- if (item->no_strict_names())
- {
- for (auto name : *item->no_strict_names())
- {
- loadSchemaFile(path, name->str(), false);
- }
- }
- }
- for (auto item : *cfg->request_id_names())
- {
- m_requestIdNames[item->id()] = item->name()->str();
- }
- for (auto item : *cfg->reply_id_names())
- {
- m_replyIdNames[item->id()] = item->name()->str();
- }
- }
-
- bool MessageDefine::loadSchemaFile(std::string_view path, const std::string& filename, bool bStrict)
- {
- if (m_parsers.find(filename) != m_parsers.end())
- return true;
-
- // load FlatBuffer schema (.fbs)
- std::string schemafile;
- std::string schemafilename = fmt::format(path, filename);
- bool ok = flatbuffers::LoadFile(schemafilename.c_str(), false, &schemafile);
- if (!ok)
- {
- LOG_ERROR(network, "couldn't load schemafilename:{}", filename);
- return false;
- }
-
- // parse schema first, so we can use it to parse the data after
- auto parser = std::make_shared
(); - const char* include_directories[] = { "../../fbs", nullptr };
- ok = parser->Parse(schemafile.c_str(), include_directories);
- if (!ok)
- {
- LOG_ERROR(network, "parse schemafilename:{} failed: {}", filename, parser->error_);
- return false;
- }
-
- if (bStrict)
- {
- parser->opts.strict_json = true;
- }
-
- m_parsers.emplace(filename, parser);
- return true;
- }
-
- std::shared_ptr
MessageDefine::findSchema(const std::string& name) - {
- if (auto it = m_parsers.find(name); it != m_parsers.end())
- {
- it->second->builder_.Clear();
- return it->second;
- }
- return nullptr;
- }
-
- std::shared_ptr
MessageDefine::findRequestSchema(MSG_DEFINE id) - {
- if (auto it = m_requestIdNames.find(id); it != m_requestIdNames.end())
- {
- return findSchema(it->second);
- }
- return nullptr;
- }
-
- std::shared_ptr
MessageDefine::findReplySchema(MSG_DEFINE id) - {
- if (auto it = m_replyIdNames.find(id); it != m_replyIdNames.end())
- {
- return findSchema(it->second);
- }
- return nullptr;
- }