47#include <shared_mutex>
49#include <unordered_map>
54#if __has_include(<flatbuffers/idl.h>)
55#include <flatbuffers/flatbuffers.h>
56#include <flatbuffers/idl.h>
57#define VLINK_HAS_SCHEMA_PLUGIN_FLATBUFFERS
60#ifdef VLINK_HAS_SCHEMA_PLUGIN_FLATBUFFERS
73class FlatbuffersRegistry final {
82 template <
typename BinarySchema>
83 static bool register_schema(
const std::string& name);
93 static bool register_schema(
const std::string& name,
const uint8_t* bfbs_data,
size_t bfbs_size);
101 [[nodiscard]] SchemaData search_schema(
const std::string& name);
108 [[nodiscard]] std::vector<SchemaData> get_all_schemas();
111 FlatbuffersRegistry() =
default;
113 ~FlatbuffersRegistry() =
default;
115 static SchemaData build_data(
const std::string& name,
const uint8_t* bfbs_data,
size_t bfbs_size);
117 std::unordered_map<std::string, SchemaData> map_;
118 std::shared_mutex mtx_;
127template <
typename BinarySchema>
128inline bool FlatbuffersRegistry::register_schema(
const std::string& name) {
129 return register_schema(name, BinarySchema::data(), BinarySchema::size());
132inline bool FlatbuffersRegistry::register_schema(
const std::string& name,
const uint8_t* bfbs_data,
size_t bfbs_size) {
133 auto schema = build_data(name, bfbs_data, bfbs_size);
135 if VUNLIKELY (schema.encoding !=
"flatbuffers" || schema.data.empty()) {
139 auto& registry =
get();
141 std::lock_guard lock(registry.mtx_);
142 registry.map_[schema.name] = std::move(schema);
147inline SchemaData FlatbuffersRegistry::search_schema(
const std::string& name) {
148 std::shared_lock lock(mtx_);
150 auto iter = map_.find(name);
152 if (iter == map_.end()) {
159inline std::vector<SchemaData> FlatbuffersRegistry::get_all_schemas() {
160 std::shared_lock lock(mtx_);
162 std::vector<SchemaData> schemas;
163 schemas.reserve(map_.size());
165 for (
const auto& [name, schema] : map_) {
167 schemas.emplace_back(schema);
173inline SchemaData FlatbuffersRegistry::build_data(
const std::string& name,
const uint8_t* bfbs_data,
size_t bfbs_size) {
177 if VUNLIKELY (name.empty() || bfbs_data ==
nullptr || bfbs_size == 0) {
182 schema.encoding =
"flatbuffers";
186 flatbuffers::Verifier verifier(schema.data.data(), schema.data.size());
188 if VUNLIKELY (!reflection::VerifySchemaBuffer(verifier)) {
189 schema.encoding.clear();
209#define VLINK_REGISTER_FLATBUFFERS_NOW(schema_name, binary_schema_type) \
210 ::vlink::FlatbuffersRegistry::register_schema<binary_schema_type>(schema_name)
230#define VLINK_REGISTER_FLATBUFFERS(schema_name, binary_schema_type) \
234 struct VlinkAutoRegisterFlatbuffersHelper; \
237 struct VlinkAutoRegisterFlatbuffersHelper<__COUNTER__> { \
240 using SchemaType = binary_schema_type; \
241 (void)VLINK_REGISTER_FLATBUFFERS_NOW(schema_name, SchemaType); \
245 [[maybe_unused]] inline static const Init instance{}; \
static void init_memory_pool() noexcept
Initialises the global thread-safe memory pool for Bytes allocations.
static Bytes shallow_copy(uint8_t *data, size_t size) noexcept
Creates a non-owning Bytes alias pointing to an external mutable buffer.
#define VUNLIKELY(...)
Shorthand alias for VLINK_UNLIKELY. Hints that the expression is unlikely true.
Definition macros.h:302
#define VLINK_SINGLETON_DECLARE(classname)
Declares a complete Meyer's-singleton get() method with safety guards.
Definition macros.h:244
constexpr std::string_view get() noexcept
Returns the unqualified compile-time name of type T as a std::string_view.
Definition name_detector.h:146
@ kUnknown
Decode category is not known.
Definition types.h:185
@ kFlatbuffers
Decode using the FlatBuffers stack.
Definition types.h:189
Carries one serialized schema blob for runtime registration or embedding.
Definition types.h:246
Core type definitions shared across all VLink node implementations.