From a1291695cbf0f28bf866577374089e93b570a56d Mon Sep 17 00:00:00 2001 From: Davide Faconti Date: Mon, 20 May 2024 10:51:45 +0200 Subject: [PATCH] remove flatbuffers from public API and old file_logger --- .../flatbuffers/base.h | 129 +- .../flatbuffers/BT_logger_generated.h | 804 ---- .../behaviortree_cpp/flatbuffers/LICENSE.txt | 202 - .../flatbuffers/flatbuffers.h | 3518 ----------------- .../flatbuffers/stl_emulation.h | 673 ---- .../behaviortree_cpp/loggers/bt_file_logger.h | 37 - src/loggers/bt_file_logger.cpp | 67 - src/loggers/bt_file_logger_v2.cpp | 2 +- tools/CMakeLists.txt | 8 +- tools/bt_log_cat.cpp | 115 - 10 files changed, 99 insertions(+), 5456 deletions(-) rename {include/behaviortree_cpp => 3rdparty}/flatbuffers/base.h (76%) delete mode 100644 include/behaviortree_cpp/flatbuffers/BT_logger_generated.h delete mode 100644 include/behaviortree_cpp/flatbuffers/LICENSE.txt delete mode 100644 include/behaviortree_cpp/flatbuffers/flatbuffers.h delete mode 100644 include/behaviortree_cpp/flatbuffers/stl_emulation.h delete mode 100644 include/behaviortree_cpp/loggers/bt_file_logger.h delete mode 100644 src/loggers/bt_file_logger.cpp delete mode 100644 tools/bt_log_cat.cpp diff --git a/include/behaviortree_cpp/flatbuffers/base.h b/3rdparty/flatbuffers/base.h similarity index 76% rename from include/behaviortree_cpp/flatbuffers/base.h rename to 3rdparty/flatbuffers/base.h index 54a51aacb..1c19dde98 100644 --- a/include/behaviortree_cpp/flatbuffers/base.h +++ b/3rdparty/flatbuffers/base.h @@ -32,7 +32,7 @@ #include #include -#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H) +#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H) && defined(__AVR__) #include #else #include @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -50,10 +51,6 @@ #include #endif -#ifdef _STLPORT_VERSION - #define FLATBUFFERS_CPP98_STL -#endif - #ifdef __ANDROID__ #include #endif @@ -142,9 +139,9 @@ #endif #endif // !defined(FLATBUFFERS_LITTLEENDIAN) -#define FLATBUFFERS_VERSION_MAJOR 1 -#define FLATBUFFERS_VERSION_MINOR 12 -#define FLATBUFFERS_VERSION_REVISION 0 +#define FLATBUFFERS_VERSION_MAJOR 24 +#define FLATBUFFERS_VERSION_MINOR 3 +#define FLATBUFFERS_VERSION_REVISION 25 #define FLATBUFFERS_STRING_EXPAND(X) #X #define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X) namespace flatbuffers { @@ -158,7 +155,7 @@ namespace flatbuffers { #define FLATBUFFERS_FINAL_CLASS final #define FLATBUFFERS_OVERRIDE override #define FLATBUFFERS_EXPLICIT_CPP11 explicit - #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : flatbuffers::voffset_t + #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : ::flatbuffers::voffset_t #else #define FLATBUFFERS_FINAL_CLASS #define FLATBUFFERS_OVERRIDE @@ -237,16 +234,26 @@ namespace flatbuffers { } #define FLATBUFFERS_HAS_STRING_VIEW 1 // Check for absl::string_view - #elif __has_include("absl/strings/string_view.h") - #include "absl/strings/string_view.h" - namespace flatbuffers { - typedef absl::string_view string_view; - } - #define FLATBUFFERS_HAS_STRING_VIEW 1 + #elif __has_include("absl/strings/string_view.h") && \ + __has_include("absl/base/config.h") && \ + (__cplusplus >= 201411) + #include "absl/base/config.h" + #if !defined(ABSL_USES_STD_STRING_VIEW) + #include "absl/strings/string_view.h" + namespace flatbuffers { + typedef absl::string_view string_view; + } + #define FLATBUFFERS_HAS_STRING_VIEW 1 + #endif #endif #endif // __has_include #endif // !FLATBUFFERS_HAS_STRING_VIEW +#ifndef FLATBUFFERS_GENERAL_HEAP_ALLOC_OK + // Allow heap allocations to be used + #define FLATBUFFERS_GENERAL_HEAP_ALLOC_OK 1 +#endif // !FLATBUFFERS_GENERAL_HEAP_ALLOC_OK + #ifndef FLATBUFFERS_HAS_NEW_STRTOD // Modern (C++11) strtod and strtof functions are available for use. // 1) nan/inf strings as argument of strtod; @@ -259,9 +266,12 @@ namespace flatbuffers { #endif // !FLATBUFFERS_HAS_NEW_STRTOD #ifndef FLATBUFFERS_LOCALE_INDEPENDENT - // Enable locale independent functions {strtof_l, strtod_l,strtoll_l, strtoull_l}. - #if ((defined(_MSC_VER) && _MSC_VER >= 1800) || \ - (defined(_XOPEN_VERSION) && (_XOPEN_VERSION>=700)) && (!defined(__ANDROID_API__) || (defined(__ANDROID_API__) && (__ANDROID_API__>=21)))) + // Enable locale independent functions {strtof_l, strtod_l,strtoll_l, + // strtoull_l}. + #if (defined(_MSC_VER) && _MSC_VER >= 1800) || \ + (defined(__ANDROID_API__) && __ANDROID_API__>= 21) || \ + (defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 700)) && \ + (!defined(__Fuchsia__) && !defined(__ANDROID_API__)) #define FLATBUFFERS_LOCALE_INDEPENDENT 1 #else #define FLATBUFFERS_LOCALE_INDEPENDENT 0 @@ -269,27 +279,29 @@ namespace flatbuffers { #endif // !FLATBUFFERS_LOCALE_INDEPENDENT // Suppress Undefined Behavior Sanitizer (recoverable only). Usage: -// - __supress_ubsan__("undefined") -// - __supress_ubsan__("signed-integer-overflow") +// - FLATBUFFERS_SUPPRESS_UBSAN("undefined") +// - FLATBUFFERS_SUPPRESS_UBSAN("signed-integer-overflow") #if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7)) - #define __supress_ubsan__(type) __attribute__((no_sanitize(type))) + #define FLATBUFFERS_SUPPRESS_UBSAN(type) __attribute__((no_sanitize(type))) #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409) - #define __supress_ubsan__(type) __attribute__((no_sanitize_undefined)) + #define FLATBUFFERS_SUPPRESS_UBSAN(type) __attribute__((no_sanitize_undefined)) #else - #define __supress_ubsan__(type) + #define FLATBUFFERS_SUPPRESS_UBSAN(type) #endif -// This is constexpr function used for checking compile-time constants. -// Avoid `#pragma warning(disable: 4127) // C4127: expression is constant`. -template FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) { - return !!t; +namespace flatbuffers { + // This is constexpr function used for checking compile-time constants. + // Avoid `#pragma warning(disable: 4127) // C4127: expression is constant`. + template FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) { + return !!t; + } } // Enable C++ attribute [[]] if std:c++17 or higher. #if ((__cplusplus >= 201703L) \ || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L))) // All attributes unknown to an implementation are ignored without causing an error. - #define FLATBUFFERS_ATTRIBUTE(attr) [[attr]] + #define FLATBUFFERS_ATTRIBUTE(attr) attr #define FLATBUFFERS_FALLTHROUGH() [[fallthrough]] #else @@ -314,9 +326,11 @@ namespace flatbuffers { // Also, using a consistent offset type maintains compatibility of serialized // offset values between 32bit and 64bit systems. typedef uint32_t uoffset_t; +typedef uint64_t uoffset64_t; // Signed offsets for references that can go in both directions. typedef int32_t soffset_t; +typedef int64_t soffset64_t; // Offset/index used in v-tables, can be changed to uint8_t in // format forks to save a bit of space if desired. @@ -325,10 +339,23 @@ typedef uint16_t voffset_t; typedef uintmax_t largest_scalar_t; // In 32bits, this evaluates to 2GB - 1 -#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1) +#define FLATBUFFERS_MAX_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset_t>::max() +#define FLATBUFFERS_MAX_64_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset64_t>::max() + +// The minimum size buffer that can be a valid flatbuffer. +// Includes the offset to the root table (uoffset_t), the offset to the vtable +// of the root table (soffset_t), the size of the vtable (uint16_t), and the +// size of the referring table (uint16_t). +#define FLATBUFFERS_MIN_BUFFER_SIZE sizeof(uoffset_t) + sizeof(soffset_t) + \ + sizeof(uint16_t) + sizeof(uint16_t) // We support aligning the contents of buffers up to this size. -#define FLATBUFFERS_MAX_ALIGNMENT 16 +#ifndef FLATBUFFERS_MAX_ALIGNMENT + #define FLATBUFFERS_MAX_ALIGNMENT 32 +#endif + +/// @brief The length of a FlatBuffer file header. +static const size_t kFileIdentifierLength = 4; inline bool VerifyAlignmentRequirements(size_t align, size_t min_align = 1) { return (min_align <= align) && (align <= (FLATBUFFERS_MAX_ALIGNMENT)) && @@ -336,7 +363,6 @@ inline bool VerifyAlignmentRequirements(size_t align, size_t min_align = 1) { } #if defined(_MSC_VER) - #pragma warning(disable: 4351) // C4351: new behavior: elements of array ... will be default initialized #pragma warning(push) #pragma warning(disable: 4127) // C4127: conditional expression is constant #endif @@ -397,7 +423,7 @@ template T EndianScalar(T t) { template // UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. -__supress_ubsan__("alignment") +FLATBUFFERS_SUPPRESS_UBSAN("alignment") T ReadScalar(const void *p) { return EndianScalar(*reinterpret_cast(p)); } @@ -411,13 +437,13 @@ T ReadScalar(const void *p) { template // UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. -__supress_ubsan__("alignment") +FLATBUFFERS_SUPPRESS_UBSAN("alignment") void WriteScalar(void *p, T t) { *reinterpret_cast(p) = EndianScalar(t); } template struct Offset; -template __supress_ubsan__("alignment") void WriteScalar(void *p, Offset t) { +template FLATBUFFERS_SUPPRESS_UBSAN("alignment") void WriteScalar(void *p, Offset t) { *reinterpret_cast(p) = EndianScalar(t.o); } @@ -428,10 +454,43 @@ template __supress_ubsan__("alignment") void WriteScalar(void *p, Of // Computes how many bytes you'd have to pad to be able to write an // "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in // memory). -__supress_ubsan__("unsigned-integer-overflow") +FLATBUFFERS_SUPPRESS_UBSAN("unsigned-integer-overflow") inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) { return ((~buf_size) + 1) & (scalar_size - 1); } +// Generic 'operator==' with conditional specialisations. +// T e - new value of a scalar field. +// T def - default of scalar (is known at compile-time). +template inline bool IsTheSameAs(T e, T def) { return e == def; } + +#if defined(FLATBUFFERS_NAN_DEFAULTS) && \ + defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) +// Like `operator==(e, def)` with weak NaN if T=(float|double). +template inline bool IsFloatTheSameAs(T e, T def) { + return (e == def) || ((def != def) && (e != e)); +} +template<> inline bool IsTheSameAs(float e, float def) { + return IsFloatTheSameAs(e, def); +} +template<> inline bool IsTheSameAs(double e, double def) { + return IsFloatTheSameAs(e, def); +} +#endif + +// Check 'v' is out of closed range [low; high]. +// Workaround for GCC warning [-Werror=type-limits]: +// comparison is always true due to limited range of data type. +template +inline bool IsOutRange(const T &v, const T &low, const T &high) { + return (v < low) || (high < v); +} + +// Check 'v' is in closed range [low; high]. +template +inline bool IsInRange(const T &v, const T &low, const T &high) { + return !IsOutRange(v, low, high); +} + } // namespace flatbuffers #endif // FLATBUFFERS_BASE_H_ diff --git a/include/behaviortree_cpp/flatbuffers/BT_logger_generated.h b/include/behaviortree_cpp/flatbuffers/BT_logger_generated.h deleted file mode 100644 index 088c8900c..000000000 --- a/include/behaviortree_cpp/flatbuffers/BT_logger_generated.h +++ /dev/null @@ -1,804 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -#ifndef FLATBUFFERS_GENERATED_BTLOGGER_SERIALIZATION_H_ -#define FLATBUFFERS_GENERATED_BTLOGGER_SERIALIZATION_H_ - -#include "behaviortree_cpp/flatbuffers/flatbuffers.h" - -namespace Serialization -{ -struct PortModel; -struct PortModelBuilder; - -struct PortConfig; -struct PortConfigBuilder; - -struct TreeNode; -struct TreeNodeBuilder; - -struct NodeModel; -struct NodeModelBuilder; - -struct BehaviorTree; -struct BehaviorTreeBuilder; - -struct Timestamp; - -struct StatusChange; - -struct StatusChangeLog; -struct StatusChangeLogBuilder; - -enum class NodeStatus : int8_t -{ - IDLE = 0, - RUNNING = 1, - SUCCESS = 2, - FAILURE = 3, - MIN = IDLE, - MAX = FAILURE -}; - -inline const NodeStatus (&EnumValuesNodeStatus())[4] -{ - static const NodeStatus values[] = { NodeStatus::IDLE, NodeStatus::RUNNING, - NodeStatus::SUCCESS, NodeStatus::FAILURE }; - return values; -} - -inline const char* const* EnumNamesNodeStatus() -{ - static const char* const names[5] = { "IDLE", "RUNNING", "SUCCESS", "FAILURE", - nullptr }; - return names; -} - -inline const char* EnumNameNodeStatus(NodeStatus e) -{ - if(flatbuffers::IsOutRange(e, NodeStatus::IDLE, NodeStatus::FAILURE)) - return ""; - const size_t index = static_cast(e); - return EnumNamesNodeStatus()[index]; -} - -enum class NodeType : int8_t -{ - UNDEFINED = 0, - ACTION = 1, - CONDITION = 2, - CONTROL = 3, - DECORATOR = 4, - SUBTREE = 5, - MIN = UNDEFINED, - MAX = SUBTREE -}; - -inline const NodeType (&EnumValuesNodeType())[6] -{ - static const NodeType values[] = { NodeType::UNDEFINED, NodeType::ACTION, - NodeType::CONDITION, NodeType::CONTROL, - NodeType::DECORATOR, NodeType::SUBTREE }; - return values; -} - -inline const char* const* EnumNamesNodeType() -{ - static const char* const names[7] = { "UNDEFINED", "ACTION", "CONDITION", "CONTROL", - "DECORATOR", "SUBTREE", nullptr }; - return names; -} - -inline const char* EnumNameNodeType(NodeType e) -{ - if(flatbuffers::IsOutRange(e, NodeType::UNDEFINED, NodeType::SUBTREE)) - return ""; - const size_t index = static_cast(e); - return EnumNamesNodeType()[index]; -} - -enum class PortDirection : int8_t -{ - INPUT = 0, - OUTPUT = 1, - INOUT = 2, - MIN = INPUT, - MAX = INOUT -}; - -inline const PortDirection (&EnumValuesPortDirection())[3] -{ - static const PortDirection values[] = { PortDirection::INPUT, PortDirection::OUTPUT, - PortDirection::INOUT }; - return values; -} - -inline const char* const* EnumNamesPortDirection() -{ - static const char* const names[4] = { "INPUT", "OUTPUT", "INOUT", nullptr }; - return names; -} - -inline const char* EnumNamePortDirection(PortDirection e) -{ - if(flatbuffers::IsOutRange(e, PortDirection::INPUT, PortDirection::INOUT)) - return ""; - const size_t index = static_cast(e); - return EnumNamesPortDirection()[index]; -} - -FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Timestamp FLATBUFFERS_FINAL_CLASS -{ -private: - uint64_t usec_since_epoch_; - -public: - Timestamp() : usec_since_epoch_(0) - {} - Timestamp(uint64_t _usec_since_epoch) - : usec_since_epoch_(flatbuffers::EndianScalar(_usec_since_epoch)) - {} - uint64_t usec_since_epoch() const - { - return flatbuffers::EndianScalar(usec_since_epoch_); - } -}; -FLATBUFFERS_STRUCT_END(Timestamp, 8); - -FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) StatusChange FLATBUFFERS_FINAL_CLASS -{ -private: - uint16_t uid_; - int8_t prev_status_; - int8_t status_; - int32_t padding0__; - Serialization::Timestamp timestamp_; - -public: - StatusChange() : uid_(0), prev_status_(0), status_(0), padding0__(0), timestamp_() - { - (void)padding0__; - } - StatusChange(uint16_t _uid, Serialization::NodeStatus _prev_status, - Serialization::NodeStatus _status, - const Serialization::Timestamp& _timestamp) - : uid_(flatbuffers::EndianScalar(_uid)) - , prev_status_(flatbuffers::EndianScalar(static_cast(_prev_status))) - , status_(flatbuffers::EndianScalar(static_cast(_status))) - , padding0__(0) - , timestamp_(_timestamp) - { - (void)padding0__; - } - uint16_t uid() const - { - return flatbuffers::EndianScalar(uid_); - } - Serialization::NodeStatus prev_status() const - { - return static_cast( - flatbuffers::EndianScalar(prev_status_)); - } - Serialization::NodeStatus status() const - { - return static_cast(flatbuffers::EndianScalar(status_)); - } - const Serialization::Timestamp& timestamp() const - { - return timestamp_; - } -}; -FLATBUFFERS_STRUCT_END(StatusChange, 16); - -struct PortModel FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table -{ - typedef PortModelBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE - { - VT_PORT_NAME = 4, - VT_DIRECTION = 6, - VT_TYPE_INFO = 8, - VT_DESCRIPTION = 10 - }; - const flatbuffers::String* port_name() const - { - return GetPointer(VT_PORT_NAME); - } - Serialization::PortDirection direction() const - { - return static_cast(GetField(VT_DIRECTION, 0)); - } - const flatbuffers::String* type_info() const - { - return GetPointer(VT_TYPE_INFO); - } - const flatbuffers::String* description() const - { - return GetPointer(VT_DESCRIPTION); - } - bool Verify(flatbuffers::Verifier& verifier) const - { - return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_PORT_NAME) && - verifier.VerifyString(port_name()) && - VerifyField(verifier, VT_DIRECTION) && - VerifyOffset(verifier, VT_TYPE_INFO) && verifier.VerifyString(type_info()) && - VerifyOffset(verifier, VT_DESCRIPTION) && - verifier.VerifyString(description()) && verifier.EndTable(); - } -}; - -struct PortModelBuilder -{ - typedef PortModel Table; - flatbuffers::FlatBufferBuilder& fbb_; - flatbuffers::uoffset_t start_; - void add_port_name(flatbuffers::Offset port_name) - { - fbb_.AddOffset(PortModel::VT_PORT_NAME, port_name); - } - void add_direction(Serialization::PortDirection direction) - { - fbb_.AddElement(PortModel::VT_DIRECTION, static_cast(direction), 0); - } - void add_type_info(flatbuffers::Offset type_info) - { - fbb_.AddOffset(PortModel::VT_TYPE_INFO, type_info); - } - void add_description(flatbuffers::Offset description) - { - fbb_.AddOffset(PortModel::VT_DESCRIPTION, description); - } - explicit PortModelBuilder(flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) - { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() - { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreatePortModel( - flatbuffers::FlatBufferBuilder& _fbb, - flatbuffers::Offset port_name = 0, - Serialization::PortDirection direction = Serialization::PortDirection::INPUT, - flatbuffers::Offset type_info = 0, - flatbuffers::Offset description = 0) -{ - PortModelBuilder builder_(_fbb); - builder_.add_description(description); - builder_.add_type_info(type_info); - builder_.add_port_name(port_name); - builder_.add_direction(direction); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreatePortModelDirect( - flatbuffers::FlatBufferBuilder& _fbb, const char* port_name = nullptr, - Serialization::PortDirection direction = Serialization::PortDirection::INPUT, - const char* type_info = nullptr, const char* description = nullptr) -{ - auto port_name__ = port_name ? _fbb.CreateString(port_name) : 0; - auto type_info__ = type_info ? _fbb.CreateString(type_info) : 0; - auto description__ = description ? _fbb.CreateString(description) : 0; - return Serialization::CreatePortModel(_fbb, port_name__, direction, type_info__, - description__); -} - -struct PortConfig FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table -{ - typedef PortConfigBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE - { - VT_PORT_NAME = 4, - VT_REMAP = 6 - }; - const flatbuffers::String* port_name() const - { - return GetPointer(VT_PORT_NAME); - } - const flatbuffers::String* remap() const - { - return GetPointer(VT_REMAP); - } - bool Verify(flatbuffers::Verifier& verifier) const - { - return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_PORT_NAME) && - verifier.VerifyString(port_name()) && VerifyOffset(verifier, VT_REMAP) && - verifier.VerifyString(remap()) && verifier.EndTable(); - } -}; - -struct PortConfigBuilder -{ - typedef PortConfig Table; - flatbuffers::FlatBufferBuilder& fbb_; - flatbuffers::uoffset_t start_; - void add_port_name(flatbuffers::Offset port_name) - { - fbb_.AddOffset(PortConfig::VT_PORT_NAME, port_name); - } - void add_remap(flatbuffers::Offset remap) - { - fbb_.AddOffset(PortConfig::VT_REMAP, remap); - } - explicit PortConfigBuilder(flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) - { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() - { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset -CreatePortConfig(flatbuffers::FlatBufferBuilder& _fbb, - flatbuffers::Offset port_name = 0, - flatbuffers::Offset remap = 0) -{ - PortConfigBuilder builder_(_fbb); - builder_.add_remap(remap); - builder_.add_port_name(port_name); - return builder_.Finish(); -} - -inline flatbuffers::Offset -CreatePortConfigDirect(flatbuffers::FlatBufferBuilder& _fbb, - const char* port_name = nullptr, const char* remap = nullptr) -{ - auto port_name__ = port_name ? _fbb.CreateString(port_name) : 0; - auto remap__ = remap ? _fbb.CreateString(remap) : 0; - return Serialization::CreatePortConfig(_fbb, port_name__, remap__); -} - -struct TreeNode FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table -{ - typedef TreeNodeBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE - { - VT_UID = 4, - VT_CHILDREN_UID = 6, - VT_STATUS = 8, - VT_INSTANCE_NAME = 10, - VT_REGISTRATION_NAME = 12, - VT_PORT_REMAPS = 14 - }; - uint16_t uid() const - { - return GetField(VT_UID, 0); - } - const flatbuffers::Vector* children_uid() const - { - return GetPointer*>(VT_CHILDREN_UID); - } - Serialization::NodeStatus status() const - { - return static_cast(GetField(VT_STATUS, 0)); - } - const flatbuffers::String* instance_name() const - { - return GetPointer(VT_INSTANCE_NAME); - } - const flatbuffers::String* registration_name() const - { - return GetPointer(VT_REGISTRATION_NAME); - } - const flatbuffers::Vector>* - port_remaps() const - { - return GetPointer< - const flatbuffers::Vector>*>( - VT_PORT_REMAPS); - } - bool Verify(flatbuffers::Verifier& verifier) const - { - return VerifyTableStart(verifier) && VerifyField(verifier, VT_UID) && - VerifyOffset(verifier, VT_CHILDREN_UID) && - verifier.VerifyVector(children_uid()) && - VerifyField(verifier, VT_STATUS) && - VerifyOffsetRequired(verifier, VT_INSTANCE_NAME) && - verifier.VerifyString(instance_name()) && - VerifyOffsetRequired(verifier, VT_REGISTRATION_NAME) && - verifier.VerifyString(registration_name()) && - VerifyOffset(verifier, VT_PORT_REMAPS) && - verifier.VerifyVector(port_remaps()) && - verifier.VerifyVectorOfTables(port_remaps()) && verifier.EndTable(); - } -}; - -struct TreeNodeBuilder -{ - typedef TreeNode Table; - flatbuffers::FlatBufferBuilder& fbb_; - flatbuffers::uoffset_t start_; - void add_uid(uint16_t uid) - { - fbb_.AddElement(TreeNode::VT_UID, uid, 0); - } - void add_children_uid(flatbuffers::Offset> children_uid) - { - fbb_.AddOffset(TreeNode::VT_CHILDREN_UID, children_uid); - } - void add_status(Serialization::NodeStatus status) - { - fbb_.AddElement(TreeNode::VT_STATUS, static_cast(status), 0); - } - void add_instance_name(flatbuffers::Offset instance_name) - { - fbb_.AddOffset(TreeNode::VT_INSTANCE_NAME, instance_name); - } - void add_registration_name(flatbuffers::Offset registration_name) - { - fbb_.AddOffset(TreeNode::VT_REGISTRATION_NAME, registration_name); - } - void - add_port_remaps(flatbuffers::Offset< - flatbuffers::Vector>> - port_remaps) - { - fbb_.AddOffset(TreeNode::VT_PORT_REMAPS, port_remaps); - } - explicit TreeNodeBuilder(flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) - { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() - { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - fbb_.Required(o, TreeNode::VT_INSTANCE_NAME); - fbb_.Required(o, TreeNode::VT_REGISTRATION_NAME); - return o; - } -}; - -inline flatbuffers::Offset -CreateTreeNode(flatbuffers::FlatBufferBuilder& _fbb, uint16_t uid = 0, - flatbuffers::Offset> children_uid = 0, - Serialization::NodeStatus status = Serialization::NodeStatus::IDLE, - flatbuffers::Offset instance_name = 0, - flatbuffers::Offset registration_name = 0, - flatbuffers::Offset< - flatbuffers::Vector>> - port_remaps = 0) -{ - TreeNodeBuilder builder_(_fbb); - builder_.add_port_remaps(port_remaps); - builder_.add_registration_name(registration_name); - builder_.add_instance_name(instance_name); - builder_.add_children_uid(children_uid); - builder_.add_uid(uid); - builder_.add_status(status); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateTreeNodeDirect( - flatbuffers::FlatBufferBuilder& _fbb, uint16_t uid = 0, - const std::vector* children_uid = nullptr, - Serialization::NodeStatus status = Serialization::NodeStatus::IDLE, - const char* instance_name = nullptr, const char* registration_name = nullptr, - const std::vector>* port_remaps = - nullptr) -{ - auto children_uid__ = children_uid ? _fbb.CreateVector(*children_uid) : 0; - auto instance_name__ = instance_name ? _fbb.CreateString(instance_name) : 0; - auto registration_name__ = registration_name ? _fbb.CreateString(registration_name) : 0; - auto port_remaps__ = - port_remaps ? _fbb.CreateVector>( - *port_remaps) : - 0; - return Serialization::CreateTreeNode(_fbb, uid, children_uid__, status, instance_name__, - registration_name__, port_remaps__); -} - -struct NodeModel FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table -{ - typedef NodeModelBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE - { - VT_REGISTRATION_NAME = 4, - VT_TYPE = 6, - VT_PORTS = 8 - }; - const flatbuffers::String* registration_name() const - { - return GetPointer(VT_REGISTRATION_NAME); - } - Serialization::NodeType type() const - { - return static_cast(GetField(VT_TYPE, 0)); - } - const flatbuffers::Vector>* ports() const - { - return GetPointer< - const flatbuffers::Vector>*>( - VT_PORTS); - } - bool Verify(flatbuffers::Verifier& verifier) const - { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_REGISTRATION_NAME) && - verifier.VerifyString(registration_name()) && - VerifyField(verifier, VT_TYPE) && VerifyOffset(verifier, VT_PORTS) && - verifier.VerifyVector(ports()) && verifier.VerifyVectorOfTables(ports()) && - verifier.EndTable(); - } -}; - -struct NodeModelBuilder -{ - typedef NodeModel Table; - flatbuffers::FlatBufferBuilder& fbb_; - flatbuffers::uoffset_t start_; - void add_registration_name(flatbuffers::Offset registration_name) - { - fbb_.AddOffset(NodeModel::VT_REGISTRATION_NAME, registration_name); - } - void add_type(Serialization::NodeType type) - { - fbb_.AddElement(NodeModel::VT_TYPE, static_cast(type), 0); - } - void add_ports(flatbuffers::Offset< - flatbuffers::Vector>> - ports) - { - fbb_.AddOffset(NodeModel::VT_PORTS, ports); - } - explicit NodeModelBuilder(flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) - { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() - { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - fbb_.Required(o, NodeModel::VT_REGISTRATION_NAME); - return o; - } -}; - -inline flatbuffers::Offset -CreateNodeModel(flatbuffers::FlatBufferBuilder& _fbb, - flatbuffers::Offset registration_name = 0, - Serialization::NodeType type = Serialization::NodeType::UNDEFINED, - flatbuffers::Offset< - flatbuffers::Vector>> - ports = 0) -{ - NodeModelBuilder builder_(_fbb); - builder_.add_ports(ports); - builder_.add_registration_name(registration_name); - builder_.add_type(type); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateNodeModelDirect( - flatbuffers::FlatBufferBuilder& _fbb, const char* registration_name = nullptr, - Serialization::NodeType type = Serialization::NodeType::UNDEFINED, - const std::vector>* ports = nullptr) -{ - auto registration_name__ = registration_name ? _fbb.CreateString(registration_name) : 0; - auto ports__ = - ports ? _fbb.CreateVector>(*ports) : - 0; - return Serialization::CreateNodeModel(_fbb, registration_name__, type, ports__); -} - -struct BehaviorTree FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table -{ - typedef BehaviorTreeBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE - { - VT_ROOT_UID = 4, - VT_NODES = 6, - VT_NODE_MODELS = 8 - }; - uint16_t root_uid() const - { - return GetField(VT_ROOT_UID, 0); - } - const flatbuffers::Vector>* nodes() const - { - return GetPointer< - const flatbuffers::Vector>*>( - VT_NODES); - } - const flatbuffers::Vector>* - node_models() const - { - return GetPointer< - const flatbuffers::Vector>*>( - VT_NODE_MODELS); - } - bool Verify(flatbuffers::Verifier& verifier) const - { - return VerifyTableStart(verifier) && VerifyField(verifier, VT_ROOT_UID) && - VerifyOffset(verifier, VT_NODES) && verifier.VerifyVector(nodes()) && - verifier.VerifyVectorOfTables(nodes()) && - VerifyOffset(verifier, VT_NODE_MODELS) && - verifier.VerifyVector(node_models()) && - verifier.VerifyVectorOfTables(node_models()) && verifier.EndTable(); - } -}; - -struct BehaviorTreeBuilder -{ - typedef BehaviorTree Table; - flatbuffers::FlatBufferBuilder& fbb_; - flatbuffers::uoffset_t start_; - void add_root_uid(uint16_t root_uid) - { - fbb_.AddElement(BehaviorTree::VT_ROOT_UID, root_uid, 0); - } - void add_nodes(flatbuffers::Offset< - flatbuffers::Vector>> - nodes) - { - fbb_.AddOffset(BehaviorTree::VT_NODES, nodes); - } - void add_node_models(flatbuffers::Offset< - flatbuffers::Vector>> - node_models) - { - fbb_.AddOffset(BehaviorTree::VT_NODE_MODELS, node_models); - } - explicit BehaviorTreeBuilder(flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) - { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() - { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateBehaviorTree( - flatbuffers::FlatBufferBuilder& _fbb, uint16_t root_uid = 0, - flatbuffers::Offset>> - nodes = 0, - flatbuffers::Offset< - flatbuffers::Vector>> - node_models = 0) -{ - BehaviorTreeBuilder builder_(_fbb); - builder_.add_node_models(node_models); - builder_.add_nodes(nodes); - builder_.add_root_uid(root_uid); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateBehaviorTreeDirect( - flatbuffers::FlatBufferBuilder& _fbb, uint16_t root_uid = 0, - const std::vector>* nodes = nullptr, - const std::vector>* node_models = - nullptr) -{ - auto nodes__ = - nodes ? _fbb.CreateVector>(*nodes) : 0; - auto node_models__ = - node_models ? - _fbb.CreateVector>(*node_models) : - 0; - return Serialization::CreateBehaviorTree(_fbb, root_uid, nodes__, node_models__); -} - -struct StatusChangeLog FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table -{ - typedef StatusChangeLogBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE - { - VT_BEHAVIOR_TREE = 4, - VT_STATE_CHANGES = 6 - }; - const Serialization::BehaviorTree* behavior_tree() const - { - return GetPointer(VT_BEHAVIOR_TREE); - } - const flatbuffers::Vector* state_changes() const - { - return GetPointer*>( - VT_STATE_CHANGES); - } - bool Verify(flatbuffers::Verifier& verifier) const - { - return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_BEHAVIOR_TREE) && - verifier.VerifyTable(behavior_tree()) && - VerifyOffset(verifier, VT_STATE_CHANGES) && - verifier.VerifyVector(state_changes()) && verifier.EndTable(); - } -}; - -struct StatusChangeLogBuilder -{ - typedef StatusChangeLog Table; - flatbuffers::FlatBufferBuilder& fbb_; - flatbuffers::uoffset_t start_; - void add_behavior_tree(flatbuffers::Offset behavior_tree) - { - fbb_.AddOffset(StatusChangeLog::VT_BEHAVIOR_TREE, behavior_tree); - } - void add_state_changes( - flatbuffers::Offset> - state_changes) - { - fbb_.AddOffset(StatusChangeLog::VT_STATE_CHANGES, state_changes); - } - explicit StatusChangeLogBuilder(flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) - { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() - { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateStatusChangeLog( - flatbuffers::FlatBufferBuilder& _fbb, - flatbuffers::Offset behavior_tree = 0, - flatbuffers::Offset> - state_changes = 0) -{ - StatusChangeLogBuilder builder_(_fbb); - builder_.add_state_changes(state_changes); - builder_.add_behavior_tree(behavior_tree); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateStatusChangeLogDirect( - flatbuffers::FlatBufferBuilder& _fbb, - flatbuffers::Offset behavior_tree = 0, - const std::vector* state_changes = nullptr) -{ - auto state_changes__ = - state_changes ? - _fbb.CreateVectorOfStructs(*state_changes) : - 0; - return Serialization::CreateStatusChangeLog(_fbb, behavior_tree, state_changes__); -} - -inline const Serialization::BehaviorTree* GetBehaviorTree(const void* buf) -{ - return flatbuffers::GetRoot(buf); -} - -inline const Serialization::BehaviorTree* GetSizePrefixedBehaviorTree(const void* buf) -{ - return flatbuffers::GetSizePrefixedRoot(buf); -} - -inline bool VerifyBehaviorTreeBuffer(flatbuffers::Verifier& verifier) -{ - return verifier.VerifyBuffer(nullptr); -} - -inline bool VerifySizePrefixedBehaviorTreeBuffer(flatbuffers::Verifier& verifier) -{ - return verifier.VerifySizePrefixedBuffer(nullptr); -} - -inline void -FinishBehaviorTreeBuffer(flatbuffers::FlatBufferBuilder& fbb, - flatbuffers::Offset root) -{ - fbb.Finish(root); -} - -inline void FinishSizePrefixedBehaviorTreeBuffer( - flatbuffers::FlatBufferBuilder& fbb, - flatbuffers::Offset root) -{ - fbb.FinishSizePrefixed(root); -} - -} // namespace Serialization - -#endif // FLATBUFFERS_GENERATED_BTLOGGER_SERIALIZATION_H_ diff --git a/include/behaviortree_cpp/flatbuffers/LICENSE.txt b/include/behaviortree_cpp/flatbuffers/LICENSE.txt deleted file mode 100644 index a4c5efd82..000000000 --- a/include/behaviortree_cpp/flatbuffers/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2014 Google Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/include/behaviortree_cpp/flatbuffers/flatbuffers.h b/include/behaviortree_cpp/flatbuffers/flatbuffers.h deleted file mode 100644 index a0acaf4dc..000000000 --- a/include/behaviortree_cpp/flatbuffers/flatbuffers.h +++ /dev/null @@ -1,3518 +0,0 @@ -/* - * Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_H_ -#define FLATBUFFERS_H_ - -#include "behaviortree_cpp/flatbuffers/base.h" -#include "behaviortree_cpp/flatbuffers/stl_emulation.h" - -#ifndef FLATBUFFERS_CPP98_STL -#include -#endif - -#if defined(FLATBUFFERS_NAN_DEFAULTS) -#include -#endif - -namespace flatbuffers -{ -// Generic 'operator==' with conditional specialisations. -// T e - new value of a scalar field. -// T def - default of scalar (is known at compile-time). -template -inline bool IsTheSameAs(T e, T def) -{ - return e == def; -} - -#if defined(FLATBUFFERS_NAN_DEFAULTS) && defined(FLATBUFFERS_HAS_NEW_STRTOD) && \ - (FLATBUFFERS_HAS_NEW_STRTOD > 0) -// Like `operator==(e, def)` with weak NaN if T=(float|double). -template -inline bool IsFloatTheSameAs(T e, T def) -{ - return (e == def) || ((def != def) && (e != e)); -} -template <> -inline bool IsTheSameAs(float e, float def) -{ - return IsFloatTheSameAs(e, def); -} -template <> -inline bool IsTheSameAs(double e, double def) -{ - return IsFloatTheSameAs(e, def); -} -#endif - -// Check 'v' is out of closed range [low; high]. -// Workaround for GCC warning [-Werror=type-limits]: -// comparison is always true due to limited range of data type. -template -inline bool IsOutRange(const T& v, const T& low, const T& high) -{ - return (v < low) || (high < v); -} - -// Check 'v' is in closed range [low; high]. -template -inline bool IsInRange(const T& v, const T& low, const T& high) -{ - return !IsOutRange(v, low, high); -} - -// Wrapper for uoffset_t to allow safe template specialization. -// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset). -template -struct Offset -{ - uoffset_t o; - Offset() : o(0) - {} - Offset(uoffset_t _o) : o(_o) - {} - Offset Union() const - { - return Offset(o); - } - bool IsNull() const - { - return !o; - } -}; - -inline void EndianCheck() -{ - int endiantest = 1; - // If this fails, see FLATBUFFERS_LITTLEENDIAN above. - FLATBUFFERS_ASSERT(*reinterpret_cast(&endiantest) == FLATBUFFERS_LITTLEENDIAN); - (void)endiantest; -} - -template -FLATBUFFERS_CONSTEXPR size_t AlignOf() -{ - // clang-format off - #ifdef _MSC_VER - return __alignof(T); - #else - #ifndef alignof - return __alignof__(T); - #else - return alignof(T); - #endif - #endif - // clang-format on -} - -// When we read serialized data from memory, in the case of most scalars, -// we want to just read T, but in the case of Offset, we want to actually -// perform the indirection and return a pointer. -// The template specialization below does just that. -// It is wrapped in a struct since function templates can't overload on the -// return type like this. -// The typedef is for the convenience of callers of this function -// (avoiding the need for a trailing return decltype) -template -struct IndirectHelper -{ - typedef T return_type; - typedef T mutable_return_type; - static const size_t element_stride = sizeof(T); - static return_type Read(const uint8_t* p, uoffset_t i) - { - return EndianScalar((reinterpret_cast(p))[i]); - } -}; -template -struct IndirectHelper> -{ - typedef const T* return_type; - typedef T* mutable_return_type; - static const size_t element_stride = sizeof(uoffset_t); - static return_type Read(const uint8_t* p, uoffset_t i) - { - p += i * sizeof(uoffset_t); - return reinterpret_cast(p + ReadScalar(p)); - } -}; -template -struct IndirectHelper -{ - typedef const T* return_type; - typedef T* mutable_return_type; - static const size_t element_stride = sizeof(T); - static return_type Read(const uint8_t* p, uoffset_t i) - { - return reinterpret_cast(p + i * sizeof(T)); - } -}; - -// An STL compatible iterator implementation for Vector below, effectively -// calling Get() for every element. -template -struct VectorIterator -{ - typedef std::random_access_iterator_tag iterator_category; - typedef IT value_type; - typedef ptrdiff_t difference_type; - typedef IT* pointer; - typedef IT& reference; - - VectorIterator(const uint8_t* data, uoffset_t i) - : data_(data + IndirectHelper::element_stride * i) - {} - VectorIterator(const VectorIterator& other) : data_(other.data_) - {} - VectorIterator() : data_(nullptr) - {} - - VectorIterator& operator=(const VectorIterator& other) - { - data_ = other.data_; - return *this; - } - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - VectorIterator &operator=(VectorIterator &&other) { - data_ = other.data_; - return *this; - } - #endif // !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - - bool operator==(const VectorIterator& other) const - { - return data_ == other.data_; - } - - bool operator<(const VectorIterator& other) const - { - return data_ < other.data_; - } - - bool operator!=(const VectorIterator& other) const - { - return data_ != other.data_; - } - - difference_type operator-(const VectorIterator& other) const - { - return (data_ - other.data_) / IndirectHelper::element_stride; - } - - IT operator*() const - { - return IndirectHelper::Read(data_, 0); - } - - IT operator->() const - { - return IndirectHelper::Read(data_, 0); - } - - VectorIterator& operator++() - { - data_ += IndirectHelper::element_stride; - return *this; - } - - VectorIterator operator++(int) - { - VectorIterator temp(data_, 0); - data_ += IndirectHelper::element_stride; - return temp; - } - - VectorIterator operator+(const uoffset_t& offset) const - { - return VectorIterator(data_ + offset * IndirectHelper::element_stride, 0); - } - - VectorIterator& operator+=(const uoffset_t& offset) - { - data_ += offset * IndirectHelper::element_stride; - return *this; - } - - VectorIterator& operator--() - { - data_ -= IndirectHelper::element_stride; - return *this; - } - - VectorIterator operator--(int) - { - VectorIterator temp(data_, 0); - data_ -= IndirectHelper::element_stride; - return temp; - } - - VectorIterator operator-(const uoffset_t& offset) const - { - return VectorIterator(data_ - offset * IndirectHelper::element_stride, 0); - } - - VectorIterator& operator-=(const uoffset_t& offset) - { - data_ -= offset * IndirectHelper::element_stride; - return *this; - } - -private: - const uint8_t* data_; -}; - -template -struct VectorReverseIterator : public std::reverse_iterator -{ - explicit VectorReverseIterator(Iterator iter) : std::reverse_iterator(iter) - {} - - typename Iterator::value_type operator*() const - { - return *(std::reverse_iterator::current); - } - - typename Iterator::value_type operator->() const - { - return *(std::reverse_iterator::current); - } -}; - -struct String; - -// This is used as a helper type for accessing vectors. -// Vector::data() assumes the vector elements start after the length field. -template -class Vector -{ -public: - typedef VectorIterator::mutable_return_type> iterator; - typedef VectorIterator::return_type> const_iterator; - typedef VectorReverseIterator reverse_iterator; - typedef VectorReverseIterator const_reverse_iterator; - - uoffset_t size() const - { - return EndianScalar(length_); - } - - // Deprecated: use size(). Here for backwards compatibility. - FLATBUFFERS_ATTRIBUTE(deprecated("use size() instead")) - uoffset_t Length() const - { - return size(); - } - - typedef typename IndirectHelper::return_type return_type; - typedef typename IndirectHelper::mutable_return_type mutable_return_type; - typedef return_type value_type; - - return_type Get(uoffset_t i) const - { - FLATBUFFERS_ASSERT(i < size()); - return IndirectHelper::Read(Data(), i); - } - - return_type operator[](uoffset_t i) const - { - return Get(i); - } - - // If this is a Vector of enums, T will be its storage type, not the enum - // type. This function makes it convenient to retrieve value with enum - // type E. - template - E GetEnum(uoffset_t i) const - { - return static_cast(Get(i)); - } - - // If this a vector of unions, this does the cast for you. There's no check - // to make sure this is the right type! - template - const U* GetAs(uoffset_t i) const - { - return reinterpret_cast(Get(i)); - } - - // If this a vector of unions, this does the cast for you. There's no check - // to make sure this is actually a string! - const String* GetAsString(uoffset_t i) const - { - return reinterpret_cast(Get(i)); - } - - const void* GetStructFromOffset(size_t o) const - { - return reinterpret_cast(Data() + o); - } - - iterator begin() - { - return iterator(Data(), 0); - } - const_iterator begin() const - { - return const_iterator(Data(), 0); - } - - iterator end() - { - return iterator(Data(), size()); - } - const_iterator end() const - { - return const_iterator(Data(), size()); - } - - reverse_iterator rbegin() - { - return reverse_iterator(end() - 1); - } - const_reverse_iterator rbegin() const - { - return const_reverse_iterator(end() - 1); - } - - reverse_iterator rend() - { - return reverse_iterator(begin() - 1); - } - const_reverse_iterator rend() const - { - return const_reverse_iterator(begin() - 1); - } - - const_iterator cbegin() const - { - return begin(); - } - - const_iterator cend() const - { - return end(); - } - - const_reverse_iterator crbegin() const - { - return rbegin(); - } - - const_reverse_iterator crend() const - { - return rend(); - } - - // Change elements if you have a non-const pointer to this object. - // Scalars only. See reflection.h, and the documentation. - void Mutate(uoffset_t i, const T& val) - { - FLATBUFFERS_ASSERT(i < size()); - WriteScalar(data() + i, val); - } - - // Change an element of a vector of tables (or strings). - // "val" points to the new table/string, as you can obtain from - // e.g. reflection::AddFlatBuffer(). - void MutateOffset(uoffset_t i, const uint8_t* val) - { - FLATBUFFERS_ASSERT(i < size()); - static_assert(sizeof(T) == sizeof(uoffset_t), "Unrelated types"); - WriteScalar(data() + i, - static_cast(val - (Data() + i * sizeof(uoffset_t)))); - } - - // Get a mutable pointer to tables/strings inside this vector. - mutable_return_type GetMutableObject(uoffset_t i) const - { - FLATBUFFERS_ASSERT(i < size()); - return const_cast(IndirectHelper::Read(Data(), i)); - } - - // The raw data in little endian format. Use with care. - const uint8_t* Data() const - { - return reinterpret_cast(&length_ + 1); - } - - uint8_t* Data() - { - return reinterpret_cast(&length_ + 1); - } - - // Similarly, but typed, much like std::vector::data - const T* data() const - { - return reinterpret_cast(Data()); - } - T* data() - { - return reinterpret_cast(Data()); - } - - template - return_type LookupByKey(K key) const - { - void* search_result = std::bsearch(&key, Data(), size(), - IndirectHelper::element_stride, KeyCompare); - - if(!search_result) - { - return nullptr; // Key not found. - } - - const uint8_t* element = reinterpret_cast(search_result); - - return IndirectHelper::Read(element, 0); - } - -protected: - // This class is only used to access pre-existing data. Don't ever - // try to construct these manually. - Vector(); - - uoffset_t length_; - -private: - // This class is a pointer. Copying will therefore create an invalid object. - // Private and unimplemented copy constructor. - Vector(const Vector&); - Vector& operator=(const Vector&); - - template - static int KeyCompare(const void* ap, const void* bp) - { - const K* key = reinterpret_cast(ap); - const uint8_t* data = reinterpret_cast(bp); - auto table = IndirectHelper::Read(data, 0); - - // std::bsearch compares with the operands transposed, so we negate the - // result here. - return -table->KeyCompareWithValue(*key); - } -}; - -// Represent a vector much like the template above, but in this case we -// don't know what the element types are (used with reflection.h). -class VectorOfAny -{ -public: - uoffset_t size() const - { - return EndianScalar(length_); - } - - const uint8_t* Data() const - { - return reinterpret_cast(&length_ + 1); - } - uint8_t* Data() - { - return reinterpret_cast(&length_ + 1); - } - -protected: - VectorOfAny(); - - uoffset_t length_; - -private: - VectorOfAny(const VectorOfAny&); - VectorOfAny& operator=(const VectorOfAny&); -}; - -#ifndef FLATBUFFERS_CPP98_STL -template -Vector>* VectorCast(Vector>* ptr) -{ - static_assert(std::is_base_of::value, "Unrelated types"); - return reinterpret_cast>*>(ptr); -} - -template -const Vector>* VectorCast(const Vector>* ptr) -{ - static_assert(std::is_base_of::value, "Unrelated types"); - return reinterpret_cast>*>(ptr); -} -#endif - -// Convenient helper function to get the length of any vector, regardless -// of whether it is null or not (the field is not set). -template -static inline size_t VectorLength(const Vector* v) -{ - return v ? v->size() : 0; -} - -// This is used as a helper type for accessing arrays. -template -class Array -{ - typedef typename flatbuffers::integral_constant::value> - scalar_tag; - typedef typename flatbuffers::conditional::type - IndirectHelperType; - -public: - typedef uint16_t size_type; - typedef typename IndirectHelper::return_type return_type; - typedef VectorIterator const_iterator; - typedef VectorReverseIterator const_reverse_iterator; - - FLATBUFFERS_CONSTEXPR uint16_t size() const - { - return length; - } - - return_type Get(uoffset_t i) const - { - FLATBUFFERS_ASSERT(i < size()); - return IndirectHelper::Read(Data(), i); - } - - return_type operator[](uoffset_t i) const - { - return Get(i); - } - - // If this is a Vector of enums, T will be its storage type, not the enum - // type. This function makes it convenient to retrieve value with enum - // type E. - template - E GetEnum(uoffset_t i) const - { - return static_cast(Get(i)); - } - - const_iterator begin() const - { - return const_iterator(Data(), 0); - } - const_iterator end() const - { - return const_iterator(Data(), size()); - } - - const_reverse_iterator rbegin() const - { - return const_reverse_iterator(end()); - } - const_reverse_iterator rend() const - { - return const_reverse_iterator(end()); - } - - const_iterator cbegin() const - { - return begin(); - } - const_iterator cend() const - { - return end(); - } - - const_reverse_iterator crbegin() const - { - return rbegin(); - } - const_reverse_iterator crend() const - { - return rend(); - } - - // Get a mutable pointer to elements inside this array. - // This method used to mutate arrays of structs followed by a @p Mutate - // operation. For primitive types use @p Mutate directly. - // @warning Assignments and reads to/from the dereferenced pointer are not - // automatically converted to the correct endianness. - typename flatbuffers::conditional::type - GetMutablePointer(uoffset_t i) const - { - FLATBUFFERS_ASSERT(i < size()); - return const_cast(&data()[i]); - } - - // Change elements if you have a non-const pointer to this object. - void Mutate(uoffset_t i, const T& val) - { - MutateImpl(scalar_tag(), i, val); - } - - // The raw data in little endian format. Use with care. - const uint8_t* Data() const - { - return data_; - } - - uint8_t* Data() - { - return data_; - } - - // Similarly, but typed, much like std::vector::data - const T* data() const - { - return reinterpret_cast(Data()); - } - T* data() - { - return reinterpret_cast(Data()); - } - - // Copy data from a span with endian conversion. - // If this Array and the span overlap, the behavior is undefined. - void CopyFromSpan(flatbuffers::span src) - { - const auto p1 = reinterpret_cast(src.data()); - const auto p2 = Data(); - FLATBUFFERS_ASSERT(!(p1 >= p2 && p1 < (p2 + length)) && - !(p2 >= p1 && p2 < (p1 + length))); - (void)p1; - (void)p2; - - CopyFromSpanImpl( - flatbuffers::integral_constant < bool, - !scalar_tag::value || sizeof(T) == 1 || FLATBUFFERS_LITTLEENDIAN > (), src); - } - -protected: - void MutateImpl(flatbuffers::integral_constant, uoffset_t i, const T& val) - { - FLATBUFFERS_ASSERT(i < size()); - WriteScalar(data() + i, val); - } - - void MutateImpl(flatbuffers::integral_constant, uoffset_t i, const T& val) - { - *(GetMutablePointer(i)) = val; - } - - void CopyFromSpanImpl(flatbuffers::integral_constant, - flatbuffers::span src) - { - // Use std::memcpy() instead of std::copy() to avoid preformance degradation - // due to aliasing if T is char or unsigned char. - // The size is known at compile time, so memcpy would be inlined. - std::memcpy(data(), src.data(), length * sizeof(T)); - } - - // Copy data from flatbuffers::span with endian conversion. - void CopyFromSpanImpl(flatbuffers::integral_constant, - flatbuffers::span src) - { - for(size_type k = 0; k < length; k++) - { - Mutate(k, src[k]); - } - } - - // This class is only used to access pre-existing data. Don't ever - // try to construct these manually. - // 'constexpr' allows us to use 'size()' at compile time. - // @note Must not use 'FLATBUFFERS_CONSTEXPR' here, as const is not allowed on - // a constructor. -#if defined(__cpp_constexpr) - constexpr Array(); -#else - Array(); -#endif - - uint8_t data_[length * sizeof(T)]; - -private: - // This class is a pointer. Copying will therefore create an invalid object. - // Private and unimplemented copy constructor. - Array(const Array&); - Array& operator=(const Array&); -}; - -// Specialization for Array[struct] with access using Offset pointer. -// This specialization used by idl_gen_text.cpp. -template -class Array, length> -{ - static_assert(flatbuffers::is_same::value, "unexpected type T"); - -public: - typedef const void* return_type; - - const uint8_t* Data() const - { - return data_; - } - - // Make idl_gen_text.cpp::PrintContainer happy. - return_type operator[](uoffset_t) const - { - FLATBUFFERS_ASSERT(false); - return nullptr; - } - -private: - // This class is only used to access pre-existing data. - Array(); - Array(const Array&); - Array& operator=(const Array&); - - uint8_t data_[1]; -}; - -// Cast a raw T[length] to a raw flatbuffers::Array -// without endian conversion. Use with care. -template -Array& CastToArray(T (&arr)[length]) -{ - return *reinterpret_cast*>(arr); -} - -template -const Array& CastToArray(const T (&arr)[length]) -{ - return *reinterpret_cast*>(arr); -} - -template -Array& CastToArrayOfEnum(T (&arr)[length]) -{ - static_assert(sizeof(E) == sizeof(T), "invalid enum type E"); - return *reinterpret_cast*>(arr); -} - -template -const Array& CastToArrayOfEnum(const T (&arr)[length]) -{ - static_assert(sizeof(E) == sizeof(T), "invalid enum type E"); - return *reinterpret_cast*>(arr); -} - -// Lexicographically compare two strings (possibly containing nulls), and -// return true if the first is less than the second. -static inline bool StringLessThan(const char* a_data, uoffset_t a_size, - const char* b_data, uoffset_t b_size) -{ - const auto cmp = memcmp(a_data, b_data, (std::min)(a_size, b_size)); - return cmp == 0 ? a_size < b_size : cmp < 0; -} - -struct String : public Vector -{ - const char* c_str() const - { - return reinterpret_cast(Data()); - } - std::string str() const - { - return std::string(c_str(), size()); - } - - // clang-format off - #ifdef FLATBUFFERS_HAS_STRING_VIEW - flatbuffers::string_view string_view() const { - return flatbuffers::string_view(c_str(), size()); - } - #endif // FLATBUFFERS_HAS_STRING_VIEW - // clang-format on - - bool operator<(const String& o) const - { - return StringLessThan(this->data(), this->size(), o.data(), o.size()); - } -}; - -// Convenience function to get std::string from a String returning an empty -// string on null pointer. -static inline std::string GetString(const String* str) -{ - return str ? str->str() : ""; -} - -// Convenience function to get char* from a String returning an empty string on -// null pointer. -static inline const char* GetCstring(const String* str) -{ - return str ? str->c_str() : ""; -} - -#ifdef FLATBUFFERS_HAS_STRING_VIEW -// Convenience function to get string_view from a String returning an empty -// string_view on null pointer. -static inline flatbuffers::string_view GetStringView(const String* str) -{ - return str ? str->string_view() : flatbuffers::string_view(); -} -#endif // FLATBUFFERS_HAS_STRING_VIEW - -// Allocator interface. This is flatbuffers-specific and meant only for -// `vector_downward` usage. -class Allocator -{ -public: - virtual ~Allocator() - {} - - // Allocate `size` bytes of memory. - virtual uint8_t* allocate(size_t size) = 0; - - // Deallocate `size` bytes of memory at `p` allocated by this allocator. - virtual void deallocate(uint8_t* p, size_t size) = 0; - - // Reallocate `new_size` bytes of memory, replacing the old region of size - // `old_size` at `p`. In contrast to a normal realloc, this grows downwards, - // and is intended specifcally for `vector_downward` use. - // `in_use_back` and `in_use_front` indicate how much of `old_size` is - // actually in use at each end, and needs to be copied. - virtual uint8_t* reallocate_downward(uint8_t* old_p, size_t old_size, size_t new_size, - size_t in_use_back, size_t in_use_front) - { - FLATBUFFERS_ASSERT(new_size > old_size); // vector_downward only grows - uint8_t* new_p = allocate(new_size); - memcpy_downward(old_p, old_size, new_p, new_size, in_use_back, in_use_front); - deallocate(old_p, old_size); - return new_p; - } - -protected: - // Called by `reallocate_downward` to copy memory from `old_p` of `old_size` - // to `new_p` of `new_size`. Only memory of size `in_use_front` and - // `in_use_back` will be copied from the front and back of the old memory - // allocation. - void memcpy_downward(uint8_t* old_p, size_t old_size, uint8_t* new_p, size_t new_size, - size_t in_use_back, size_t in_use_front) - { - memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back, in_use_back); - memcpy(new_p, old_p, in_use_front); - } -}; - -// DefaultAllocator uses new/delete to allocate memory regions -class DefaultAllocator : public Allocator -{ -public: - uint8_t* allocate(size_t size) FLATBUFFERS_OVERRIDE - { - return new uint8_t[size]; - } - - void deallocate(uint8_t* p, size_t) FLATBUFFERS_OVERRIDE - { - delete[] p; - } - - static void dealloc(void* p, size_t) - { - delete[] static_cast(p); - } -}; - -// These functions allow for a null allocator to mean use the default allocator, -// as used by DetachedBuffer and vector_downward below. -// This is to avoid having a statically or dynamically allocated default -// allocator, or having to move it between the classes that may own it. -inline uint8_t* Allocate(Allocator* allocator, size_t size) -{ - return allocator ? allocator->allocate(size) : DefaultAllocator().allocate(size); -} - -inline void Deallocate(Allocator* allocator, uint8_t* p, size_t size) -{ - if(allocator) - allocator->deallocate(p, size); - else - DefaultAllocator().deallocate(p, size); -} - -inline uint8_t* ReallocateDownward(Allocator* allocator, uint8_t* old_p, size_t old_size, - size_t new_size, size_t in_use_back, - size_t in_use_front) -{ - return allocator ? allocator->reallocate_downward(old_p, old_size, new_size, - in_use_back, in_use_front) : - DefaultAllocator().reallocate_downward(old_p, old_size, new_size, - in_use_back, in_use_front); -} - -// DetachedBuffer is a finished flatbuffer memory region, detached from its -// builder. The original memory region and allocator are also stored so that -// the DetachedBuffer can manage the memory lifetime. -class DetachedBuffer -{ -public: - DetachedBuffer() - : allocator_(nullptr) - , own_allocator_(false) - , buf_(nullptr) - , reserved_(0) - , cur_(nullptr) - , size_(0) - {} - - DetachedBuffer(Allocator* allocator, bool own_allocator, uint8_t* buf, size_t reserved, - uint8_t* cur, size_t sz) - : allocator_(allocator) - , own_allocator_(own_allocator) - , buf_(buf) - , reserved_(reserved) - , cur_(cur) - , size_(sz) - {} - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - DetachedBuffer(DetachedBuffer&& other) - : allocator_(other.allocator_) - , own_allocator_(other.own_allocator_) - , buf_(other.buf_) - , reserved_(other.reserved_) - , cur_(other.cur_) - , size_(other.size_) - { - other.reset(); - } - // clang-format off - #endif // !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - DetachedBuffer& operator=(DetachedBuffer&& other) - { - if(this == &other) - return *this; - - destroy(); - - allocator_ = other.allocator_; - own_allocator_ = other.own_allocator_; - buf_ = other.buf_; - reserved_ = other.reserved_; - cur_ = other.cur_; - size_ = other.size_; - - other.reset(); - - return *this; - } - // clang-format off - #endif // !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - - ~DetachedBuffer() - { - destroy(); - } - - const uint8_t* data() const - { - return cur_; - } - - uint8_t* data() - { - return cur_; - } - - size_t size() const - { - return size_; - } - - // clang-format off - #if 0 // disabled for now due to the ordering of classes in this header - template - bool Verify() const { - Verifier verifier(data(), size()); - return verifier.Verify(nullptr); - } - - template - const T* GetRoot() const { - return flatbuffers::GetRoot(data()); - } - - template - T* GetRoot() { - return flatbuffers::GetRoot(data()); - } - #endif - // clang-format on - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - // These may change access mode, leave these at end of public section - FLATBUFFERS_DELETE_FUNC(DetachedBuffer(const DetachedBuffer& other)); - FLATBUFFERS_DELETE_FUNC(DetachedBuffer& operator=(const DetachedBuffer& other)); - // clang-format off - #endif // !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - -protected: - Allocator* allocator_; - bool own_allocator_; - uint8_t* buf_; - size_t reserved_; - uint8_t* cur_; - size_t size_; - - inline void destroy() - { - if(buf_) - Deallocate(allocator_, buf_, reserved_); - if(own_allocator_ && allocator_) - { - delete allocator_; - } - reset(); - } - - inline void reset() - { - allocator_ = nullptr; - own_allocator_ = false; - buf_ = nullptr; - reserved_ = 0; - cur_ = nullptr; - size_ = 0; - } -}; - -// This is a minimal replication of std::vector functionality, -// except growing from higher to lower addresses. i.e push_back() inserts data -// in the lowest address in the vector. -// Since this vector leaves the lower part unused, we support a "scratch-pad" -// that can be stored there for temporary data, to share the allocated space. -// Essentially, this supports 2 std::vectors in a single buffer. -class vector_downward -{ -public: - explicit vector_downward(size_t initial_size, Allocator* allocator, bool own_allocator, - size_t buffer_minalign) - : allocator_(allocator) - , own_allocator_(own_allocator) - , initial_size_(initial_size) - , buffer_minalign_(buffer_minalign) - , reserved_(0) - , buf_(nullptr) - , cur_(nullptr) - , scratch_(nullptr) - {} - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - vector_downward(vector_downward &&other) - #else - vector_downward(vector_downward &other) - #endif // defined(FLATBUFFERS_CPP98_STL) - // clang-format on - : allocator_(other.allocator_) - , own_allocator_(other.own_allocator_) - , initial_size_(other.initial_size_) - , buffer_minalign_(other.buffer_minalign_) - , reserved_(other.reserved_) - , buf_(other.buf_) - , cur_(other.cur_) - , scratch_(other.scratch_) - { - // No change in other.allocator_ - // No change in other.initial_size_ - // No change in other.buffer_minalign_ - other.own_allocator_ = false; - other.reserved_ = 0; - other.buf_ = nullptr; - other.cur_ = nullptr; - other.scratch_ = nullptr; - } - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - vector_downward& operator=(vector_downward&& other) - { - // Move construct a temporary and swap idiom - vector_downward temp(std::move(other)); - swap(temp); - return *this; - } - // clang-format off - #endif // defined(FLATBUFFERS_CPP98_STL) - // clang-format on - - ~vector_downward() - { - clear_buffer(); - clear_allocator(); - } - - void reset() - { - clear_buffer(); - clear(); - } - - void clear() - { - if(buf_) - { - cur_ = buf_ + reserved_; - } - else - { - reserved_ = 0; - cur_ = nullptr; - } - clear_scratch(); - } - - void clear_scratch() - { - scratch_ = buf_; - } - - void clear_allocator() - { - if(own_allocator_ && allocator_) - { - delete allocator_; - } - allocator_ = nullptr; - own_allocator_ = false; - } - - void clear_buffer() - { - if(buf_) - Deallocate(allocator_, buf_, reserved_); - buf_ = nullptr; - } - - // Relinquish the pointer to the caller. - uint8_t* release_raw(size_t& allocated_bytes, size_t& offset) - { - auto* buf = buf_; - allocated_bytes = reserved_; - offset = static_cast(cur_ - buf_); - - // release_raw only relinquishes the buffer ownership. - // Does not deallocate or reset the allocator. Destructor will do that. - buf_ = nullptr; - clear(); - return buf; - } - - // Relinquish the pointer to the caller. - DetachedBuffer release() - { - // allocator ownership (if any) is transferred to DetachedBuffer. - DetachedBuffer fb(allocator_, own_allocator_, buf_, reserved_, cur_, size()); - if(own_allocator_) - { - allocator_ = nullptr; - own_allocator_ = false; - } - buf_ = nullptr; - clear(); - return fb; - } - - size_t ensure_space(size_t len) - { - FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_); - if(len > static_cast(cur_ - scratch_)) - { - reallocate(len); - } - // Beyond this, signed offsets may not have enough range: - // (FlatBuffers > 2GB not supported). - FLATBUFFERS_ASSERT(size() < FLATBUFFERS_MAX_BUFFER_SIZE); - return len; - } - - inline uint8_t* make_space(size_t len) - { - size_t space = ensure_space(len); - cur_ -= space; - return cur_; - } - - // Returns nullptr if using the DefaultAllocator. - Allocator* get_custom_allocator() - { - return allocator_; - } - - uoffset_t size() const - { - return static_cast(reserved_ - static_cast(cur_ - buf_)); - } - - uoffset_t scratch_size() const - { - return static_cast(scratch_ - buf_); - } - - size_t capacity() const - { - return reserved_; - } - - uint8_t* data() const - { - FLATBUFFERS_ASSERT(cur_); - return cur_; - } - - uint8_t* scratch_data() const - { - FLATBUFFERS_ASSERT(buf_); - return buf_; - } - - uint8_t* scratch_end() const - { - FLATBUFFERS_ASSERT(scratch_); - return scratch_; - } - - uint8_t* data_at(size_t offset) const - { - return buf_ + reserved_ - offset; - } - - void push(const uint8_t* bytes, size_t num) - { - if(num > 0) - { - memcpy(make_space(num), bytes, num); - } - } - - // Specialized version of push() that avoids memcpy call for small data. - template - void push_small(const T& little_endian_t) - { - make_space(sizeof(T)); - *reinterpret_cast(cur_) = little_endian_t; - } - - template - void scratch_push_small(const T& t) - { - ensure_space(sizeof(T)); - *reinterpret_cast(scratch_) = t; - scratch_ += sizeof(T); - } - - // fill() is most frequently called with small byte counts (<= 4), - // which is why we're using loops rather than calling memset. - void fill(size_t zero_pad_bytes) - { - make_space(zero_pad_bytes); - for(size_t i = 0; i < zero_pad_bytes; i++) - cur_[i] = 0; - } - - // Version for when we know the size is larger. - // Precondition: zero_pad_bytes > 0 - void fill_big(size_t zero_pad_bytes) - { - memset(make_space(zero_pad_bytes), 0, zero_pad_bytes); - } - - void pop(size_t bytes_to_remove) - { - cur_ += bytes_to_remove; - } - void scratch_pop(size_t bytes_to_remove) - { - scratch_ -= bytes_to_remove; - } - - void swap(vector_downward& other) - { - using std::swap; - swap(allocator_, other.allocator_); - swap(own_allocator_, other.own_allocator_); - swap(initial_size_, other.initial_size_); - swap(buffer_minalign_, other.buffer_minalign_); - swap(reserved_, other.reserved_); - swap(buf_, other.buf_); - swap(cur_, other.cur_); - swap(scratch_, other.scratch_); - } - - void swap_allocator(vector_downward& other) - { - using std::swap; - swap(allocator_, other.allocator_); - swap(own_allocator_, other.own_allocator_); - } - -private: - // You shouldn't really be copying instances of this class. - FLATBUFFERS_DELETE_FUNC(vector_downward(const vector_downward&)); - FLATBUFFERS_DELETE_FUNC(vector_downward& operator=(const vector_downward&)); - - Allocator* allocator_; - bool own_allocator_; - size_t initial_size_; - size_t buffer_minalign_; - size_t reserved_; - uint8_t* buf_; - uint8_t* cur_; // Points at location between empty (below) and used (above). - uint8_t* scratch_; // Points to the end of the scratchpad in use. - - void reallocate(size_t len) - { - auto old_reserved = reserved_; - auto old_size = size(); - auto old_scratch_size = scratch_size(); - reserved_ += (std::max)(len, old_reserved ? old_reserved / 2 : initial_size_); - reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1); - if(buf_) - { - buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_, old_size, - old_scratch_size); - } - else - { - buf_ = Allocate(allocator_, reserved_); - } - cur_ = buf_ + reserved_ - old_size; - scratch_ = buf_ + old_scratch_size; - } -}; - -// Converts a Field ID to a virtual table offset. -inline voffset_t FieldIndexToOffset(voffset_t field_id) -{ - // Should correspond to what EndTable() below builds up. - const int fixed_fields = 2; // Vtable size and Object Size. - return static_cast((field_id + fixed_fields) * sizeof(voffset_t)); -} - -template -const T* data(const std::vector& v) -{ - // Eventually the returned pointer gets passed down to memcpy, so - // we need it to be non-null to avoid undefined behavior. - static uint8_t t; - return v.empty() ? reinterpret_cast(&t) : &v.front(); -} -template -T* data(std::vector& v) -{ - // Eventually the returned pointer gets passed down to memcpy, so - // we need it to be non-null to avoid undefined behavior. - static uint8_t t; - return v.empty() ? reinterpret_cast(&t) : &v.front(); -} - -/// @endcond - -/// @addtogroup flatbuffers_cpp_api -/// @{ -/// @class FlatBufferBuilder -/// @brief Helper class to hold data needed in creation of a FlatBuffer. -/// To serialize data, you typically call one of the `Create*()` functions in -/// the generated code, which in turn call a sequence of `StartTable`/ -/// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/ -/// `CreateVector` functions. Do this is depth-first order to build up a tree to -/// the root. `Finish()` wraps up the buffer ready for transport. -class FlatBufferBuilder -{ -public: - /// @brief Default constructor for FlatBufferBuilder. - /// @param[in] initial_size The initial size of the buffer, in bytes. Defaults - /// to `1024`. - /// @param[in] allocator An `Allocator` to use. If null will use - /// `DefaultAllocator`. - /// @param[in] own_allocator Whether the builder/vector should own the - /// allocator. Defaults to / `false`. - /// @param[in] buffer_minalign Force the buffer to be aligned to the given - /// minimum alignment upon reallocation. Only needed if you intend to store - /// types with custom alignment AND you wish to read the buffer in-place - /// directly after creation. - explicit FlatBufferBuilder(size_t initial_size = 1024, Allocator* allocator = nullptr, - bool own_allocator = false, - size_t buffer_minalign = AlignOf()) - : buf_(initial_size, allocator, own_allocator, buffer_minalign) - , num_field_loc(0) - , max_voffset_(0) - , nested(false) - , finished(false) - , minalign_(1) - , force_defaults_(false) - , dedup_vtables_(true) - , string_pool(nullptr) - { - EndianCheck(); - } - - // clang-format off - /// @brief Move constructor for FlatBufferBuilder. - #if !defined(FLATBUFFERS_CPP98_STL) - FlatBufferBuilder(FlatBufferBuilder &&other) - #else - FlatBufferBuilder(FlatBufferBuilder &other) - #endif // #if !defined(FLATBUFFERS_CPP98_STL) - : buf_(1024, nullptr, false, AlignOf()), - num_field_loc(0), - max_voffset_(0), - nested(false), - finished(false), - minalign_(1), - force_defaults_(false), - dedup_vtables_(true), - string_pool(nullptr) { - EndianCheck(); - // Default construct and swap idiom. - // Lack of delegating constructors in vs2010 makes it more verbose than needed. - Swap(other); - } - // clang-format on - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - /// @brief Move assignment operator for FlatBufferBuilder. - FlatBufferBuilder& operator=(FlatBufferBuilder&& other) - { - // Move construct a temporary and swap idiom - FlatBufferBuilder temp(std::move(other)); - Swap(temp); - return *this; - } - // clang-format off - #endif // defined(FLATBUFFERS_CPP98_STL) - // clang-format on - - void Swap(FlatBufferBuilder& other) - { - using std::swap; - buf_.swap(other.buf_); - swap(num_field_loc, other.num_field_loc); - swap(max_voffset_, other.max_voffset_); - swap(nested, other.nested); - swap(finished, other.finished); - swap(minalign_, other.minalign_); - swap(force_defaults_, other.force_defaults_); - swap(dedup_vtables_, other.dedup_vtables_); - swap(string_pool, other.string_pool); - } - - ~FlatBufferBuilder() - { - if(string_pool) - delete string_pool; - } - - void Reset() - { - Clear(); // clear builder state - buf_.reset(); // deallocate buffer - } - - /// @brief Reset all the state in this FlatBufferBuilder so it can be reused - /// to construct another buffer. - void Clear() - { - ClearOffsets(); - buf_.clear(); - nested = false; - finished = false; - minalign_ = 1; - if(string_pool) - string_pool->clear(); - } - - /// @brief The current size of the serialized buffer, counting from the end. - /// @return Returns an `uoffset_t` with the current size of the buffer. - uoffset_t GetSize() const - { - return buf_.size(); - } - - /// @brief Get the serialized buffer (after you call `Finish()`). - /// @return Returns an `uint8_t` pointer to the FlatBuffer data inside the - /// buffer. - uint8_t* GetBufferPointer() const - { - Finished(); - return buf_.data(); - } - - /// @brief Get the serialized buffer (after you call `Finish()`) as a span. - /// @return Returns a constructed flatbuffers::span that is a view over the - /// FlatBuffer data inside the buffer. - flatbuffers::span GetBufferSpan() const - { - Finished(); - return flatbuffers::span(buf_.data(), buf_.size()); - } - - /// @brief Get a pointer to an unfinished buffer. - /// @return Returns a `uint8_t` pointer to the unfinished buffer. - uint8_t* GetCurrentBufferPointer() const - { - return buf_.data(); - } - - /// @brief Get the released pointer to the serialized buffer. - /// @warning Do NOT attempt to use this FlatBufferBuilder afterwards! - /// @return A `FlatBuffer` that owns the buffer and its allocator and - /// behaves similar to a `unique_ptr` with a deleter. - FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead")) - DetachedBuffer ReleaseBufferPointer() - { - Finished(); - return buf_.release(); - } - - /// @brief Get the released DetachedBuffer. - /// @return A `DetachedBuffer` that owns the buffer and its allocator. - DetachedBuffer Release() - { - Finished(); - return buf_.release(); - } - - /// @brief Get the released pointer to the serialized buffer. - /// @param size The size of the memory block containing - /// the serialized `FlatBuffer`. - /// @param offset The offset from the released pointer where the finished - /// `FlatBuffer` starts. - /// @return A raw pointer to the start of the memory block containing - /// the serialized `FlatBuffer`. - /// @remark If the allocator is owned, it gets deleted when the destructor is - /// called.. - uint8_t* ReleaseRaw(size_t& size, size_t& offset) - { - Finished(); - return buf_.release_raw(size, offset); - } - - /// @brief get the minimum alignment this buffer needs to be accessed - /// properly. This is only known once all elements have been written (after - /// you call Finish()). You can use this information if you need to embed - /// a FlatBuffer in some other buffer, such that you can later read it - /// without first having to copy it into its own buffer. - size_t GetBufferMinAlignment() const - { - Finished(); - return minalign_; - } - - /// @cond FLATBUFFERS_INTERNAL - void Finished() const - { - // If you get this assert, you're attempting to get access a buffer - // which hasn't been finished yet. Be sure to call - // FlatBufferBuilder::Finish with your root table. - // If you really need to access an unfinished buffer, call - // GetCurrentBufferPointer instead. - FLATBUFFERS_ASSERT(finished); - } - /// @endcond - - /// @brief In order to save space, fields that are set to their default value - /// don't get serialized into the buffer. - /// @param[in] fd When set to `true`, always serializes default values that - /// are set. Optional fields which are not set explicitly, will still not be - /// serialized. - void ForceDefaults(bool fd) - { - force_defaults_ = fd; - } - - /// @brief By default vtables are deduped in order to save space. - /// @param[in] dedup When set to `true`, dedup vtables. - void DedupVtables(bool dedup) - { - dedup_vtables_ = dedup; - } - - /// @cond FLATBUFFERS_INTERNAL - void Pad(size_t num_bytes) - { - buf_.fill(num_bytes); - } - - void TrackMinAlign(size_t elem_size) - { - if(elem_size > minalign_) - minalign_ = elem_size; - } - - void Align(size_t elem_size) - { - TrackMinAlign(elem_size); - buf_.fill(PaddingBytes(buf_.size(), elem_size)); - } - - void PushFlatBuffer(const uint8_t* bytes, size_t size) - { - PushBytes(bytes, size); - finished = true; - } - - void PushBytes(const uint8_t* bytes, size_t size) - { - buf_.push(bytes, size); - } - - void PopBytes(size_t amount) - { - buf_.pop(amount); - } - - template - void AssertScalarT() - { - // The code assumes power of 2 sizes and endian-swap-ability. - static_assert(flatbuffers::is_scalar::value, "T must be a scalar type"); - } - - // Write a single aligned scalar to the buffer - template - uoffset_t PushElement(T element) - { - AssertScalarT(); - T litle_endian_element = EndianScalar(element); - Align(sizeof(T)); - buf_.push_small(litle_endian_element); - return GetSize(); - } - - template - uoffset_t PushElement(Offset off) - { - // Special case for offsets: see ReferTo below. - return PushElement(ReferTo(off.o)); - } - - // When writing fields, we track where they are, so we can create correct - // vtables later. - void TrackField(voffset_t field, uoffset_t off) - { - FieldLoc fl = { off, field }; - buf_.scratch_push_small(fl); - num_field_loc++; - max_voffset_ = (std::max)(max_voffset_, field); - } - - // Like PushElement, but additionally tracks the field this represents. - template - void AddElement(voffset_t field, T e, T def) - { - // We don't serialize values equal to the default. - if(IsTheSameAs(e, def) && !force_defaults_) - return; - auto off = PushElement(e); - TrackField(field, off); - } - - template - void AddElement(voffset_t field, T e) - { - auto off = PushElement(e); - TrackField(field, off); - } - - template - void AddOffset(voffset_t field, Offset off) - { - if(off.IsNull()) - return; // Don't store. - AddElement(field, ReferTo(off.o), static_cast(0)); - } - - template - void AddStruct(voffset_t field, const T* structptr) - { - if(!structptr) - return; // Default, don't store. - Align(AlignOf()); - buf_.push_small(*structptr); - TrackField(field, GetSize()); - } - - void AddStructOffset(voffset_t field, uoffset_t off) - { - TrackField(field, off); - } - - // Offsets initially are relative to the end of the buffer (downwards). - // This function converts them to be relative to the current location - // in the buffer (when stored here), pointing upwards. - uoffset_t ReferTo(uoffset_t off) - { - // Align to ensure GetSize() below is correct. - Align(sizeof(uoffset_t)); - // Offset must refer to something already in buffer. - FLATBUFFERS_ASSERT(off && off <= GetSize()); - return GetSize() - off + static_cast(sizeof(uoffset_t)); - } - - void NotNested() - { - // If you hit this, you're trying to construct a Table/Vector/String - // during the construction of its parent table (between the MyTableBuilder - // and table.Finish(). - // Move the creation of these sub-objects to above the MyTableBuilder to - // not get this assert. - // Ignoring this assert may appear to work in simple cases, but the reason - // it is here is that storing objects in-line may cause vtable offsets - // to not fit anymore. It also leads to vtable duplication. - FLATBUFFERS_ASSERT(!nested); - // If you hit this, fields were added outside the scope of a table. - FLATBUFFERS_ASSERT(!num_field_loc); - } - - // From generated code (or from the parser), we call StartTable/EndTable - // with a sequence of AddElement calls in between. - uoffset_t StartTable() - { - NotNested(); - nested = true; - return GetSize(); - } - - // This finishes one serialized object by generating the vtable if it's a - // table, comparing it against existing vtables, and writing the - // resulting vtable offset. - uoffset_t EndTable(uoffset_t start) - { - // If you get this assert, a corresponding StartTable wasn't called. - FLATBUFFERS_ASSERT(nested); - // Write the vtable offset, which is the start of any Table. - // We fill it's value later. - auto vtableoffsetloc = PushElement(0); - // Write a vtable, which consists entirely of voffset_t elements. - // It starts with the number of offsets, followed by a type id, followed - // by the offsets themselves. In reverse: - // Include space for the last offset and ensure empty tables have a - // minimum size. - max_voffset_ = (std::max)(static_cast(max_voffset_ + sizeof(voffset_t)), - FieldIndexToOffset(0)); - buf_.fill_big(max_voffset_); - auto table_object_size = vtableoffsetloc - start; - // Vtable use 16bit offsets. - FLATBUFFERS_ASSERT(table_object_size < 0x10000); - WriteScalar(buf_.data() + sizeof(voffset_t), - static_cast(table_object_size)); - WriteScalar(buf_.data(), max_voffset_); - // Write the offsets into the table - for(auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc); - it < buf_.scratch_end(); it += sizeof(FieldLoc)) - { - auto field_location = reinterpret_cast(it); - auto pos = static_cast(vtableoffsetloc - field_location->off); - // If this asserts, it means you've set a field twice. - FLATBUFFERS_ASSERT(!ReadScalar(buf_.data() + field_location->id)); - WriteScalar(buf_.data() + field_location->id, pos); - } - ClearOffsets(); - auto vt1 = reinterpret_cast(buf_.data()); - auto vt1_size = ReadScalar(vt1); - auto vt_use = GetSize(); - // See if we already have generated a vtable with this exact same - // layout before. If so, make it point to the old one, remove this one. - if(dedup_vtables_) - { - for(auto it = buf_.scratch_data(); it < buf_.scratch_end(); it += sizeof(uoffset_t)) - { - auto vt_offset_ptr = reinterpret_cast(it); - auto vt2 = reinterpret_cast(buf_.data_at(*vt_offset_ptr)); - auto vt2_size = ReadScalar(vt2); - if(vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) - continue; - vt_use = *vt_offset_ptr; - buf_.pop(GetSize() - vtableoffsetloc); - break; - } - } - // If this is a new vtable, remember it. - if(vt_use == GetSize()) - { - buf_.scratch_push_small(vt_use); - } - // Fill the vtable offset we created above. - // The offset points from the beginning of the object to where the - // vtable is stored. - // Offsets default direction is downward in memory for future format - // flexibility (storing all vtables at the start of the file). - WriteScalar(buf_.data_at(vtableoffsetloc), - static_cast(vt_use) - static_cast(vtableoffsetloc)); - - nested = false; - return vtableoffsetloc; - } - - FLATBUFFERS_ATTRIBUTE(deprecated("call the version above instead")) - uoffset_t EndTable(uoffset_t start, voffset_t /*numfields*/) - { - return EndTable(start); - } - - // This checks a required field has been set in a given table that has - // just been constructed. - template - void Required(Offset table, voffset_t field); - - uoffset_t StartStruct(size_t alignment) - { - Align(alignment); - return GetSize(); - } - - uoffset_t EndStruct() - { - return GetSize(); - } - - void ClearOffsets() - { - buf_.scratch_pop(num_field_loc * sizeof(FieldLoc)); - num_field_loc = 0; - max_voffset_ = 0; - } - - // Aligns such that when "len" bytes are written, an object can be written - // after it with "alignment" without padding. - void PreAlign(size_t len, size_t alignment) - { - TrackMinAlign(alignment); - buf_.fill(PaddingBytes(GetSize() + len, alignment)); - } - template - void PreAlign(size_t len) - { - AssertScalarT(); - PreAlign(len, sizeof(T)); - } - /// @endcond - - /// @brief Store a string in the buffer, which can contain any binary data. - /// @param[in] str A const char pointer to the data to be stored as a string. - /// @param[in] len The number of bytes that should be stored from `str`. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const char* str, size_t len) - { - NotNested(); - PreAlign(len + 1); // Always 0-terminated. - buf_.fill(1); - PushBytes(reinterpret_cast(str), len); - PushElement(static_cast(len)); - return Offset(GetSize()); - } - - /// @brief Store a string in the buffer, which is null-terminated. - /// @param[in] str A const char pointer to a C-string to add to the buffer. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const char* str) - { - return CreateString(str, strlen(str)); - } - - /// @brief Store a string in the buffer, which is null-terminated. - /// @param[in] str A char pointer to a C-string to add to the buffer. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(char* str) - { - return CreateString(str, strlen(str)); - } - - /// @brief Store a string in the buffer, which can contain any binary data. - /// @param[in] str A const reference to a std::string to store in the buffer. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const std::string& str) - { - return CreateString(str.c_str(), str.length()); - } - - // clang-format off - #ifdef FLATBUFFERS_HAS_STRING_VIEW - /// @brief Store a string in the buffer, which can contain any binary data. - /// @param[in] str A const string_view to copy in to the buffer. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(flatbuffers::string_view str) { - return CreateString(str.data(), str.size()); - } - #endif // FLATBUFFERS_HAS_STRING_VIEW - // clang-format on - - /// @brief Store a string in the buffer, which can contain any binary data. - /// @param[in] str A const pointer to a `String` struct to add to the buffer. - /// @return Returns the offset in the buffer where the string starts - Offset CreateString(const String* str) - { - return str ? CreateString(str->c_str(), str->size()) : 0; - } - - /// @brief Store a string in the buffer, which can contain any binary data. - /// @param[in] str A const reference to a std::string like type with support - /// of T::c_str() and T::length() to store in the buffer. - /// @return Returns the offset in the buffer where the string starts. - template - Offset CreateString(const T& str) - { - return CreateString(str.c_str(), str.length()); - } - - /// @brief Store a string in the buffer, which can contain any binary data. - /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. - /// @param[in] str A const char pointer to the data to be stored as a string. - /// @param[in] len The number of bytes that should be stored from `str`. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateSharedString(const char* str, size_t len) - { - if(!string_pool) - string_pool = new StringOffsetMap(StringOffsetCompare(buf_)); - auto size_before_string = buf_.size(); - // Must first serialize the string, since the set is all offsets into - // buffer. - auto off = CreateString(str, len); - auto it = string_pool->find(off); - // If it exists we reuse existing serialized data! - if(it != string_pool->end()) - { - // We can remove the string we serialized. - buf_.pop(buf_.size() - size_before_string); - return *it; - } - // Record this string for future use. - string_pool->insert(off); - return off; - } - -#ifdef FLATBUFFERS_HAS_STRING_VIEW - /// @brief Store a string in the buffer, which can contain any binary data. - /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. - /// @param[in] str A const std::string_view to store in the buffer. - /// @return Returns the offset in the buffer where the string starts - Offset CreateSharedString(const flatbuffers::string_view str) - { - return CreateSharedString(str.data(), str.size()); - } -#else - /// @brief Store a string in the buffer, which null-terminated. - /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. - /// @param[in] str A const char pointer to a C-string to add to the buffer. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateSharedString(const char* str) - { - return CreateSharedString(str, strlen(str)); - } - - /// @brief Store a string in the buffer, which can contain any binary data. - /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. - /// @param[in] str A const reference to a std::string to store in the buffer. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateSharedString(const std::string& str) - { - return CreateSharedString(str.c_str(), str.length()); - } -#endif - - /// @brief Store a string in the buffer, which can contain any binary data. - /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. - /// @param[in] str A const pointer to a `String` struct to add to the buffer. - /// @return Returns the offset in the buffer where the string starts - Offset CreateSharedString(const String* str) - { - return CreateSharedString(str->c_str(), str->size()); - } - - /// @cond FLATBUFFERS_INTERNAL - uoffset_t EndVector(size_t len) - { - FLATBUFFERS_ASSERT(nested); // Hit if no corresponding StartVector. - nested = false; - return PushElement(static_cast(len)); - } - - void StartVector(size_t len, size_t elemsize) - { - NotNested(); - nested = true; - PreAlign(len * elemsize); - PreAlign(len * elemsize, elemsize); // Just in case elemsize > uoffset_t. - } - - // Call this right before StartVector/CreateVector if you want to force the - // alignment to be something different than what the element size would - // normally dictate. - // This is useful when storing a nested_flatbuffer in a vector of bytes, - // or when storing SIMD floats, etc. - void ForceVectorAlignment(size_t len, size_t elemsize, size_t alignment) - { - FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment)); - PreAlign(len * elemsize, alignment); - } - - // Similar to ForceVectorAlignment but for String fields. - void ForceStringAlignment(size_t len, size_t alignment) - { - FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment)); - PreAlign((len + 1) * sizeof(char), alignment); - } - - /// @endcond - - /// @brief Serialize an array into a FlatBuffer `vector`. - /// @tparam T The data type of the array elements. - /// @param[in] v A pointer to the array of type `T` to serialize into the - /// buffer as a `vector`. - /// @param[in] len The number of elements to serialize. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVector(const T* v, size_t len) - { - // If this assert hits, you're specifying a template argument that is - // causing the wrong overload to be selected, remove it. - AssertScalarT(); - StartVector(len, sizeof(T)); - if(len == 0) - { - return Offset>(EndVector(len)); - } - // clang-format off - #if FLATBUFFERS_LITTLEENDIAN - PushBytes(reinterpret_cast(v), len * sizeof(T)); - #else - if (sizeof(T) == 1) { - PushBytes(reinterpret_cast(v), len); - } else { - for (auto i = len; i > 0; ) { - PushElement(v[--i]); - } - } - #endif - // clang-format on - return Offset>(EndVector(len)); - } - - template - Offset>> CreateVector(const Offset* v, size_t len) - { - StartVector(len, sizeof(Offset)); - for(auto i = len; i > 0;) - { - PushElement(v[--i]); - } - return Offset>>(EndVector(len)); - } - - /// @brief Serialize a `std::vector` into a FlatBuffer `vector`. - /// @tparam T The data type of the `std::vector` elements. - /// @param v A const reference to the `std::vector` to serialize into the - /// buffer as a `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVector(const std::vector& v) - { - return CreateVector(data(v), v.size()); - } - - // vector may be implemented using a bit-set, so we can't access it as - // an array. Instead, read elements manually. - // Background: https://isocpp.org/blog/2012/11/on-vectorbool - Offset> CreateVector(const std::vector& v) - { - StartVector(v.size(), sizeof(uint8_t)); - for(auto i = v.size(); i > 0;) - { - PushElement(static_cast(v[--i])); - } - return Offset>(EndVector(v.size())); - } - - // clang-format off - #ifndef FLATBUFFERS_CPP98_STL - /// @brief Serialize values returned by a function into a FlatBuffer `vector`. - /// This is a convenience function that takes care of iteration for you. - /// @tparam T The data type of the `std::vector` elements. - /// @param f A function that takes the current iteration 0..vector_size-1 and - /// returns any type that you can construct a FlatBuffers vector out of. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template Offset> CreateVector(size_t vector_size, - const std::function &f) { - std::vector elems(vector_size); - for (size_t i = 0; i < vector_size; i++) elems[i] = f(i); - return CreateVector(elems); - } - #endif - // clang-format on - - /// @brief Serialize values returned by a function into a FlatBuffer `vector`. - /// This is a convenience function that takes care of iteration for you. - /// @tparam T The data type of the `std::vector` elements. - /// @param f A function that takes the current iteration 0..vector_size-1, - /// and the state parameter returning any type that you can construct a - /// FlatBuffers vector out of. - /// @param state State passed to f. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVector(size_t vector_size, F f, S* state) - { - std::vector elems(vector_size); - for(size_t i = 0; i < vector_size; i++) - elems[i] = f(i, state); - return CreateVector(elems); - } - - /// @brief Serialize a `std::vector` into a FlatBuffer `vector`. - /// This is a convenience function for a common case. - /// @param v A const reference to the `std::vector` to serialize into the - /// buffer as a `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - Offset>> CreateVectorOfStrings(const std::vector& v) - { - std::vector> offsets(v.size()); - for(size_t i = 0; i < v.size(); i++) - offsets[i] = CreateString(v[i]); - return CreateVector(offsets); - } - - /// @brief Serialize an array of structs into a FlatBuffer `vector`. - /// @tparam T The data type of the struct array elements. - /// @param[in] v A pointer to the array of type `T` to serialize into the - /// buffer as a `vector`. - /// @param[in] len The number of elements to serialize. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfStructs(const T* v, size_t len) - { - StartVector(len * sizeof(T) / AlignOf(), AlignOf()); - PushBytes(reinterpret_cast(v), sizeof(T) * len); - return Offset>(EndVector(len)); - } - - /// @brief Serialize an array of native structs into a FlatBuffer `vector`. - /// @tparam T The data type of the struct array elements. - /// @tparam S The data type of the native struct array elements. - /// @param[in] v A pointer to the array of type `S` to serialize into the - /// buffer as a `vector`. - /// @param[in] len The number of elements to serialize. - /// @param[in] pack_func Pointer to a function to convert the native struct - /// to the FlatBuffer struct. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfNativeStructs(const S* v, size_t len, - T((*const pack_func)(const S&))) - { - FLATBUFFERS_ASSERT(pack_func); - std::vector vv(len); - std::transform(v, v + len, vv.begin(), pack_func); - return CreateVectorOfStructs(data(vv), vv.size()); - } - - /// @brief Serialize an array of native structs into a FlatBuffer `vector`. - /// @tparam T The data type of the struct array elements. - /// @tparam S The data type of the native struct array elements. - /// @param[in] v A pointer to the array of type `S` to serialize into the - /// buffer as a `vector`. - /// @param[in] len The number of elements to serialize. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfNativeStructs(const S* v, size_t len) - { - extern T Pack(const S&); - return CreateVectorOfNativeStructs(v, len, Pack); - } - - // clang-format off - #ifndef FLATBUFFERS_CPP98_STL - /// @brief Serialize an array of structs into a FlatBuffer `vector`. - /// @tparam T The data type of the struct array elements. - /// @param[in] filler A function that takes the current iteration 0..vector_size-1 - /// and a pointer to the struct that must be filled. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - /// This is mostly useful when flatbuffers are generated with mutation - /// accessors. - template Offset> CreateVectorOfStructs( - size_t vector_size, const std::function &filler) { - T* structs = StartVectorOfStructs(vector_size); - for (size_t i = 0; i < vector_size; i++) { - filler(i, structs); - structs++; - } - return EndVectorOfStructs(vector_size); - } - #endif - // clang-format on - - /// @brief Serialize an array of structs into a FlatBuffer `vector`. - /// @tparam T The data type of the struct array elements. - /// @param[in] f A function that takes the current iteration 0..vector_size-1, - /// a pointer to the struct that must be filled and the state argument. - /// @param[in] state Arbitrary state to pass to f. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - /// This is mostly useful when flatbuffers are generated with mutation - /// accessors. - template - Offset> CreateVectorOfStructs(size_t vector_size, F f, S* state) - { - T* structs = StartVectorOfStructs(vector_size); - for(size_t i = 0; i < vector_size; i++) - { - f(i, structs, state); - structs++; - } - return EndVectorOfStructs(vector_size); - } - - /// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`. - /// @tparam T The data type of the `std::vector` struct elements. - /// @param[in] v A const reference to the `std::vector` of structs to - /// serialize into the buffer as a `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfStructs(const std::vector& v) - { - return CreateVectorOfStructs(data(v), v.size()); - } - - /// @brief Serialize a `std::vector` of native structs into a FlatBuffer - /// `vector`. - /// @tparam T The data type of the `std::vector` struct elements. - /// @tparam S The data type of the `std::vector` native struct elements. - /// @param[in] v A const reference to the `std::vector` of structs to - /// serialize into the buffer as a `vector`. - /// @param[in] pack_func Pointer to a function to convert the native struct - /// to the FlatBuffer struct. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfNativeStructs(const std::vector& v, - T((*const pack_func)(const S&))) - { - return CreateVectorOfNativeStructs(data(v), v.size(), pack_func); - } - - /// @brief Serialize a `std::vector` of native structs into a FlatBuffer - /// `vector`. - /// @tparam T The data type of the `std::vector` struct elements. - /// @tparam S The data type of the `std::vector` native struct elements. - /// @param[in] v A const reference to the `std::vector` of structs to - /// serialize into the buffer as a `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfNativeStructs(const std::vector& v) - { - return CreateVectorOfNativeStructs(data(v), v.size()); - } - - /// @cond FLATBUFFERS_INTERNAL - template - struct StructKeyComparator - { - bool operator()(const T& a, const T& b) const - { - return a.KeyCompareLessThan(&b); - } - - FLATBUFFERS_DELETE_FUNC(StructKeyComparator& operator=(const StructKeyComparator&)); - }; - /// @endcond - - /// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector` - /// in sorted order. - /// @tparam T The data type of the `std::vector` struct elements. - /// @param[in] v A const reference to the `std::vector` of structs to - /// serialize into the buffer as a `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfSortedStructs(std::vector* v) - { - return CreateVectorOfSortedStructs(data(*v), v->size()); - } - - /// @brief Serialize a `std::vector` of native structs into a FlatBuffer - /// `vector` in sorted order. - /// @tparam T The data type of the `std::vector` struct elements. - /// @tparam S The data type of the `std::vector` native struct elements. - /// @param[in] v A const reference to the `std::vector` of structs to - /// serialize into the buffer as a `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfSortedNativeStructs(std::vector* v) - { - return CreateVectorOfSortedNativeStructs(data(*v), v->size()); - } - - /// @brief Serialize an array of structs into a FlatBuffer `vector` in sorted - /// order. - /// @tparam T The data type of the struct array elements. - /// @param[in] v A pointer to the array of type `T` to serialize into the - /// buffer as a `vector`. - /// @param[in] len The number of elements to serialize. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfSortedStructs(T* v, size_t len) - { - std::sort(v, v + len, StructKeyComparator()); - return CreateVectorOfStructs(v, len); - } - - /// @brief Serialize an array of native structs into a FlatBuffer `vector` in - /// sorted order. - /// @tparam T The data type of the struct array elements. - /// @tparam S The data type of the native struct array elements. - /// @param[in] v A pointer to the array of type `S` to serialize into the - /// buffer as a `vector`. - /// @param[in] len The number of elements to serialize. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfSortedNativeStructs(S* v, size_t len) - { - extern T Pack(const S&); - typedef T (*Pack_t)(const S&); - std::vector vv(len); - std::transform(v, v + len, vv.begin(), static_cast(Pack)); - return CreateVectorOfSortedStructs(vv, len); - } - - /// @cond FLATBUFFERS_INTERNAL - template - struct TableKeyComparator - { - TableKeyComparator(vector_downward& buf) : buf_(buf) - {} - TableKeyComparator(const TableKeyComparator& other) : buf_(other.buf_) - {} - bool operator()(const Offset& a, const Offset& b) const - { - auto table_a = reinterpret_cast(buf_.data_at(a.o)); - auto table_b = reinterpret_cast(buf_.data_at(b.o)); - return table_a->KeyCompareLessThan(table_b); - } - vector_downward& buf_; - - private: - FLATBUFFERS_DELETE_FUNC( - TableKeyComparator& operator=(const TableKeyComparator& other)); - }; - /// @endcond - - /// @brief Serialize an array of `table` offsets as a `vector` in the buffer - /// in sorted order. - /// @tparam T The data type that the offset refers to. - /// @param[in] v An array of type `Offset` that contains the `table` - /// offsets to store in the buffer in sorted order. - /// @param[in] len The number of elements to store in the `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset>> CreateVectorOfSortedTables(Offset* v, size_t len) - { - std::sort(v, v + len, TableKeyComparator(buf_)); - return CreateVector(v, len); - } - - /// @brief Serialize an array of `table` offsets as a `vector` in the buffer - /// in sorted order. - /// @tparam T The data type that the offset refers to. - /// @param[in] v An array of type `Offset` that contains the `table` - /// offsets to store in the buffer in sorted order. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset>> CreateVectorOfSortedTables(std::vector>* v) - { - return CreateVectorOfSortedTables(data(*v), v->size()); - } - - /// @brief Specialized version of `CreateVector` for non-copying use cases. - /// Write the data any time later to the returned buffer pointer `buf`. - /// @param[in] len The number of elements to store in the `vector`. - /// @param[in] elemsize The size of each element in the `vector`. - /// @param[out] buf A pointer to a `uint8_t` pointer that can be - /// written to at a later time to serialize the data into a `vector` - /// in the buffer. - uoffset_t CreateUninitializedVector(size_t len, size_t elemsize, uint8_t** buf) - { - NotNested(); - StartVector(len, elemsize); - buf_.make_space(len * elemsize); - auto vec_start = GetSize(); - auto vec_end = EndVector(len); - *buf = buf_.data_at(vec_start); - return vec_end; - } - - /// @brief Specialized version of `CreateVector` for non-copying use cases. - /// Write the data any time later to the returned buffer pointer `buf`. - /// @tparam T The data type of the data that will be stored in the buffer - /// as a `vector`. - /// @param[in] len The number of elements to store in the `vector`. - /// @param[out] buf A pointer to a pointer of type `T` that can be - /// written to at a later time to serialize the data into a `vector` - /// in the buffer. - template - Offset> CreateUninitializedVector(size_t len, T** buf) - { - AssertScalarT(); - return CreateUninitializedVector(len, sizeof(T), reinterpret_cast(buf)); - } - - template - Offset> CreateUninitializedVectorOfStructs(size_t len, T** buf) - { - return CreateUninitializedVector(len, sizeof(T), reinterpret_cast(buf)); - } - - // @brief Create a vector of scalar type T given as input a vector of scalar - // type U, useful with e.g. pre "enum class" enums, or any existing scalar - // data of the wrong type. - template - Offset> CreateVectorScalarCast(const U* v, size_t len) - { - AssertScalarT(); - AssertScalarT(); - StartVector(len, sizeof(T)); - for(auto i = len; i > 0;) - { - PushElement(static_cast(v[--i])); - } - return Offset>(EndVector(len)); - } - - /// @brief Write a struct by itself, typically to be part of a union. - template - Offset CreateStruct(const T& structobj) - { - NotNested(); - Align(AlignOf()); - buf_.push_small(structobj); - return Offset(GetSize()); - } - - /// @brief The length of a FlatBuffer file header. - static const size_t kFileIdentifierLength = 4; - - /// @brief Finish serializing a buffer by writing the root offset. - /// @param[in] file_identifier If a `file_identifier` is given, the buffer - /// will be prefixed with a standard FlatBuffers file header. - template - void Finish(Offset root, const char* file_identifier = nullptr) - { - Finish(root.o, file_identifier, false); - } - - /// @brief Finish a buffer with a 32 bit size field pre-fixed (size of the - /// buffer following the size field). These buffers are NOT compatible - /// with standard buffers created by Finish, i.e. you can't call GetRoot - /// on them, you have to use GetSizePrefixedRoot instead. - /// All >32 bit quantities in this buffer will be aligned when the whole - /// size pre-fixed buffer is aligned. - /// These kinds of buffers are useful for creating a stream of FlatBuffers. - template - void FinishSizePrefixed(Offset root, const char* file_identifier = nullptr) - { - Finish(root.o, file_identifier, true); - } - - void SwapBufAllocator(FlatBufferBuilder& other) - { - buf_.swap_allocator(other.buf_); - } - -protected: - // You shouldn't really be copying instances of this class. - FlatBufferBuilder(const FlatBufferBuilder&); - FlatBufferBuilder& operator=(const FlatBufferBuilder&); - - void Finish(uoffset_t root, const char* file_identifier, bool size_prefix) - { - NotNested(); - buf_.clear_scratch(); - // This will cause the whole buffer to be aligned. - PreAlign((size_prefix ? sizeof(uoffset_t) : 0) + sizeof(uoffset_t) + - (file_identifier ? kFileIdentifierLength : 0), - minalign_); - if(file_identifier) - { - FLATBUFFERS_ASSERT(strlen(file_identifier) == kFileIdentifierLength); - PushBytes(reinterpret_cast(file_identifier), kFileIdentifierLength); - } - PushElement(ReferTo(root)); // Location of root. - if(size_prefix) - { - PushElement(GetSize()); - } - finished = true; - } - - struct FieldLoc - { - uoffset_t off; - voffset_t id; - }; - - vector_downward buf_; - - // Accumulating offsets of table members while it is being built. - // We store these in the scratch pad of buf_, after the vtable offsets. - uoffset_t num_field_loc; - // Track how much of the vtable is in use, so we can output the most compact - // possible vtable. - voffset_t max_voffset_; - - // Ensure objects are not nested. - bool nested; - - // Ensure the buffer is finished before it is being accessed. - bool finished; - - size_t minalign_; - - bool force_defaults_; // Serialize values equal to their defaults anyway. - - bool dedup_vtables_; - - struct StringOffsetCompare - { - StringOffsetCompare(const vector_downward& buf) : buf_(&buf) - {} - bool operator()(const Offset& a, const Offset& b) const - { - auto stra = reinterpret_cast(buf_->data_at(a.o)); - auto strb = reinterpret_cast(buf_->data_at(b.o)); - return StringLessThan(stra->data(), stra->size(), strb->data(), strb->size()); - } - const vector_downward* buf_; - }; - - // For use with CreateSharedString. Instantiated on first use only. - typedef std::set, StringOffsetCompare> StringOffsetMap; - StringOffsetMap* string_pool; - -private: - // Allocates space for a vector of structures. - // Must be completed with EndVectorOfStructs(). - template - T* StartVectorOfStructs(size_t vector_size) - { - StartVector(vector_size * sizeof(T) / AlignOf(), AlignOf()); - return reinterpret_cast(buf_.make_space(vector_size * sizeof(T))); - } - - // End the vector of structues in the flatbuffers. - // Vector should have previously be started with StartVectorOfStructs(). - template - Offset> EndVectorOfStructs(size_t vector_size) - { - return Offset>(EndVector(vector_size)); - } -}; -/// @} - -/// @cond FLATBUFFERS_INTERNAL -// Helpers to get a typed pointer to the root object contained in the buffer. -template -T* GetMutableRoot(void* buf) -{ - EndianCheck(); - return reinterpret_cast(reinterpret_cast(buf) + - EndianScalar(*reinterpret_cast(buf))); -} - -template -const T* GetRoot(const void* buf) -{ - return GetMutableRoot(const_cast(buf)); -} - -template -const T* GetSizePrefixedRoot(const void* buf) -{ - return GetRoot(reinterpret_cast(buf) + sizeof(uoffset_t)); -} - -/// Helpers to get a typed pointer to objects that are currently being built. -/// @warning Creating new objects will lead to reallocations and invalidates -/// the pointer! -template -T* GetMutableTemporaryPointer(FlatBufferBuilder& fbb, Offset offset) -{ - return reinterpret_cast(fbb.GetCurrentBufferPointer() + fbb.GetSize() - offset.o); -} - -template -const T* GetTemporaryPointer(FlatBufferBuilder& fbb, Offset offset) -{ - return GetMutableTemporaryPointer(fbb, offset); -} - -/// @brief Get a pointer to the the file_identifier section of the buffer. -/// @return Returns a const char pointer to the start of the file_identifier -/// characters in the buffer. The returned char * has length -/// 'flatbuffers::FlatBufferBuilder::kFileIdentifierLength'. -/// This function is UNDEFINED for FlatBuffers whose schema does not include -/// a file_identifier (likely points at padding or the start of a the root -/// vtable). -inline const char* GetBufferIdentifier(const void* buf, bool size_prefixed = false) -{ - return reinterpret_cast(buf) + - ((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t)); -} - -// Helper to see if the identifier in a buffer has the expected value. -inline bool BufferHasIdentifier(const void* buf, const char* identifier, - bool size_prefixed = false) -{ - return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier, - FlatBufferBuilder::kFileIdentifierLength) == 0; -} - -// Helper class to verify the integrity of a FlatBuffer -class Verifier FLATBUFFERS_FINAL_CLASS -{ -public: - Verifier(const uint8_t* buf, size_t buf_len, uoffset_t _max_depth = 64, - uoffset_t _max_tables = 1000000, bool _check_alignment = true) - : buf_(buf) - , size_(buf_len) - , depth_(0) - , max_depth_(_max_depth) - , num_tables_(0) - , max_tables_(_max_tables) - , upper_bound_(0) - , check_alignment_(_check_alignment) - { - FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE); - } - - // Central location where any verification failures register. - bool Check(bool ok) const - { - // clang-format off - #ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE - FLATBUFFERS_ASSERT(ok); - #endif - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - if (!ok) - upper_bound_ = 0; - #endif - // clang-format on - return ok; - } - - // Verify any range within the buffer. - bool Verify(size_t elem, size_t elem_len) const - { - // clang-format off - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - auto upper_bound = elem + elem_len; - if (upper_bound_ < upper_bound) - upper_bound_ = upper_bound; - #endif - // clang-format on - return Check(elem_len < size_ && elem <= size_ - elem_len); - } - - template - bool VerifyAlignment(size_t elem) const - { - return Check((elem & (sizeof(T) - 1)) == 0 || !check_alignment_); - } - - // Verify a range indicated by sizeof(T). - template - bool Verify(size_t elem) const - { - return VerifyAlignment(elem) && Verify(elem, sizeof(T)); - } - - bool VerifyFromPointer(const uint8_t* p, size_t len) - { - auto o = static_cast(p - buf_); - return Verify(o, len); - } - - // Verify relative to a known-good base pointer. - bool Verify(const uint8_t* base, voffset_t elem_off, size_t elem_len) const - { - return Verify(static_cast(base - buf_) + elem_off, elem_len); - } - - template - bool Verify(const uint8_t* base, voffset_t elem_off) const - { - return Verify(static_cast(base - buf_) + elem_off, sizeof(T)); - } - - // Verify a pointer (may be NULL) of a table type. - template - bool VerifyTable(const T* table) - { - return !table || table->Verify(*this); - } - - // Verify a pointer (may be NULL) of any vector type. - template - bool VerifyVector(const Vector* vec) const - { - return !vec || VerifyVectorOrString(reinterpret_cast(vec), sizeof(T)); - } - - // Verify a pointer (may be NULL) of a vector to struct. - template - bool VerifyVector(const Vector* vec) const - { - return VerifyVector(reinterpret_cast*>(vec)); - } - - // Verify a pointer (may be NULL) to string. - bool VerifyString(const String* str) const - { - size_t end; - return !str || - (VerifyVectorOrString(reinterpret_cast(str), 1, &end) && - Verify(end, 1) && // Must have terminator - Check(buf_[end] == '\0')); // Terminating byte must be 0. - } - - // Common code between vectors and strings. - bool VerifyVectorOrString(const uint8_t* vec, size_t elem_size, - size_t* end = nullptr) const - { - auto veco = static_cast(vec - buf_); - // Check we can read the size field. - if(!Verify(veco)) - return false; - // Check the whole array. If this is a string, the byte past the array - // must be 0. - auto size = ReadScalar(vec); - auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size; - if(!Check(size < max_elems)) - return false; // Protect against byte_size overflowing. - auto byte_size = sizeof(size) + elem_size * size; - if(end) - *end = veco + byte_size; - return Verify(veco, byte_size); - } - - // Special case for string contents, after the above has been called. - bool VerifyVectorOfStrings(const Vector>* vec) const - { - if(vec) - { - for(uoffset_t i = 0; i < vec->size(); i++) - { - if(!VerifyString(vec->Get(i))) - return false; - } - } - return true; - } - - // Special case for table contents, after the above has been called. - template - bool VerifyVectorOfTables(const Vector>* vec) - { - if(vec) - { - for(uoffset_t i = 0; i < vec->size(); i++) - { - if(!vec->Get(i)->Verify(*this)) - return false; - } - } - return true; - } - - __supress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart( - const uint8_t* table) - { - // Check the vtable offset. - auto tableo = static_cast(table - buf_); - if(!Verify(tableo)) - return false; - // This offset may be signed, but doing the subtraction unsigned always - // gives the result we want. - auto vtableo = tableo - static_cast(ReadScalar(table)); - // Check the vtable size field, then check vtable fits in its entirety. - return VerifyComplexity() && Verify(vtableo) && - VerifyAlignment(ReadScalar(buf_ + vtableo)) && - Verify(vtableo, ReadScalar(buf_ + vtableo)); - } - - template - bool VerifyBufferFromStart(const char* identifier, size_t start) - { - if(identifier && !Check((size_ >= 2 * sizeof(flatbuffers::uoffset_t) && - BufferHasIdentifier(buf_ + start, identifier)))) - { - return false; - } - - // Call T::Verify, which must be in the generated code for this type. - auto o = VerifyOffset(start); - return o && reinterpret_cast(buf_ + start + o)->Verify(*this) - // clang-format off - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - && GetComputedSize() - #endif - ; - // clang-format on - } - - // Verify this whole buffer, starting with root type T. - template - bool VerifyBuffer() - { - return VerifyBuffer(nullptr); - } - - template - bool VerifyBuffer(const char* identifier) - { - return VerifyBufferFromStart(identifier, 0); - } - - template - bool VerifySizePrefixedBuffer(const char* identifier) - { - return Verify(0U) && - ReadScalar(buf_) == size_ - sizeof(uoffset_t) && - VerifyBufferFromStart(identifier, sizeof(uoffset_t)); - } - - uoffset_t VerifyOffset(size_t start) const - { - if(!Verify(start)) - return 0; - auto o = ReadScalar(buf_ + start); - // May not point to itself. - if(!Check(o != 0)) - return 0; - // Can't wrap around / buffers are max 2GB. - if(!Check(static_cast(o) >= 0)) - return 0; - // Must be inside the buffer to create a pointer from it (pointer outside - // buffer is UB). - if(!Verify(start + o, 1)) - return 0; - return o; - } - - uoffset_t VerifyOffset(const uint8_t* base, voffset_t start) const - { - return VerifyOffset(static_cast(base - buf_) + start); - } - - // Called at the start of a table to increase counters measuring data - // structure depth and amount, and possibly bails out with false if - // limits set by the constructor have been hit. Needs to be balanced - // with EndTable(). - bool VerifyComplexity() - { - depth_++; - num_tables_++; - return Check(depth_ <= max_depth_ && num_tables_ <= max_tables_); - } - - // Called at the end of a table to pop the depth count. - bool EndTable() - { - depth_--; - return true; - } - - // Returns the message size in bytes - size_t GetComputedSize() const - { - // clang-format off - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - uintptr_t size = upper_bound_; - // Align the size to uoffset_t - size = (size - 1 + sizeof(uoffset_t)) & ~(sizeof(uoffset_t) - 1); - return (size > size_) ? 0 : size; - #else - // Must turn on FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE for this to work. - (void)upper_bound_; - FLATBUFFERS_ASSERT(false); - return 0; - #endif - // clang-format on - } - -private: - const uint8_t* buf_; - size_t size_; - uoffset_t depth_; - uoffset_t max_depth_; - uoffset_t num_tables_; - uoffset_t max_tables_; - mutable size_t upper_bound_; - bool check_alignment_; -}; - -// Convenient way to bundle a buffer and its length, to pass it around -// typed by its root. -// A BufferRef does not own its buffer. -struct BufferRefBase -{ -}; // for std::is_base_of -template -struct BufferRef : BufferRefBase -{ - BufferRef() : buf(nullptr), len(0), must_free(false) - {} - BufferRef(uint8_t* _buf, uoffset_t _len) : buf(_buf), len(_len), must_free(false) - {} - - ~BufferRef() - { - if(must_free) - free(buf); - } - - const T* GetRoot() const - { - return flatbuffers::GetRoot(buf); - } - - bool Verify() - { - Verifier verifier(buf, len); - return verifier.VerifyBuffer(nullptr); - } - - uint8_t* buf; - uoffset_t len; - bool must_free; -}; - -// "structs" are flat structures that do not have an offset table, thus -// always have all members present and do not support forwards/backwards -// compatible extensions. - -class Struct FLATBUFFERS_FINAL_CLASS -{ -public: - template - T GetField(uoffset_t o) const - { - return ReadScalar(&data_[o]); - } - - template - T GetStruct(uoffset_t o) const - { - return reinterpret_cast(&data_[o]); - } - - const uint8_t* GetAddressOf(uoffset_t o) const - { - return &data_[o]; - } - uint8_t* GetAddressOf(uoffset_t o) - { - return &data_[o]; - } - -private: - // private constructor & copy constructor: you obtain instances of this - // class by pointing to existing data only - Struct(); - Struct(const Struct&); - Struct& operator=(const Struct&); - - uint8_t data_[1]; -}; - -// "tables" use an offset table (possibly shared) that allows fields to be -// omitted and added at will, but uses an extra indirection to read. -class Table -{ -public: - const uint8_t* GetVTable() const - { - return data_ - ReadScalar(data_); - } - - // This gets the field offset for any of the functions below it, or 0 - // if the field was not present. - voffset_t GetOptionalFieldOffset(voffset_t field) const - { - // The vtable offset is always at the start. - auto vtable = GetVTable(); - // The first element is the size of the vtable (fields + type id + itself). - auto vtsize = ReadScalar(vtable); - // If the field we're accessing is outside the vtable, we're reading older - // data, so it's the same as if the offset was 0 (not present). - return field < vtsize ? ReadScalar(vtable + field) : 0; - } - - template - T GetField(voffset_t field, T defaultval) const - { - auto field_offset = GetOptionalFieldOffset(field); - return field_offset ? ReadScalar(data_ + field_offset) : defaultval; - } - - template - P GetPointer(voffset_t field) - { - auto field_offset = GetOptionalFieldOffset(field); - auto p = data_ + field_offset; - return field_offset ? reinterpret_cast

