77 #include <shared_mutex>
79 #include <unordered_map>
82 #include "../impl/types.h"
84 #if __has_include(<flatbuffers/idl.h>)
85 #include <flatbuffers/flatbuffers.h>
86 #include <flatbuffers/idl.h>
87 #define VLINK_HAS_SCHEMA_PLUGIN_FLATBUFFERS
90 #ifdef VLINK_HAS_SCHEMA_PLUGIN_FLATBUFFERS
104 class FlatbuffersRegistry final {
113 template <
typename BinarySchema>
114 static bool register_schema(
const std::string& name);
124 static bool register_schema(
const std::string& name,
const uint8_t* bfbs_data,
size_t bfbs_size);
132 [[nodiscard]] SchemaData search_schema(
const std::string& name);
139 [[nodiscard]] std::vector<SchemaData> get_all_schemas();
142 FlatbuffersRegistry() =
default;
144 ~FlatbuffersRegistry() =
default;
146 static SchemaData build_data(
const std::string& name,
const uint8_t* bfbs_data,
size_t bfbs_size);
148 std::unordered_map<std::string, SchemaData> map_;
149 std::shared_mutex mtx_;
158 template <
typename BinarySchema>
159 inline bool FlatbuffersRegistry::register_schema(
const std::string& name) {
160 return register_schema(name, BinarySchema::data(), BinarySchema::size());
163 inline bool FlatbuffersRegistry::register_schema(
const std::string& name,
const uint8_t* bfbs_data,
size_t bfbs_size) {
164 auto schema = build_data(name, bfbs_data, bfbs_size);
166 if VUNLIKELY (schema.encoding !=
"flatbuffers" || schema.data.empty()) {
170 auto& registry =
get();
172 std::lock_guard lock(registry.mtx_);
173 registry.map_[schema.name] = std::move(schema);
178 inline SchemaData FlatbuffersRegistry::search_schema(
const std::string& name) {
179 std::shared_lock lock(mtx_);
181 auto iter = map_.find(name);
183 if (iter == map_.end()) {
190 inline std::vector<SchemaData> FlatbuffersRegistry::get_all_schemas() {
191 std::shared_lock lock(mtx_);
193 std::vector<SchemaData> schemas;
194 schemas.reserve(map_.size());
196 for (
const auto& [name, schema] : map_) {
198 schemas.emplace_back(schema);
204 inline SchemaData FlatbuffersRegistry::build_data(
const std::string& name,
const uint8_t* bfbs_data,
size_t bfbs_size) {
208 if VUNLIKELY (name.empty() || bfbs_data ==
nullptr || bfbs_size == 0) {
213 schema.encoding =
"flatbuffers";
219 if VUNLIKELY (!reflection::VerifySchemaBuffer(verifier)) {
220 schema.encoding.clear();
239 #define VLINK_REGISTER_FLATBUFFERS_NOW(schema_name, binary_schema_type) \
240 ::vlink::FlatbuffersRegistry::register_schema<binary_schema_type>(schema_name)
259 #define VLINK_REGISTER_FLATBUFFERS(schema_name, binary_schema_type) \
263 struct VlinkAutoRegisterFlatbuffersHelper; \
266 struct VlinkAutoRegisterFlatbuffersHelper<__COUNTER__> { \
269 using SchemaType = binary_schema_type; \
270 (void)VLINK_REGISTER_FLATBUFFERS_NOW(schema_name, SchemaType); \
274 [[maybe_unused]] inline static const Init instance{}; \
static void init_memory_pool() noexcept
Eagerly constructs the process-wide MemoryPool that backs heap allocations.
static Bytes shallow_copy(uint8_t *data, size_t size) noexcept
Wraps an external mutable buffer as a non-owning alias.
#define VUNLIKELY(...)
Short alias for VLINK_UNLIKELY.
Definition: macros.h:289
#define VLINK_SINGLETON_DECLARE(classname)
Declares a Meyers singleton get and the matching uniqueness guards on classname.
Definition: macros.h:232
constexpr std::string_view get() noexcept
Returns the trimmed compile-time identifier for TypeT.
Definition: name_detector.h:603
@ kUnknown
Decoding family unknown.
@ kFlatbuffers
Decode through the FlatBuffers stack.
Definition: serializer-inl.h:142