(p + ReadScalar(p)) : nullptr; - } - template - P GetPointer(voffset_t field) const - { - return const_cast(this)->GetPointer

(field); - } - - template - P GetStruct(voffset_t field) const - { - auto field_offset = GetOptionalFieldOffset(field); - auto p = const_cast(data_ + field_offset); - return field_offset ? reinterpret_cast

(p) : nullptr; - } - - template - flatbuffers::Optional GetOptional(voffset_t field) const - { - auto field_offset = GetOptionalFieldOffset(field); - auto p = data_ + field_offset; - return field_offset ? Optional(static_cast(ReadScalar(p))) : - Optional(); - } - - template - bool SetField(voffset_t field, T val, T def) - { - auto field_offset = GetOptionalFieldOffset(field); - if(!field_offset) - return IsTheSameAs(val, def); - WriteScalar(data_ + field_offset, val); - return true; - } - template - bool SetField(voffset_t field, T val) - { - auto field_offset = GetOptionalFieldOffset(field); - if(!field_offset) - return false; - WriteScalar(data_ + field_offset, val); - return true; - } - - bool SetPointer(voffset_t field, const uint8_t* val) - { - auto field_offset = GetOptionalFieldOffset(field); - if(!field_offset) - return false; - WriteScalar(data_ + field_offset, - static_cast(val - (data_ + field_offset))); - return true; - } - - uint8_t* GetAddressOf(voffset_t field) - { - auto field_offset = GetOptionalFieldOffset(field); - return field_offset ? data_ + field_offset : nullptr; - } - const uint8_t* GetAddressOf(voffset_t field) const - { - return const_cast(this)->GetAddressOf(field); - } - - bool CheckField(voffset_t field) const - { - return GetOptionalFieldOffset(field) != 0; - } - - // Verify the vtable of this table. - // Call this once per table, followed by VerifyField once per field. - bool VerifyTableStart(Verifier& verifier) const - { - return verifier.VerifyTableStart(data_); - } - - // Verify a particular field. - template - bool VerifyField(const Verifier& verifier, voffset_t field) const - { - // Calling GetOptionalFieldOffset should be safe now thanks to - // VerifyTable(). - auto field_offset = GetOptionalFieldOffset(field); - // Check the actual field. - return !field_offset || verifier.Verify(data_, field_offset); - } - - // VerifyField for required fields. - template - bool VerifyFieldRequired(const Verifier& verifier, voffset_t field) const - { - auto field_offset = GetOptionalFieldOffset(field); - return verifier.Check(field_offset != 0) && verifier.Verify(data_, field_offset); - } - - // Versions for offsets. - bool VerifyOffset(const Verifier& verifier, voffset_t field) const - { - auto field_offset = GetOptionalFieldOffset(field); - return !field_offset || verifier.VerifyOffset(data_, field_offset); - } - - bool VerifyOffsetRequired(const Verifier& verifier, voffset_t field) const - { - auto field_offset = GetOptionalFieldOffset(field); - return verifier.Check(field_offset != 0) && - verifier.VerifyOffset(data_, field_offset); - } - -private: - // private constructor & copy constructor: you obtain instances of this - // class by pointing to existing data only - Table(); - Table(const Table& other); - Table& operator=(const Table&); - - uint8_t data_[1]; -}; - -// This specialization allows avoiding warnings like: -// MSVC C4800: type: forcing value to bool 'true' or 'false'. -template <> -inline flatbuffers::Optional -Table::GetOptional(voffset_t field) const -{ - auto field_offset = GetOptionalFieldOffset(field); - auto p = data_ + field_offset; - return field_offset ? Optional(ReadScalar(p) != 0) : Optional(); -} - -template -void FlatBufferBuilder::Required(Offset table, voffset_t field) -{ - auto table_ptr = reinterpret_cast(buf_.data_at(table.o)); - bool ok = table_ptr->GetOptionalFieldOffset(field) != 0; - // If this fails, the caller will show what field needs to be set. - FLATBUFFERS_ASSERT(ok); - (void)ok; -} - -/// @brief This can compute the start of a FlatBuffer from a root pointer, i.e. -/// it is the opposite transformation of GetRoot(). -/// This may be useful if you want to pass on a root and have the recipient -/// delete the buffer afterwards. -inline const uint8_t* GetBufferStartFromRootPointer(const void* root) -{ - auto table = reinterpret_cast(root); - auto vtable = table->GetVTable(); - // Either the vtable is before the root or after the root. - auto start = (std::min)(vtable, reinterpret_cast(root)); - // Align to at least sizeof(uoffset_t). - start = reinterpret_cast(reinterpret_cast(start) & - ~(sizeof(uoffset_t) - 1)); - // Additionally, there may be a file_identifier in the buffer, and the root - // offset. The buffer may have been aligned to any size between - // sizeof(uoffset_t) and FLATBUFFERS_MAX_ALIGNMENT (see "force_align"). - // Sadly, the exact alignment is only known when constructing the buffer, - // since it depends on the presence of values with said alignment properties. - // So instead, we simply look at the next uoffset_t values (root, - // file_identifier, and alignment padding) to see which points to the root. - // None of the other values can "impersonate" the root since they will either - // be 0 or four ASCII characters. - static_assert(FlatBufferBuilder::kFileIdentifierLength == sizeof(uoffset_t), "file_" - "identifie" - "r " - "is " - "assumed " - "to be " - "the same " - "size as " - "uoffset_" - "t"); - for(auto possible_roots = FLATBUFFERS_MAX_ALIGNMENT / sizeof(uoffset_t) + 1; - possible_roots; possible_roots--) - { - start -= sizeof(uoffset_t); - if(ReadScalar(start) + start == reinterpret_cast(root)) - return start; - } - // We didn't find the root, either the "root" passed isn't really a root, - // or the buffer is corrupt. - // Assert, because calling this function with bad data may cause reads - // outside of buffer boundaries. - FLATBUFFERS_ASSERT(false); - return nullptr; -} - -/// @brief This return the prefixed size of a FlatBuffer. -inline uoffset_t GetPrefixedSize(const uint8_t* buf) -{ - return ReadScalar(buf); -} - -// Base class for native objects (FlatBuffer data de-serialized into native -// C++ data structures). -// Contains no functionality, purely documentative. -struct NativeTable -{ -}; - -/// @brief Function types to be used with resolving hashes into objects and -/// back again. The resolver gets a pointer to a field inside an object API -/// object that is of the type specified in the schema using the attribute -/// `cpp_type` (it is thus important whatever you write to this address -/// matches that type). The value of this field is initially null, so you -/// may choose to implement a delayed binding lookup using this function -/// if you wish. The resolver does the opposite lookup, for when the object -/// is being serialized again. -typedef uint64_t hash_value_t; -// clang-format off -#ifdef FLATBUFFERS_CPP98_STL - typedef void (*resolver_function_t)(void **pointer_adr, hash_value_t hash); - typedef hash_value_t (*rehasher_function_t)(void *pointer); -#else - typedef std::function - resolver_function_t; - typedef std::function rehasher_function_t; -#endif -// clang-format on - -// Helper function to test if a field is present, using any of the field -// enums in the generated code. -// `table` must be a generated table type. Since this is a template parameter, -// this is not typechecked to be a subclass of Table, so beware! -// Note: this function will return false for fields equal to the default -// value, since they're not stored in the buffer (unless force_defaults was -// used). -template -bool IsFieldPresent(const T* table, typename T::FlatBuffersVTableOffset field) -{ - // Cast, since Table is a private baseclass of any table types. - return reinterpret_cast(table)->CheckField(static_cast(field)); -} - -// Utility function for reverse lookups on the EnumNames*() functions -// (in the generated C++ code) -// names must be NULL terminated. -inline int LookupEnum(const char** names, const char* name) -{ - for(const char** p = names; *p; p++) - if(!strcmp(*p, name)) - return static_cast(p - names); - return -1; -} - -// These macros allow us to layout a struct with a guarantee that they'll end -// up looking the same on different compilers and platforms. -// It does this by disallowing the compiler to do any padding, and then -// does padding itself by inserting extra padding fields that make every -// element aligned to its own size. -// Additionally, it manually sets the alignment of the struct as a whole, -// which is typically its largest element, or a custom size set in the schema -// by the force_align attribute. -// These are used in the generated code only. - -// clang-format off -#if defined(_MSC_VER) - #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \ - __pragma(pack(1)) \ - struct __declspec(align(alignment)) - #define FLATBUFFERS_STRUCT_END(name, size) \ - __pragma(pack()) \ - static_assert(sizeof(name) == size, "compiler breaks packing rules") -#elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__) - #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \ - _Pragma("pack(1)") \ - struct __attribute__((aligned(alignment))) - #define FLATBUFFERS_STRUCT_END(name, size) \ - _Pragma("pack()") \ - static_assert(sizeof(name) == size, "compiler breaks packing rules") -#else - #error Unknown compiler, please define structure alignment macros -#endif -// clang-format on - -// Minimal reflection via code generation. -// Besides full-fat reflection (see reflection.h) and parsing/printing by -// loading schemas (see idl.h), we can also have code generation for mimimal -// reflection data which allows pretty-printing and other uses without needing -// a schema or a parser. -// Generate code with --reflect-types (types only) or --reflect-names (names -// also) to enable. -// See minireflect.h for utilities using this functionality. - -// These types are organized slightly differently as the ones in idl.h. -enum SequenceType -{ - ST_TABLE, - ST_STRUCT, - ST_UNION, - ST_ENUM -}; - -// Scalars have the same order as in idl.h -// clang-format off -#define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \ - ET(ET_UTYPE) \ - ET(ET_BOOL) \ - ET(ET_CHAR) \ - ET(ET_UCHAR) \ - ET(ET_SHORT) \ - ET(ET_USHORT) \ - ET(ET_INT) \ - ET(ET_UINT) \ - ET(ET_LONG) \ - ET(ET_ULONG) \ - ET(ET_FLOAT) \ - ET(ET_DOUBLE) \ - ET(ET_STRING) \ - ET(ET_SEQUENCE) // See SequenceType. - -enum ElementaryType { - #define FLATBUFFERS_ET(E) E, - FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET) - #undef FLATBUFFERS_ET -}; - -inline const char * const *ElementaryTypeNames() { - static const char * const names[] = { - #define FLATBUFFERS_ET(E) #E, - FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET) - #undef FLATBUFFERS_ET - }; - return names; -} -// clang-format on - -// Basic type info cost just 16bits per field! -// We're explicitly defining the signedness since the signedness of integer -// bitfields is otherwise implementation-defined and causes warnings on older -// GCC compilers. -struct TypeCode -{ - // ElementaryType - unsigned short base_type : 4; - // Either vector (in table) or array (in struct) - unsigned short is_repeating : 1; - // Index into type_refs below, or -1 for none. - signed short sequence_ref : 11; -}; - -static_assert(sizeof(TypeCode) == 2, "TypeCode"); - -struct TypeTable; - -// Signature of the static method present in each type. -typedef const TypeTable* (*TypeFunction)(); - -struct TypeTable -{ - SequenceType st; - size_t num_elems; // of type_codes, values, names (but not type_refs). - const TypeCode* type_codes; // num_elems count - const TypeFunction* type_refs; // less than num_elems entries (see TypeCode). - const int16_t* array_sizes; // less than num_elems entries (see TypeCode). - const int64_t* values; // Only set for non-consecutive enum/union or structs. - const char* const* names; // Only set if compiled with --reflect-names. -}; - -// String which identifies the current version of FlatBuffers. -// flatbuffer_version_string is used by Google developers to identify which -// applications uploaded to Google Play are using this library. This allows -// the development team at Google to determine the popularity of the library. -// How it works: Applications that are uploaded to the Google Play Store are -// scanned for this version string. We track which applications are using it -// to measure popularity. You are free to remove it (of course) but we would -// appreciate if you left it in. - -// Weak linkage is culled by VS & doesn't work on cygwin. -// clang-format off -#if !defined(_WIN32) && !defined(__CYGWIN__) - -extern volatile __attribute__((weak)) const char *flatbuffer_version_string; -volatile __attribute__((weak)) const char *flatbuffer_version_string = - "FlatBuffers " - FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "." - FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "." - FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION); - -#endif // !defined(_WIN32) && !defined(__CYGWIN__) - -#define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\ - inline E operator | (E lhs, E rhs){\ - return E(T(lhs) | T(rhs));\ - }\ - inline E operator & (E lhs, E rhs){\ - return E(T(lhs) & T(rhs));\ - }\ - inline E operator ^ (E lhs, E rhs){\ - return E(T(lhs) ^ T(rhs));\ - }\ - inline E operator ~ (E lhs){\ - return E(~T(lhs));\ - }\ - inline E operator |= (E &lhs, E rhs){\ - lhs = lhs | rhs;\ - return lhs;\ - }\ - inline E operator &= (E &lhs, E rhs){\ - lhs = lhs & rhs;\ - return lhs;\ - }\ - inline E operator ^= (E &lhs, E rhs){\ - lhs = lhs ^ rhs;\ - return lhs;\ - }\ - inline bool operator !(E rhs) \ - {\ - return !bool(T(rhs)); \ - } -/// @endcond -} // namespace flatbuffers - -// clang-format on - -#endif // FLATBUFFERS_H_ diff --git a/include/behaviortree_cpp/flatbuffers/stl_emulation.h b/include/behaviortree_cpp/flatbuffers/stl_emulation.h deleted file mode 100644 index 7aaca4e6d..000000000 --- a/include/behaviortree_cpp/flatbuffers/stl_emulation.h +++ /dev/null @@ -1,673 +0,0 @@ -/* - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_STL_EMULATION_H_ -#define FLATBUFFERS_STL_EMULATION_H_ - -// clang-format off -#include "behaviortree_cpp/flatbuffers/base.h" - -#include -#include -#include -#include -#include - -#if defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL) - #define FLATBUFFERS_CPP98_STL -#endif // defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL) - -#if defined(FLATBUFFERS_CPP98_STL) - #include -#endif // defined(FLATBUFFERS_CPP98_STL) - -// Detect C++17 compatible compiler. -// __cplusplus >= 201703L - a compiler has support of 'static inline' variables. -#if defined(FLATBUFFERS_USE_STD_OPTIONAL) \ - || (defined(__cplusplus) && __cplusplus >= 201703L) \ - || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L)) - #include - #ifndef FLATBUFFERS_USE_STD_OPTIONAL - #define FLATBUFFERS_USE_STD_OPTIONAL - #endif -#endif // defined(FLATBUFFERS_USE_STD_OPTIONAL) ... - -// The __cpp_lib_span is the predefined feature macro. -#if defined(FLATBUFFERS_USE_STD_SPAN) - #include -#elif defined(__cpp_lib_span) && defined(__has_include) - #if __has_include() - #include - #define FLATBUFFERS_USE_STD_SPAN - #endif -#else - // Disable non-trivial ctors if FLATBUFFERS_SPAN_MINIMAL defined. - #if !defined(FLATBUFFERS_TEMPLATES_ALIASES) || defined(FLATBUFFERS_CPP98_STL) - #define FLATBUFFERS_SPAN_MINIMAL - #else - // Enable implicit construction of a span from a std::array. - #include - #endif -#endif // defined(FLATBUFFERS_USE_STD_SPAN) - -// This header provides backwards compatibility for C++98 STLs like stlport. -namespace flatbuffers { - -// Retrieve ::back() from a string in a way that is compatible with pre C++11 -// STLs (e.g stlport). -inline char& string_back(std::string &value) { - return value[value.length() - 1]; -} - -inline char string_back(const std::string &value) { - return value[value.length() - 1]; -} - -// Helper method that retrieves ::data() from a vector in a way that is -// compatible with pre C++11 STLs (e.g stlport). -template inline T *vector_data(std::vector &vector) { - // In some debug environments, operator[] does bounds checking, so &vector[0] - // can't be used. - return vector.empty() ? nullptr : &vector[0]; -} - -template inline const T *vector_data( - const std::vector &vector) { - return vector.empty() ? nullptr : &vector[0]; -} - -template -inline void vector_emplace_back(std::vector *vector, V &&data) { - #if defined(FLATBUFFERS_CPP98_STL) - vector->push_back(data); - #else - vector->emplace_back(std::forward(data)); - #endif // defined(FLATBUFFERS_CPP98_STL) -} - -#ifndef FLATBUFFERS_CPP98_STL - #if defined(FLATBUFFERS_TEMPLATES_ALIASES) - template - using numeric_limits = std::numeric_limits; - #else - template class numeric_limits : - public std::numeric_limits {}; - #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) -#else - template class numeric_limits : - public std::numeric_limits { - public: - // Android NDK fix. - static T lowest() { - return std::numeric_limits::min(); - } - }; - - template <> class numeric_limits : - public std::numeric_limits { - public: - static float lowest() { return -FLT_MAX; } - }; - - template <> class numeric_limits : - public std::numeric_limits { - public: - static double lowest() { return -DBL_MAX; } - }; - - template <> class numeric_limits { - public: - static unsigned long long min() { return 0ULL; } - static unsigned long long max() { return ~0ULL; } - static unsigned long long lowest() { - return numeric_limits::min(); - } - }; - - template <> class numeric_limits { - public: - static long long min() { - return static_cast(1ULL << ((sizeof(long long) << 3) - 1)); - } - static long long max() { - return static_cast( - (1ULL << ((sizeof(long long) << 3) - 1)) - 1); - } - static long long lowest() { - return numeric_limits::min(); - } - }; -#endif // FLATBUFFERS_CPP98_STL - -#if defined(FLATBUFFERS_TEMPLATES_ALIASES) - #ifndef FLATBUFFERS_CPP98_STL - template using is_scalar = std::is_scalar; - template using is_same = std::is_same; - template using is_floating_point = std::is_floating_point; - template using is_unsigned = std::is_unsigned; - template using is_enum = std::is_enum; - template using make_unsigned = std::make_unsigned; - template - using conditional = std::conditional; - template - using integral_constant = std::integral_constant; - template - using bool_constant = integral_constant; - #else - // Map C++ TR1 templates defined by stlport. - template using is_scalar = std::tr1::is_scalar; - template using is_same = std::tr1::is_same; - template using is_floating_point = - std::tr1::is_floating_point; - template using is_unsigned = std::tr1::is_unsigned; - template using is_enum = std::tr1::is_enum; - // Android NDK doesn't have std::make_unsigned or std::tr1::make_unsigned. - template struct make_unsigned { - static_assert(is_unsigned::value, "Specialization not implemented!"); - using type = T; - }; - template<> struct make_unsigned { using type = unsigned char; }; - template<> struct make_unsigned { using type = unsigned short; }; - template<> struct make_unsigned { using type = unsigned int; }; - template<> struct make_unsigned { using type = unsigned long; }; - template<> - struct make_unsigned { using type = unsigned long long; }; - template - using conditional = std::tr1::conditional; - template - using integral_constant = std::tr1::integral_constant; - template - using bool_constant = integral_constant; - #endif // !FLATBUFFERS_CPP98_STL -#else - // MSVC 2010 doesn't support C++11 aliases. - template struct is_scalar : public std::is_scalar {}; - template struct is_same : public std::is_same {}; - template struct is_floating_point : - public std::is_floating_point {}; - template struct is_unsigned : public std::is_unsigned {}; - template struct is_enum : public std::is_enum {}; - template struct make_unsigned : public std::make_unsigned {}; - template - struct conditional : public std::conditional {}; - template - struct integral_constant : public std::integral_constant {}; - template - struct bool_constant : public integral_constant {}; -#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) - -#ifndef FLATBUFFERS_CPP98_STL - #if defined(FLATBUFFERS_TEMPLATES_ALIASES) - template using unique_ptr = std::unique_ptr; - #else - // MSVC 2010 doesn't support C++11 aliases. - // We're manually "aliasing" the class here as we want to bring unique_ptr - // into the flatbuffers namespace. We have unique_ptr in the flatbuffers - // namespace we have a completely independent implementation (see below) - // for C++98 STL implementations. - template class unique_ptr : public std::unique_ptr { - public: - unique_ptr() {} - explicit unique_ptr(T* p) : std::unique_ptr(p) {} - unique_ptr(std::unique_ptr&& u) { *this = std::move(u); } - unique_ptr(unique_ptr&& u) { *this = std::move(u); } - unique_ptr& operator=(std::unique_ptr&& u) { - std::unique_ptr::reset(u.release()); - return *this; - } - unique_ptr& operator=(unique_ptr&& u) { - std::unique_ptr::reset(u.release()); - return *this; - } - unique_ptr& operator=(T* p) { - return std::unique_ptr::operator=(p); - } - }; - #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) -#else - // Very limited implementation of unique_ptr. - // This is provided simply to allow the C++ code generated from the default - // settings to function in C++98 environments with no modifications. - template class unique_ptr { - public: - typedef T element_type; - - unique_ptr() : ptr_(nullptr) {} - explicit unique_ptr(T* p) : ptr_(p) {} - unique_ptr(unique_ptr&& u) : ptr_(nullptr) { reset(u.release()); } - unique_ptr(const unique_ptr& u) : ptr_(nullptr) { - reset(const_cast(&u)->release()); - } - ~unique_ptr() { reset(); } - - unique_ptr& operator=(const unique_ptr& u) { - reset(const_cast(&u)->release()); - return *this; - } - - unique_ptr& operator=(unique_ptr&& u) { - reset(u.release()); - return *this; - } - - unique_ptr& operator=(T* p) { - reset(p); - return *this; - } - - const T& operator*() const { return *ptr_; } - T* operator->() const { return ptr_; } - T* get() const noexcept { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - // modifiers - T* release() { - T* value = ptr_; - ptr_ = nullptr; - return value; - } - - void reset(T* p = nullptr) { - T* value = ptr_; - ptr_ = p; - if (value) delete value; - } - - void swap(unique_ptr& u) { - T* temp_ptr = ptr_; - ptr_ = u.ptr_; - u.ptr_ = temp_ptr; - } - - private: - T* ptr_; - }; - - template bool operator==(const unique_ptr& x, - const unique_ptr& y) { - return x.get() == y.get(); - } - - template bool operator==(const unique_ptr& x, - const D* y) { - return static_cast(x.get()) == y; - } - - template bool operator==(const unique_ptr& x, intptr_t y) { - return reinterpret_cast(x.get()) == y; - } - - template bool operator!=(const unique_ptr& x, decltype(nullptr)) { - return !!x; - } - - template bool operator!=(decltype(nullptr), const unique_ptr& x) { - return !!x; - } - - template bool operator==(const unique_ptr& x, decltype(nullptr)) { - return !x; - } - - template bool operator==(decltype(nullptr), const unique_ptr& x) { - return !x; - } - -#endif // !FLATBUFFERS_CPP98_STL - -#ifdef FLATBUFFERS_USE_STD_OPTIONAL -template -using Optional = std::optional; -using nullopt_t = std::nullopt_t; -inline constexpr nullopt_t nullopt = std::nullopt; - -#else -// Limited implementation of Optional type for a scalar T. -// This implementation limited by trivial types compatible with -// std::is_arithmetic or std::is_enum type traits. - -// A tag to indicate an empty flatbuffers::optional. -struct nullopt_t { - explicit FLATBUFFERS_CONSTEXPR_CPP11 nullopt_t(int) {} -}; - -#if defined(FLATBUFFERS_CONSTEXPR_DEFINED) - namespace internal { - template struct nullopt_holder { - static constexpr nullopt_t instance_ = nullopt_t(0); - }; - template - constexpr nullopt_t nullopt_holder::instance_; - } - static constexpr const nullopt_t &nullopt = internal::nullopt_holder::instance_; - -#else - namespace internal { - template struct nullopt_holder { - static const nullopt_t instance_; - }; - template - const nullopt_t nullopt_holder::instance_ = nullopt_t(0); - } - static const nullopt_t &nullopt = internal::nullopt_holder::instance_; - -#endif - -template -class Optional FLATBUFFERS_FINAL_CLASS { - // Non-scalar 'T' would extremely complicated Optional. - // Use is_scalar checking because flatbuffers flatbuffers::is_arithmetic - // isn't implemented. - static_assert(flatbuffers::is_scalar::value, "unexpected type T"); - - public: - ~Optional() {} - - FLATBUFFERS_CONSTEXPR_CPP11 Optional() FLATBUFFERS_NOEXCEPT - : value_(), has_value_(false) {} - - FLATBUFFERS_CONSTEXPR_CPP11 Optional(nullopt_t) FLATBUFFERS_NOEXCEPT - : value_(), has_value_(false) {} - - FLATBUFFERS_CONSTEXPR_CPP11 Optional(T val) FLATBUFFERS_NOEXCEPT - : value_(val), has_value_(true) {} - - FLATBUFFERS_CONSTEXPR_CPP11 Optional(const Optional &other) FLATBUFFERS_NOEXCEPT - : value_(other.value_), has_value_(other.has_value_) {} - - FLATBUFFERS_CONSTEXPR_CPP14 Optional &operator=(const Optional &other) FLATBUFFERS_NOEXCEPT { - value_ = other.value_; - has_value_ = other.has_value_; - return *this; - } - - FLATBUFFERS_CONSTEXPR_CPP14 Optional &operator=(nullopt_t) FLATBUFFERS_NOEXCEPT { - value_ = T(); - has_value_ = false; - return *this; - } - - FLATBUFFERS_CONSTEXPR_CPP14 Optional &operator=(T val) FLATBUFFERS_NOEXCEPT { - value_ = val; - has_value_ = true; - return *this; - } - - void reset() FLATBUFFERS_NOEXCEPT { - *this = nullopt; - } - - void swap(Optional &other) FLATBUFFERS_NOEXCEPT { - std::swap(value_, other.value_); - std::swap(has_value_, other.has_value_); - } - - FLATBUFFERS_CONSTEXPR_CPP11 FLATBUFFERS_EXPLICIT_CPP11 operator bool() const FLATBUFFERS_NOEXCEPT { - return has_value_; - } - - FLATBUFFERS_CONSTEXPR_CPP11 bool has_value() const FLATBUFFERS_NOEXCEPT { - return has_value_; - } - - FLATBUFFERS_CONSTEXPR_CPP11 const T& operator*() const FLATBUFFERS_NOEXCEPT { - return value_; - } - - const T& value() const { - FLATBUFFERS_ASSERT(has_value()); - return value_; - } - - T value_or(T default_value) const FLATBUFFERS_NOEXCEPT { - return has_value() ? value_ : default_value; - } - - private: - T value_; - bool has_value_; -}; - -template -FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(const Optional& opt, nullopt_t) FLATBUFFERS_NOEXCEPT { - return !opt; -} -template -FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(nullopt_t, const Optional& opt) FLATBUFFERS_NOEXCEPT { - return !opt; -} - -template -FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(const Optional& lhs, const U& rhs) FLATBUFFERS_NOEXCEPT { - return static_cast(lhs) && (*lhs == rhs); -} - -template -FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(const T& lhs, const Optional& rhs) FLATBUFFERS_NOEXCEPT { - return static_cast(rhs) && (lhs == *rhs); -} - -template -FLATBUFFERS_CONSTEXPR_CPP11 bool operator==(const Optional& lhs, const Optional& rhs) FLATBUFFERS_NOEXCEPT { - return static_cast(lhs) != static_cast(rhs) - ? false - : !static_cast(lhs) ? false : (*lhs == *rhs); -} -#endif // FLATBUFFERS_USE_STD_OPTIONAL - - -// Very limited and naive partial implementation of C++20 std::span. -#if defined(FLATBUFFERS_USE_STD_SPAN) - inline constexpr std::size_t dynamic_extent = std::dynamic_extent; - template - using span = std::span; - -#else // !defined(FLATBUFFERS_USE_STD_SPAN) -FLATBUFFERS_CONSTEXPR std::size_t dynamic_extent = static_cast(-1); - -// Exclude this code if MSVC2010 or non-STL Android is active. -// The non-STL Android doesn't have `std::is_convertible` required for SFINAE. -#if !defined(FLATBUFFERS_SPAN_MINIMAL) -namespace internal { - // This is SFINAE helper class for checking of a common condition: - // > This overload only participates in overload resolution - // > Check whether a pointer to an array of U can be converted - // > to a pointer to an array of E. - // This helper is used for checking of 'U -> const U'. - template - struct is_span_convertable { - using type = - typename std::conditional::value - && (Extent == dynamic_extent || N == Extent), - int, void>::type; - }; - -} // namespace internal -#endif // !defined(FLATBUFFERS_SPAN_MINIMAL) - -// T - element type; must be a complete type that is not an abstract -// class type. -// Extent - the number of elements in the sequence, or dynamic. -template -class span FLATBUFFERS_FINAL_CLASS { - public: - typedef T element_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; - typedef std::size_t size_type; - - static FLATBUFFERS_CONSTEXPR size_type extent = Extent; - - // Returns the number of elements in the span. - FLATBUFFERS_CONSTEXPR_CPP11 size_type size() const FLATBUFFERS_NOEXCEPT { - return count_; - } - - // Returns the size of the sequence in bytes. - FLATBUFFERS_CONSTEXPR_CPP11 - size_type size_bytes() const FLATBUFFERS_NOEXCEPT { - return size() * sizeof(element_type); - } - - // Checks if the span is empty. - FLATBUFFERS_CONSTEXPR_CPP11 bool empty() const FLATBUFFERS_NOEXCEPT { - return size() == 0; - } - - // Returns a pointer to the beginning of the sequence. - FLATBUFFERS_CONSTEXPR_CPP11 pointer data() const FLATBUFFERS_NOEXCEPT { - return data_; - } - - // Returns a reference to the idx-th element of the sequence. - // The behavior is undefined if the idx is greater than or equal to size(). - FLATBUFFERS_CONSTEXPR_CPP11 reference operator[](size_type idx) const { - return data()[idx]; - } - - FLATBUFFERS_CONSTEXPR_CPP11 span(const span &other) FLATBUFFERS_NOEXCEPT - : data_(other.data_), count_(other.count_) {} - - FLATBUFFERS_CONSTEXPR_CPP14 span &operator=(const span &other) - FLATBUFFERS_NOEXCEPT { - data_ = other.data_; - count_ = other.count_; - } - - // Limited implementation of - // `template constexpr std::span(It first, size_type count);`. - // - // Constructs a span that is a view over the range [first, first + count); - // the resulting span has: data() == first and size() == count. - // The behavior is undefined if [first, first + count) is not a valid range, - // or if (extent != flatbuffers::dynamic_extent && count != extent). - FLATBUFFERS_CONSTEXPR_CPP11 - explicit span(pointer first, size_type count) FLATBUFFERS_NOEXCEPT - : data_ (Extent == dynamic_extent ? first : (Extent == count ? first : nullptr)), - count_(Extent == dynamic_extent ? count : (Extent == count ? Extent : 0)) { - // Make span empty if the count argument is incompatible with span. - } - - // Exclude this code if MSVC2010 is active. The MSVC2010 isn't C++11 - // compliant, it doesn't support default template arguments for functions. - #if defined(FLATBUFFERS_SPAN_MINIMAL) - FLATBUFFERS_CONSTEXPR_CPP11 span() FLATBUFFERS_NOEXCEPT : data_(nullptr), - count_(0) { - static_assert(extent == 0 || extent == dynamic_extent, "invalid span"); - } - - #else - // Constructs an empty span whose data() == nullptr and size() == 0. - // This overload only participates in overload resolution if - // extent == 0 || extent == flatbuffers::dynamic_extent. - // A dummy template argument N is need dependency for SFINAE. - template::type = 0> - FLATBUFFERS_CONSTEXPR_CPP11 span() FLATBUFFERS_NOEXCEPT : data_(nullptr), - count_(0) { - static_assert(extent == 0 || extent == dynamic_extent, "invalid span"); - } - - // Constructs a span that is a view over the array arr; the resulting span - // has size() == N and data() == std::data(arr). These overloads only - // participate in overload resolution if - // extent == std::dynamic_extent || N == extent is true and - // std::remove_pointer_t(*)[] - // is convertible to element_type (*)[]. - template::type = 0> - FLATBUFFERS_CONSTEXPR_CPP11 span(element_type (&arr)[N]) FLATBUFFERS_NOEXCEPT - : data_(arr), count_(N) {} - - template::type = 0> - FLATBUFFERS_CONSTEXPR_CPP11 span(std::array &arr) FLATBUFFERS_NOEXCEPT - : data_(arr.data()), count_(N) {} - - //template - //FLATBUFFERS_CONSTEXPR_CPP11 span(std::array &arr) FLATBUFFERS_NOEXCEPT - // : data_(arr.data()), count_(N) {} - - template::type = 0> - FLATBUFFERS_CONSTEXPR_CPP11 span(const std::array &arr) FLATBUFFERS_NOEXCEPT - : data_(arr.data()), count_(N) {} - - // Converting constructor from another span s; - // the resulting span has size() == s.size() and data() == s.data(). - // This overload only participates in overload resolution - // if extent == std::dynamic_extent || N == extent is true and U (*)[] - // is convertible to element_type (*)[]. - template::type = 0> - FLATBUFFERS_CONSTEXPR_CPP11 span(const flatbuffers::span &s) FLATBUFFERS_NOEXCEPT - : span(s.data(), s.size()) { - } - - #endif // !defined(FLATBUFFERS_SPAN_MINIMAL) - - private: - // This is a naive implementation with 'count_' member even if (Extent != dynamic_extent). - pointer const data_; - const size_type count_; -}; - - #if !defined(FLATBUFFERS_SPAN_MINIMAL) - template - FLATBUFFERS_CONSTEXPR_CPP11 - flatbuffers::span make_span(U(&arr)[N]) FLATBUFFERS_NOEXCEPT { - return span(arr); - } - - template - FLATBUFFERS_CONSTEXPR_CPP11 - flatbuffers::span make_span(const U(&arr)[N]) FLATBUFFERS_NOEXCEPT { - return span(arr); - } - - template - FLATBUFFERS_CONSTEXPR_CPP11 - flatbuffers::span make_span(std::array &arr) FLATBUFFERS_NOEXCEPT { - return span(arr); - } - - template - FLATBUFFERS_CONSTEXPR_CPP11 - flatbuffers::span make_span(const std::array &arr) FLATBUFFERS_NOEXCEPT { - return span(arr); - } - - template - FLATBUFFERS_CONSTEXPR_CPP11 - flatbuffers::span make_span(U *first, std::size_t count) FLATBUFFERS_NOEXCEPT { - return span(first, count); - } - - template - FLATBUFFERS_CONSTEXPR_CPP11 - flatbuffers::span make_span(const U *first, std::size_t count) FLATBUFFERS_NOEXCEPT { - return span(first, count); - } -#endif - -#endif // defined(FLATBUFFERS_USE_STD_SPAN) - -} // namespace flatbuffers - -#endif // FLATBUFFERS_STL_EMULATION_H_ diff --git a/include/behaviortree_cpp/loggers/bt_file_logger.h b/include/behaviortree_cpp/loggers/bt_file_logger.h deleted file mode 100644 index 8b98517a3..000000000 --- a/include/behaviortree_cpp/loggers/bt_file_logger.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef BT_FILE_LOGGER_H -#define BT_FILE_LOGGER_H - -#include -#include -#include -#include "behaviortree_cpp/loggers/abstract_logger.h" -#include "behaviortree_cpp/flatbuffers/bt_flatbuffer_helper.h" - -namespace BT -{ - -class [[deprecated("Use FileLogger2 instead")]] FileLogger : public StatusChangeLogger -{ -public: - FileLogger(const Tree& tree, const char* filename, uint16_t buffer_size = 10); - - virtual ~FileLogger() override; - - virtual void callback(Duration timestamp, const TreeNode& node, NodeStatus prev_status, - NodeStatus status) override; - - virtual void flush() override; - -private: - std::ofstream file_os_; - - std::chrono::high_resolution_clock::time_point start_time; - - std::vector buffer_; - - size_t buffer_max_size_; -}; - -} // namespace BT - -#endif // BT_FILE_LOGGER_H diff --git a/src/loggers/bt_file_logger.cpp b/src/loggers/bt_file_logger.cpp deleted file mode 100644 index 324e926de..000000000 --- a/src/loggers/bt_file_logger.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "behaviortree_cpp/loggers/bt_file_logger.h" -#include "behaviortree_cpp/flatbuffers/bt_flatbuffer_helper.h" - -namespace BT -{ -FileLogger::FileLogger(const BT::Tree& tree, const char* filename, uint16_t buffer_size) - : StatusChangeLogger(tree.rootNode()), buffer_max_size_(buffer_size) -{ - if(buffer_max_size_ != 0) - { - buffer_.reserve(buffer_max_size_); - } - - enableTransitionToIdle(true); - - flatbuffers::FlatBufferBuilder builder(1024); - CreateFlatbuffersBehaviorTree(builder, tree); - - //------------------------------------- - - file_os_.open(filename, std::ofstream::binary | std::ofstream::out); - - // serialize the length of the buffer in the first 4 bytes - char size_buff[4]; - flatbuffers::WriteScalar(size_buff, static_cast(builder.GetSize())); - - file_os_.write(size_buff, 4); - file_os_.write(reinterpret_cast(builder.GetBufferPointer()), - builder.GetSize()); -} - -FileLogger::~FileLogger() -{ - this->flush(); - file_os_.close(); -} - -void FileLogger::callback(Duration timestamp, const TreeNode& node, - NodeStatus prev_status, NodeStatus status) -{ - SerializedTransition buffer = - SerializeTransition(node.UID(), timestamp, prev_status, status); - - if(buffer_max_size_ == 0) - { - file_os_.write(reinterpret_cast(buffer.data()), buffer.size()); - } - else - { - buffer_.push_back(buffer); - if(buffer_.size() >= buffer_max_size_) - { - this->flush(); - } - } -} - -void FileLogger::flush() -{ - for(const auto& array : buffer_) - { - file_os_.write(reinterpret_cast(array.data()), array.size()); - } - file_os_.flush(); - buffer_.clear(); -} -} // namespace BT diff --git a/src/loggers/bt_file_logger_v2.cpp b/src/loggers/bt_file_logger_v2.cpp index 54e4902f2..40d39381d 100644 --- a/src/loggers/bt_file_logger_v2.cpp +++ b/src/loggers/bt_file_logger_v2.cpp @@ -1,6 +1,6 @@ #include "behaviortree_cpp/loggers/bt_file_logger_v2.h" -#include "behaviortree_cpp/flatbuffers/base.h" #include "behaviortree_cpp/xml_parsing.h" +#include "flatbuffers/base.h" namespace BT { diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 2bd5d8411..b3d0875f3 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,10 +1,10 @@ include_directories(${PROJECT_SOURCE_DIR}/3rdparty) -add_executable(bt4_log_cat bt_log_cat.cpp ) -target_link_libraries(bt4_log_cat ${BTCPP_LIBRARY} ) -install(TARGETS bt4_log_cat - DESTINATION ${BTCPP_BIN_DESTINATION} ) +# add_executable(bt4_log_cat bt_log_cat.cpp ) +# target_link_libraries(bt4_log_cat ${BTCPP_LIBRARY} ) +# install(TARGETS bt4_log_cat +# DESTINATION ${BTCPP_BIN_DESTINATION} ) if( ZMQ_FOUND ) add_executable(bt4_recorder bt_recorder.cpp ) diff --git a/tools/bt_log_cat.cpp b/tools/bt_log_cat.cpp deleted file mode 100644 index d4cc9c70c..000000000 --- a/tools/bt_log_cat.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include -#include -#include -#include -#include "behaviortree_cpp/flatbuffers/BT_logger_generated.h" - -int main(int argc, char* argv[]) -{ - if(argc != 2) - { - printf("Wrong number of arguments\nUsage: %s [filename]\n", argv[0]); - return 1; - } - - FILE* file = fopen(argv[1], "rb"); - - if(!file) - { - printf("Failed to open file: [%s]\n", argv[1]); - return 1; - } - - fseek(file, 0L, SEEK_END); - const size_t length = static_cast(ftell(file)); - fseek(file, 0L, SEEK_SET); - std::vector buffer(length); - auto ret = fread(buffer.data(), sizeof(char), length, file); - (void)ret; - fclose(file); - - const auto bt_header_size = flatbuffers::ReadScalar(&buffer[0]); - - auto behavior_tree = Serialization::GetBehaviorTree(&buffer[4]); - - std::unordered_map names_by_uid; - std::unordered_map node_by_uid; - uint16_t max_uid = 0; - - for(const Serialization::TreeNode* node : *(behavior_tree->nodes())) - { - names_by_uid.insert({ node->uid(), std::string(node->instance_name()->c_str()) }); - node_by_uid.insert({ node->uid(), node }); - max_uid = std::max(max_uid, node->uid()); - } - uint16_t digits_max_uid = std::to_string(max_uid).size(); - - printf("----------------------------\n"); - - std::function recursiveStep; - - recursiveStep = [&](uint16_t uid, int indent) { - printf("(%*d): ", digits_max_uid, uid); - for(int i = 0; i < indent; i++) - { - printf(" "); - names_by_uid[uid] = std::string(" ") + names_by_uid[uid]; - } - printf("%s\n", names_by_uid[uid].c_str()); - std::cout << std::flush; - - const auto& node = node_by_uid[uid]; - - for(size_t i = 0; i < node->children_uid()->size(); i++) - { - recursiveStep(node->children_uid()->Get(uint16_t(i)), indent + 1); - } - }; - - recursiveStep(behavior_tree->root_uid(), 0); - - printf("----------------------------\n"); - - constexpr const char* whitespaces = " "; - constexpr const size_t ws_count = 25; - - auto printStatus = [](Serialization::NodeStatus status) { - switch(status) - { - case Serialization::NodeStatus::SUCCESS: - return ("\x1b[32m" - "SUCCESS" - "\x1b[0m"); // RED - case Serialization::NodeStatus::FAILURE: - return ("\x1b[31m" - "FAILURE" - "\x1b[0m"); // GREEN - case Serialization::NodeStatus::RUNNING: - return ("\x1b[33m" - "RUNNING" - "\x1b[0m"); // YELLOW - case Serialization::NodeStatus::IDLE: - return ("\x1b[36m" - "IDLE " - "\x1b[0m"); // CYAN - } - return "Undefined"; - }; - - for(size_t index = bt_header_size + 4; index < length; index += 12) - { - const uint16_t uid = flatbuffers::ReadScalar(&buffer[index + 8]); - const std::string& name = names_by_uid[uid]; - const uint32_t t_sec = flatbuffers::ReadScalar(&buffer[index]); - const uint32_t t_usec = flatbuffers::ReadScalar(&buffer[index + 4]); - - printf("[%d.%06d] (%*d): %s%s %s -> %s\n", t_sec, t_usec, digits_max_uid, uid, - name.c_str(), &whitespaces[std::min(ws_count, name.size())], - printStatus( - flatbuffers::ReadScalar(&buffer[index + 10])), - printStatus( - flatbuffers::ReadScalar(&buffer[index + 11]))); - } - - return 0; -}