diff options
author | eeight <eeight@yandex-team.ru> | 2022-02-10 16:46:19 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:19 +0300 |
commit | bd085aee9b4f7a0bee302ce687964ffb7098f986 (patch) | |
tree | 1a2c5ffcf89eb53ecd79dbc9bc0a195c27404d0c /contrib/libs/flatbuffers/include | |
parent | 475c0a46f28166e83fd263badc7546377cddcabe (diff) | |
download | ydb-bd085aee9b4f7a0bee302ce687964ffb7098f986.tar.gz |
Restoring authorship annotation for <eeight@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/flatbuffers/include')
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/base.h | 492 | ||||
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/code_generators.h | 246 | ||||
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/flatbuffers.h | 2828 | ||||
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/flatc.h | 172 | ||||
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h | 2938 | ||||
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/grpc.h | 576 | ||||
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/hash.h | 58 | ||||
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/idl.h | 646 | ||||
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/minireflect.h | 686 | ||||
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/reflection.h | 230 | ||||
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h | 1614 | ||||
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/registry.h | 250 | ||||
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/stl_emulation.h | 454 | ||||
-rw-r--r-- | contrib/libs/flatbuffers/include/flatbuffers/util.h | 422 |
14 files changed, 5806 insertions, 5806 deletions
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/base.h b/contrib/libs/flatbuffers/include/flatbuffers/base.h index 3f46d8e037..e2defddb80 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/base.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/base.h @@ -1,73 +1,73 @@ -#ifndef FLATBUFFERS_BASE_H_ -#define FLATBUFFERS_BASE_H_ - -// clang-format off +#ifndef FLATBUFFERS_BASE_H_ +#define FLATBUFFERS_BASE_H_ + +// clang-format off // If activate should be declared and included first. -#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \ - defined(_MSC_VER) && defined(_DEBUG) +#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \ + defined(_MSC_VER) && defined(_DEBUG) // The _CRTDBG_MAP_ALLOC inside <crtdbg.h> will replace // calloc/free (etc) to its debug version using #define directives. - #define _CRTDBG_MAP_ALLOC + #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> // Replace operator new by trace-enabled version. #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) #define new DEBUG_NEW -#endif - +#endif + #if !defined(FLATBUFFERS_ASSERT) -#include <assert.h> -#define FLATBUFFERS_ASSERT assert +#include <assert.h> +#define FLATBUFFERS_ASSERT assert #elif defined(FLATBUFFERS_ASSERT_INCLUDE) // Include file with forward declaration #include FLATBUFFERS_ASSERT_INCLUDE -#endif - -#ifndef ARDUINO -#include <cstdint> -#endif - -#include <cstddef> -#include <cstdlib> -#include <cstring> - -#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H) +#endif + +#ifndef ARDUINO +#include <cstdint> +#endif + +#include <cstddef> +#include <cstdlib> +#include <cstring> + +#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H) #error #include <utility.h> -#else - #include <utility> -#endif - -#include <string> -#include <type_traits> -#include <vector> -#include <set> -#include <algorithm> -#include <iterator> -#include <memory> - +#else + #include <utility> +#endif + +#include <string> +#include <type_traits> +#include <vector> +#include <set> +#include <algorithm> +#include <iterator> +#include <memory> + #if defined(__unix__) && !defined(FLATBUFFERS_LOCALE_INDEPENDENT) #include <unistd.h> #endif -#ifdef _STLPORT_VERSION - #define FLATBUFFERS_CPP98_STL -#endif +#ifdef _STLPORT_VERSION + #define FLATBUFFERS_CPP98_STL +#endif #ifdef __ANDROID__ #include <android/api-level.h> -#endif - +#endif + #if defined(__ICCARM__) #include <intrinsics.h> #endif -// Note the __clang__ check is needed, because clang presents itself -// as an older GNUC compiler (4.2). -// Clang 3.3 and later implement all of the ISO C++ 2011 standard. -// Clang 3.4 and later implement all of the ISO C++ 2014 standard. -// http://clang.llvm.org/cxx_status.html - +// Note the __clang__ check is needed, because clang presents itself +// as an older GNUC compiler (4.2). +// Clang 3.3 and later implement all of the ISO C++ 2011 standard. +// Clang 3.4 and later implement all of the ISO C++ 2014 standard. +// http://clang.llvm.org/cxx_status.html + // Note the MSVC value '__cplusplus' may be incorrect: // The '__cplusplus' predefined macro in the MSVC stuck at the value 199711L, // indicating (erroneously!) that the compiler conformed to the C++98 Standard. @@ -89,119 +89,119 @@ #define FLATBUFFERS_CLANG 0 #endif -/// @cond FLATBUFFERS_INTERNAL -#if __cplusplus <= 199711L && \ - (!defined(_MSC_VER) || _MSC_VER < 1600) && \ - (!defined(__GNUC__) || \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400)) - #error A C++11 compatible compiler with support for the auto typing is \ - required for FlatBuffers. - #error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ -#endif - -#if !defined(__clang__) && \ - defined(__GNUC__) && \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600) +/// @cond FLATBUFFERS_INTERNAL +#if __cplusplus <= 199711L && \ + (!defined(_MSC_VER) || _MSC_VER < 1600) && \ + (!defined(__GNUC__) || \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400)) + #error A C++11 compatible compiler with support for the auto typing is \ + required for FlatBuffers. + #error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ +#endif + +#if !defined(__clang__) && \ + defined(__GNUC__) && \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600) // Backwards compatibility for g++ 4.4, and 4.5 which don't have the nullptr - // and constexpr keywords. Note the __clang__ check is needed, because clang - // presents itself as an older GNUC compiler. - #ifndef nullptr_t - const class nullptr_t { - public: - template<class T> inline operator T*() const { return 0; } - private: - void operator&() const; - } nullptr = {}; - #endif - #ifndef constexpr - #define constexpr const - #endif -#endif - -// The wire format uses a little endian encoding (since that's efficient for -// the common platforms). -#if defined(__s390x__) - #define FLATBUFFERS_LITTLEENDIAN 0 -#endif // __s390x__ -#if !defined(FLATBUFFERS_LITTLEENDIAN) + // and constexpr keywords. Note the __clang__ check is needed, because clang + // presents itself as an older GNUC compiler. + #ifndef nullptr_t + const class nullptr_t { + public: + template<class T> inline operator T*() const { return 0; } + private: + void operator&() const; + } nullptr = {}; + #endif + #ifndef constexpr + #define constexpr const + #endif +#endif + +// The wire format uses a little endian encoding (since that's efficient for +// the common platforms). +#if defined(__s390x__) + #define FLATBUFFERS_LITTLEENDIAN 0 +#endif // __s390x__ +#if !defined(FLATBUFFERS_LITTLEENDIAN) #if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__) #if (defined(__BIG_ENDIAN__) || \ (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) - #define FLATBUFFERS_LITTLEENDIAN 0 - #else - #define FLATBUFFERS_LITTLEENDIAN 1 - #endif // __BIG_ENDIAN__ - #elif defined(_MSC_VER) - #if defined(_M_PPC) - #define FLATBUFFERS_LITTLEENDIAN 0 - #else - #define FLATBUFFERS_LITTLEENDIAN 1 - #endif - #else - #error Unable to determine endianness, define FLATBUFFERS_LITTLEENDIAN. - #endif -#endif // !defined(FLATBUFFERS_LITTLEENDIAN) - + #define FLATBUFFERS_LITTLEENDIAN 0 + #else + #define FLATBUFFERS_LITTLEENDIAN 1 + #endif // __BIG_ENDIAN__ + #elif defined(_MSC_VER) + #if defined(_M_PPC) + #define FLATBUFFERS_LITTLEENDIAN 0 + #else + #define FLATBUFFERS_LITTLEENDIAN 1 + #endif + #else + #error Unable to determine endianness, define FLATBUFFERS_LITTLEENDIAN. + #endif +#endif // !defined(FLATBUFFERS_LITTLEENDIAN) + #define FLATBUFFERS_VERSION_MAJOR 2 #define FLATBUFFERS_VERSION_MINOR 0 -#define FLATBUFFERS_VERSION_REVISION 0 -#define FLATBUFFERS_STRING_EXPAND(X) #X -#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X) +#define FLATBUFFERS_VERSION_REVISION 0 +#define FLATBUFFERS_STRING_EXPAND(X) #X +#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X) namespace flatbuffers { // Returns version as string "MAJOR.MINOR.REVISION". const char* FLATBUFFERS_VERSION(); } - -#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \ - (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \ - defined(__clang__) - #define FLATBUFFERS_FINAL_CLASS final - #define FLATBUFFERS_OVERRIDE override + +#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \ + (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \ + defined(__clang__) + #define FLATBUFFERS_FINAL_CLASS final + #define FLATBUFFERS_OVERRIDE override #define FLATBUFFERS_EXPLICIT_CPP11 explicit #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : flatbuffers::voffset_t -#else - #define FLATBUFFERS_FINAL_CLASS - #define FLATBUFFERS_OVERRIDE +#else + #define FLATBUFFERS_FINAL_CLASS + #define FLATBUFFERS_OVERRIDE #define FLATBUFFERS_EXPLICIT_CPP11 #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE -#endif - -#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \ - (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ - (defined(__cpp_constexpr) && __cpp_constexpr >= 200704) - #define FLATBUFFERS_CONSTEXPR constexpr +#endif + +#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \ + (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ + (defined(__cpp_constexpr) && __cpp_constexpr >= 200704) + #define FLATBUFFERS_CONSTEXPR constexpr #define FLATBUFFERS_CONSTEXPR_CPP11 constexpr #define FLATBUFFERS_CONSTEXPR_DEFINED -#else +#else #define FLATBUFFERS_CONSTEXPR const #define FLATBUFFERS_CONSTEXPR_CPP11 -#endif - -#if (defined(__cplusplus) && __cplusplus >= 201402L) || \ - (defined(__cpp_constexpr) && __cpp_constexpr >= 201304) +#endif + +#if (defined(__cplusplus) && __cplusplus >= 201402L) || \ + (defined(__cpp_constexpr) && __cpp_constexpr >= 201304) #define FLATBUFFERS_CONSTEXPR_CPP14 FLATBUFFERS_CONSTEXPR_CPP11 -#else - #define FLATBUFFERS_CONSTEXPR_CPP14 -#endif - -#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ - (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023026)) || \ - defined(__clang__) - #define FLATBUFFERS_NOEXCEPT noexcept -#else - #define FLATBUFFERS_NOEXCEPT -#endif - -// NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to -// private, so be sure to put it at the end or reset access mode explicitly. -#if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \ - (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) || \ - defined(__clang__) +#else + #define FLATBUFFERS_CONSTEXPR_CPP14 +#endif + +#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ + (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023026)) || \ + defined(__clang__) + #define FLATBUFFERS_NOEXCEPT noexcept +#else + #define FLATBUFFERS_NOEXCEPT +#endif + +// NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to +// private, so be sure to put it at the end or reset access mode explicitly. +#if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \ + (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) || \ + defined(__clang__) #define FLATBUFFERS_DELETE_FUNC(func) func = delete -#else +#else #define FLATBUFFERS_DELETE_FUNC(func) private: func -#endif - +#endif + #if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \ (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \ defined(__clang__) @@ -218,24 +218,24 @@ namespace flatbuffers { #define FLATBUFFERS_TEMPLATES_ALIASES #endif -#ifndef FLATBUFFERS_HAS_STRING_VIEW - // Only provide flatbuffers::string_view if __has_include can be used - // to detect a header that provides an implementation - #if defined(__has_include) - // Check for std::string_view (in c++17) +#ifndef FLATBUFFERS_HAS_STRING_VIEW + // Only provide flatbuffers::string_view if __has_include can be used + // to detect a header that provides an implementation + #if defined(__has_include) + // Check for std::string_view (in c++17) #if __has_include(<string_view>) && (__cplusplus >= 201606 || (defined(_HAS_CXX17) && _HAS_CXX17)) - #include <string_view> - namespace flatbuffers { - typedef std::string_view string_view; - } - #define FLATBUFFERS_HAS_STRING_VIEW 1 - // Check for std::experimental::string_view (in c++14, compiler-dependent) - #elif __has_include(<experimental/string_view>) && (__cplusplus >= 201411) + #include <string_view> + namespace flatbuffers { + typedef std::string_view string_view; + } + #define FLATBUFFERS_HAS_STRING_VIEW 1 + // Check for std::experimental::string_view (in c++14, compiler-dependent) + #elif __has_include(<experimental/string_view>) && (__cplusplus >= 201411) #error #include <experimental/string_view> - namespace flatbuffers { - typedef std::experimental::string_view string_view; - } - #define FLATBUFFERS_HAS_STRING_VIEW 1 + namespace flatbuffers { + typedef std::experimental::string_view string_view; + } + #define FLATBUFFERS_HAS_STRING_VIEW 1 // Check for absl::string_view #elif __has_include("absl/strings/string_view.h") #error #include "absl/strings/string_view.h" @@ -243,10 +243,10 @@ namespace flatbuffers { typedef absl::string_view string_view; } #define FLATBUFFERS_HAS_STRING_VIEW 1 - #endif - #endif // __has_include -#endif // !FLATBUFFERS_HAS_STRING_VIEW - + #endif + #endif // __has_include +#endif // !FLATBUFFERS_HAS_STRING_VIEW + #ifndef FLATBUFFERS_HAS_NEW_STRTOD // Modern (C++11) strtod and strtof functions are available for use. // 1) nan/inf strings as argument of strtod; @@ -306,104 +306,104 @@ template<typename T> FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) { #endif #endif -/// @endcond - -/// @file -namespace flatbuffers { - -/// @cond FLATBUFFERS_INTERNAL -// Our default offset / size type, 32bit on purpose on 64bit systems. -// Also, using a consistent offset type maintains compatibility of serialized -// offset values between 32bit and 64bit systems. -typedef uint32_t uoffset_t; - -// Signed offsets for references that can go in both directions. -typedef int32_t soffset_t; - -// Offset/index used in v-tables, can be changed to uint8_t in -// format forks to save a bit of space if desired. -typedef uint16_t voffset_t; - -typedef uintmax_t largest_scalar_t; - -// In 32bits, this evaluates to 2GB - 1 +/// @endcond + +/// @file +namespace flatbuffers { + +/// @cond FLATBUFFERS_INTERNAL +// Our default offset / size type, 32bit on purpose on 64bit systems. +// Also, using a consistent offset type maintains compatibility of serialized +// offset values between 32bit and 64bit systems. +typedef uint32_t uoffset_t; + +// Signed offsets for references that can go in both directions. +typedef int32_t soffset_t; + +// Offset/index used in v-tables, can be changed to uint8_t in +// format forks to save a bit of space if desired. +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) - -// We support aligning the contents of buffers up to this size. -#define FLATBUFFERS_MAX_ALIGNMENT 16 - + +// We support aligning the contents of buffers up to this size. +#define FLATBUFFERS_MAX_ALIGNMENT 16 + inline bool VerifyAlignmentRequirements(size_t align, size_t min_align = 1) { return (min_align <= align) && (align <= (FLATBUFFERS_MAX_ALIGNMENT)) && (align & (align - 1)) == 0; // must be power of 2 } -#if defined(_MSC_VER) +#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 - -template<typename T> T EndianSwap(T t) { - #if defined(_MSC_VER) - #define FLATBUFFERS_BYTESWAP16 _byteswap_ushort - #define FLATBUFFERS_BYTESWAP32 _byteswap_ulong - #define FLATBUFFERS_BYTESWAP64 _byteswap_uint64 + #pragma warning(push) + #pragma warning(disable: 4127) // C4127: conditional expression is constant +#endif + +template<typename T> T EndianSwap(T t) { + #if defined(_MSC_VER) + #define FLATBUFFERS_BYTESWAP16 _byteswap_ushort + #define FLATBUFFERS_BYTESWAP32 _byteswap_ulong + #define FLATBUFFERS_BYTESWAP64 _byteswap_uint64 #elif defined(__ICCARM__) #define FLATBUFFERS_BYTESWAP16 __REV16 #define FLATBUFFERS_BYTESWAP32 __REV #define FLATBUFFERS_BYTESWAP64(x) \ ((__REV(static_cast<uint32_t>(x >> 32U))) | (static_cast<uint64_t>(__REV(static_cast<uint32_t>(x)))) << 32U) - #else - #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__) - // __builtin_bswap16 was missing prior to GCC 4.8. - #define FLATBUFFERS_BYTESWAP16(x) \ - static_cast<uint16_t>(__builtin_bswap32(static_cast<uint32_t>(x) << 16)) - #else - #define FLATBUFFERS_BYTESWAP16 __builtin_bswap16 - #endif - #define FLATBUFFERS_BYTESWAP32 __builtin_bswap32 - #define FLATBUFFERS_BYTESWAP64 __builtin_bswap64 - #endif - if (sizeof(T) == 1) { // Compile-time if-then's. - return t; - } else if (sizeof(T) == 2) { + #else + #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__) + // __builtin_bswap16 was missing prior to GCC 4.8. + #define FLATBUFFERS_BYTESWAP16(x) \ + static_cast<uint16_t>(__builtin_bswap32(static_cast<uint32_t>(x) << 16)) + #else + #define FLATBUFFERS_BYTESWAP16 __builtin_bswap16 + #endif + #define FLATBUFFERS_BYTESWAP32 __builtin_bswap32 + #define FLATBUFFERS_BYTESWAP64 __builtin_bswap64 + #endif + if (sizeof(T) == 1) { // Compile-time if-then's. + return t; + } else if (sizeof(T) == 2) { union { T t; uint16_t i; } u = { t }; - u.i = FLATBUFFERS_BYTESWAP16(u.i); - return u.t; - } else if (sizeof(T) == 4) { + u.i = FLATBUFFERS_BYTESWAP16(u.i); + return u.t; + } else if (sizeof(T) == 4) { union { T t; uint32_t i; } u = { t }; - u.i = FLATBUFFERS_BYTESWAP32(u.i); - return u.t; - } else if (sizeof(T) == 8) { + u.i = FLATBUFFERS_BYTESWAP32(u.i); + return u.t; + } else if (sizeof(T) == 8) { union { T t; uint64_t i; } u = { t }; - u.i = FLATBUFFERS_BYTESWAP64(u.i); - return u.t; - } else { - FLATBUFFERS_ASSERT(0); + u.i = FLATBUFFERS_BYTESWAP64(u.i); + return u.t; + } else { + FLATBUFFERS_ASSERT(0); + return t; + } +} + +#if defined(_MSC_VER) + #pragma warning(pop) +#endif + + +template<typename T> T EndianScalar(T t) { + #if FLATBUFFERS_LITTLEENDIAN return t; - } -} - -#if defined(_MSC_VER) - #pragma warning(pop) -#endif - - -template<typename T> T EndianScalar(T t) { - #if FLATBUFFERS_LITTLEENDIAN - return t; - #else - return EndianSwap(t); - #endif -} - + #else + return EndianSwap(t); + #endif +} + template<typename T> // UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. __supress_ubsan__("alignment") T ReadScalar(const void *p) { return EndianScalar(*reinterpret_cast<const T *>(p)); -} - +} + // See https://github.com/google/flatbuffers/issues/5950 #if (FLATBUFFERS_GCC >= 100000) && (FLATBUFFERS_GCC < 110000) @@ -415,9 +415,9 @@ template<typename T> // UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. __supress_ubsan__("alignment") void WriteScalar(void *p, T t) { - *reinterpret_cast<T *>(p) = EndianScalar(t); -} - + *reinterpret_cast<T *>(p) = EndianScalar(t); +} + template<typename T> struct Offset; template<typename T> __supress_ubsan__("alignment") void WriteScalar(void *p, Offset<T> t) { *reinterpret_cast<uoffset_t *>(p) = EndianScalar(t.o); @@ -427,13 +427,13 @@ template<typename T> __supress_ubsan__("alignment") void WriteScalar(void *p, Of #pragma GCC diagnostic pop #endif -// 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). +// 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") -inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) { - return ((~buf_size) + 1) & (scalar_size - 1); -} - -} // namespace flatbuffers -#endif // FLATBUFFERS_BASE_H_ +inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) { + return ((~buf_size) + 1) & (scalar_size - 1); +} + +} // namespace flatbuffers +#endif // FLATBUFFERS_BASE_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/code_generators.h b/contrib/libs/flatbuffers/include/flatbuffers/code_generators.h index f0c9612758..09b773a468 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/code_generators.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/code_generators.h @@ -1,74 +1,74 @@ -/* - * 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_CODE_GENERATORS_H_ -#define FLATBUFFERS_CODE_GENERATORS_H_ - -#include <map> -#include <sstream> +/* + * 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_CODE_GENERATORS_H_ +#define FLATBUFFERS_CODE_GENERATORS_H_ + +#include <map> +#include <sstream> #include "idl.h" - -namespace flatbuffers { - -// Utility class to assist in generating code through use of text templates. -// -// Example code: + +namespace flatbuffers { + +// Utility class to assist in generating code through use of text templates. +// +// Example code: // CodeWriter code("\t"); -// code.SetValue("NAME", "Foo"); -// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }"; -// code.SetValue("NAME", "Bar"); -// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }"; -// std::cout << code.ToString() << std::endl; -// -// Output: -// void Foo() { printf("%s", "Foo"); } -// void Bar() { printf("%s", "Bar"); } -class CodeWriter { - public: +// code.SetValue("NAME", "Foo"); +// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }"; +// code.SetValue("NAME", "Bar"); +// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }"; +// std::cout << code.ToString() << std::endl; +// +// Output: +// void Foo() { printf("%s", "Foo"); } +// void Bar() { printf("%s", "Bar"); } +class CodeWriter { + public: CodeWriter(std::string pad = std::string()) : pad_(pad), cur_ident_lvl_(0), ignore_ident_(false) {} - - // Clears the current "written" code. - void Clear() { - stream_.str(""); - stream_.clear(); - } - - // Associates a key with a value. All subsequent calls to operator+=, where - // the specified key is contained in {{ and }} delimiters will be replaced by - // the given value. - void SetValue(const std::string &key, const std::string &value) { - value_map_[key] = value; - } - + + // Clears the current "written" code. + void Clear() { + stream_.str(""); + stream_.clear(); + } + + // Associates a key with a value. All subsequent calls to operator+=, where + // the specified key is contained in {{ and }} delimiters will be replaced by + // the given value. + void SetValue(const std::string &key, const std::string &value) { + value_map_[key] = value; + } + std::string GetValue(const std::string &key) const { const auto it = value_map_.find(key); return it == value_map_.end() ? "" : it->second; } - // Appends the given text to the generated code as well as a newline + // Appends the given text to the generated code as well as a newline // character. Any text within {{ and }} delimiters is replaced by values - // previously stored in the CodeWriter by calling SetValue above. The newline - // will be suppressed if the text ends with the \\ character. - void operator+=(std::string text); - - // Returns the current contents of the CodeWriter as a std::string. - std::string ToString() const { return stream_.str(); } - + // previously stored in the CodeWriter by calling SetValue above. The newline + // will be suppressed if the text ends with the \\ character. + void operator+=(std::string text); + + // Returns the current contents of the CodeWriter as a std::string. + std::string ToString() const { return stream_.str(); } + // Increase ident level for writing code void IncrementIdentLevel() { cur_ident_lvl_++; } // Decrease ident level for writing code @@ -78,90 +78,90 @@ class CodeWriter { void SetPadding(const std::string &padding) { pad_ = padding; } - private: - std::map<std::string, std::string> value_map_; - std::stringstream stream_; + private: + std::map<std::string, std::string> value_map_; + std::stringstream stream_; std::string pad_; int cur_ident_lvl_; bool ignore_ident_; // Add ident padding (tab or space) based on ident level void AppendIdent(std::stringstream &stream); -}; - -class BaseGenerator { - public: - virtual bool generate() = 0; - - static std::string NamespaceDir(const Parser &parser, const std::string &path, +}; + +class BaseGenerator { + public: + virtual bool generate() = 0; + + static std::string NamespaceDir(const Parser &parser, const std::string &path, const Namespace &ns, const bool dasherize = false); - + static std::string ToDasherizedCase(const std::string pascal_case); std::string GeneratedFileName(const std::string &path, const std::string &file_name, const IDLOptions &options) const; - protected: - BaseGenerator(const Parser &parser, const std::string &path, + protected: + BaseGenerator(const Parser &parser, const std::string &path, const std::string &file_name, std::string qualifying_start, std::string qualifying_separator, std::string default_extension) - : parser_(parser), - path_(path), - file_name_(file_name), - qualifying_start_(qualifying_start), + : parser_(parser), + path_(path), + file_name_(file_name), + qualifying_start_(qualifying_start), qualifying_separator_(qualifying_separator), default_extension_(default_extension) {} - virtual ~BaseGenerator() {} - - // No copy/assign. - BaseGenerator &operator=(const BaseGenerator &); - BaseGenerator(const BaseGenerator &); - + virtual ~BaseGenerator() {} + + // No copy/assign. + BaseGenerator &operator=(const BaseGenerator &); + BaseGenerator(const BaseGenerator &); + std::string NamespaceDir(const Namespace &ns, const bool dasherize = false) const; - - static const char *FlatBuffersGeneratedWarning(); - - static std::string FullNamespace(const char *separator, const Namespace &ns); - - static std::string LastNamespacePart(const Namespace &ns); - - // tracks the current namespace for early exit in WrapInNameSpace - // c++, java and csharp returns a different namespace from - // the following default (no early exit, always fully qualify), - // which works for js and php - virtual const Namespace *CurrentNameSpace() const { return nullptr; } - + + static const char *FlatBuffersGeneratedWarning(); + + static std::string FullNamespace(const char *separator, const Namespace &ns); + + static std::string LastNamespacePart(const Namespace &ns); + + // tracks the current namespace for early exit in WrapInNameSpace + // c++, java and csharp returns a different namespace from + // the following default (no early exit, always fully qualify), + // which works for js and php + virtual const Namespace *CurrentNameSpace() const { return nullptr; } + // Ensure that a type is prefixed with its namespace even within // its own namespace to avoid conflict between generated method // names and similarly named classes or structs - std::string WrapInNameSpace(const Namespace *ns, - const std::string &name) const; - - std::string WrapInNameSpace(const Definition &def) const; - - std::string GetNameSpace(const Definition &def) const; - - const Parser &parser_; - const std::string &path_; - const std::string &file_name_; - const std::string qualifying_start_; - const std::string qualifying_separator_; + std::string WrapInNameSpace(const Namespace *ns, + const std::string &name) const; + + std::string WrapInNameSpace(const Definition &def) const; + + std::string GetNameSpace(const Definition &def) const; + + const Parser &parser_; + const std::string &path_; + const std::string &file_name_; + const std::string qualifying_start_; + const std::string qualifying_separator_; const std::string default_extension_; -}; - -struct CommentConfig { - const char *first_line; - const char *content_line_prefix; - const char *last_line; -}; - -extern void GenComment(const std::vector<std::string> &dc, - std::string *code_ptr, const CommentConfig *config, - const char *prefix = ""); - +}; + +struct CommentConfig { + const char *first_line; + const char *content_line_prefix; + const char *last_line; +}; + +extern void GenComment(const std::vector<std::string> &dc, + std::string *code_ptr, const CommentConfig *config, + const char *prefix = ""); + class FloatConstantGenerator { public: virtual ~FloatConstantGenerator() {} @@ -230,6 +230,6 @@ class TypedFloatConstantGenerator : public FloatConstantGenerator { const std::string neg_inf_number_; }; -} // namespace flatbuffers - -#endif // FLATBUFFERS_CODE_GENERATORS_H_ +} // namespace flatbuffers + +#endif // FLATBUFFERS_CODE_GENERATORS_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers.h b/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers.h index dbe838cc70..20935307a6 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers.h @@ -17,7 +17,7 @@ #ifndef FLATBUFFERS_H_ #define FLATBUFFERS_H_ -#include "base.h" +#include "base.h" #include "stl_emulation.h" #ifndef FLATBUFFERS_CPP98_STL @@ -63,25 +63,25 @@ inline bool IsInRange(const T &v, const T &low, const T &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). +// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset). template<typename T> struct Offset { uoffset_t o; Offset() : o(0) {} Offset(uoffset_t _o) : o(_o) {} Offset<void> Union() const { return Offset<void>(o); } - bool IsNull() const { return !o; } + bool IsNull() const { return !o; } }; inline void EndianCheck() { int endiantest = 1; // If this fails, see FLATBUFFERS_LITTLEENDIAN above. - FLATBUFFERS_ASSERT(*reinterpret_cast<char *>(&endiantest) == - FLATBUFFERS_LITTLEENDIAN); + FLATBUFFERS_ASSERT(*reinterpret_cast<char *>(&endiantest) == + FLATBUFFERS_LITTLEENDIAN); (void)endiantest; } -template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() { - // clang-format off +template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() { + // clang-format off #ifdef _MSC_VER return __alignof(T); #else @@ -91,7 +91,7 @@ template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() { return alignof(T); #endif #endif - // clang-format on + // clang-format on } // When we read serialized data from memory, in the case of most scalars, @@ -104,7 +104,7 @@ template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() { // (avoiding the need for a trailing return decltype) template<typename T> struct IndirectHelper { typedef T return_type; - typedef T mutable_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<const T *>(p))[i]); @@ -112,7 +112,7 @@ template<typename T> struct IndirectHelper { }; template<typename T> struct IndirectHelper<Offset<T>> { typedef const T *return_type; - typedef T *mutable_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); @@ -121,7 +121,7 @@ template<typename T> struct IndirectHelper<Offset<T>> { }; template<typename T> struct IndirectHelper<const T *> { typedef const T *return_type; - typedef T *mutable_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<const T *>(p + i * sizeof(T)); @@ -130,15 +130,15 @@ template<typename T> struct IndirectHelper<const T *> { // An STL compatible iterator implementation for Vector below, effectively // calling Get() for every element. -template<typename T, typename IT> 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<T>::element_stride * i) {} +template<typename T, typename IT> 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<T>::element_stride * i) {} VectorIterator(const VectorIterator &other) : data_(other.data_) {} VectorIterator() : data_(nullptr) {} @@ -156,29 +156,29 @@ template<typename T, typename IT> struct VectorIterator { #endif // !defined(FLATBUFFERS_CPP98_STL) // clang-format on - bool operator==(const VectorIterator &other) const { + 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 { + 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 { + difference_type operator-(const VectorIterator &other) const { return (data_ - other.data_) / IndirectHelper<T>::element_stride; } // Note: return type is incompatible with the standard // `reference operator*()`. - IT operator*() const { return IndirectHelper<T>::Read(data_, 0); } + IT operator*() const { return IndirectHelper<T>::Read(data_, 0); } // Note: return type is incompatible with the standard // `pointer operator->()`. - IT operator->() const { return IndirectHelper<T>::Read(data_, 0); } + IT operator->() const { return IndirectHelper<T>::Read(data_, 0); } VectorIterator &operator++() { data_ += IndirectHelper<T>::element_stride; @@ -186,17 +186,17 @@ template<typename T, typename IT> struct VectorIterator { } VectorIterator operator++(int) { - VectorIterator temp(data_, 0); + VectorIterator temp(data_, 0); data_ += IndirectHelper<T>::element_stride; return temp; } - VectorIterator operator+(const uoffset_t &offset) const { - return VectorIterator(data_ + offset * IndirectHelper<T>::element_stride, - 0); + VectorIterator operator+(const uoffset_t &offset) const { + return VectorIterator(data_ + offset * IndirectHelper<T>::element_stride, + 0); } - VectorIterator &operator+=(const uoffset_t &offset) { + VectorIterator &operator+=(const uoffset_t &offset) { data_ += offset * IndirectHelper<T>::element_stride; return *this; } @@ -207,22 +207,22 @@ template<typename T, typename IT> struct VectorIterator { } VectorIterator operator--(int) { - VectorIterator temp(data_, 0); + VectorIterator temp(data_, 0); data_ -= IndirectHelper<T>::element_stride; return temp; } VectorIterator operator-(const uoffset_t &offset) const { - return VectorIterator(data_ - offset * IndirectHelper<T>::element_stride, - 0); + return VectorIterator(data_ - offset * IndirectHelper<T>::element_stride, + 0); } - VectorIterator &operator-=(const uoffset_t &offset) { + VectorIterator &operator-=(const uoffset_t &offset) { data_ -= offset * IndirectHelper<T>::element_stride; return *this; } - private: + private: const uint8_t *data_; }; @@ -246,16 +246,16 @@ struct VectorReverseIterator : public std::reverse_iterator<Iterator> { } }; -struct String; - +struct String; + // This is used as a helper type for accessing vectors. // Vector::data() assumes the vector elements start after the length field. template<typename T> class Vector { - public: - typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type> - iterator; - typedef VectorIterator<T, typename IndirectHelper<T>::return_type> - const_iterator; + public: + typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type> + iterator; + typedef VectorIterator<T, typename IndirectHelper<T>::return_type> + const_iterator; typedef VectorReverseIterator<iterator> reverse_iterator; typedef VectorReverseIterator<const_iterator> const_reverse_iterator; @@ -266,11 +266,11 @@ template<typename T> class Vector { uoffset_t Length() const { return size(); } typedef typename IndirectHelper<T>::return_type return_type; - typedef typename IndirectHelper<T>::mutable_return_type mutable_return_type; + typedef typename IndirectHelper<T>::mutable_return_type mutable_return_type; typedef return_type value_type; return_type Get(uoffset_t i) const { - FLATBUFFERS_ASSERT(i < size()); + FLATBUFFERS_ASSERT(i < size()); return IndirectHelper<T>::Read(Data(), i); } @@ -283,18 +283,18 @@ template<typename T> class Vector { return static_cast<E>(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<typename U> const U *GetAs(uoffset_t i) const { - return reinterpret_cast<const U *>(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<const String *>(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<typename U> const U *GetAs(uoffset_t i) const { + return reinterpret_cast<const U *>(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<const String *>(Get(i)); + } + const void *GetStructFromOffset(size_t o) const { return reinterpret_cast<const void *>(Data() + o); } @@ -325,8 +325,8 @@ template<typename T> class Vector { // 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()); + void Mutate(uoffset_t i, const T &val) { + FLATBUFFERS_ASSERT(i < size()); WriteScalar(data() + i, val); } @@ -334,32 +334,32 @@ template<typename T> class Vector { // "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<uoffset_t>(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<mutable_return_type>(IndirectHelper<T>::Read(Data(), i)); - } - + FLATBUFFERS_ASSERT(i < size()); + static_assert(sizeof(T) == sizeof(uoffset_t), "Unrelated types"); + WriteScalar(data() + i, + static_cast<uoffset_t>(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<mutable_return_type>(IndirectHelper<T>::Read(Data(), i)); + } + // The raw data in little endian format. Use with care. const uint8_t *Data() const { return reinterpret_cast<const uint8_t *>(&length_ + 1); } - uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); } + uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); } // Similarly, but typed, much like std::vector::data const T *data() const { return reinterpret_cast<const T *>(Data()); } T *data() { return reinterpret_cast<T *>(Data()); } template<typename K> return_type LookupByKey(K key) const { - void *search_result = std::bsearch( - &key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>); + void *search_result = std::bsearch( + &key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>); if (!search_result) { return nullptr; // Key not found. @@ -370,19 +370,19 @@ template<typename T> class Vector { return IndirectHelper<T>::Read(element, 0); } - protected: + 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 &); + 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<typename K> static int KeyCompare(const void *ap, const void *bp) { const K *key = reinterpret_cast<const K *>(ap); const uint8_t *data = reinterpret_cast<const uint8_t *>(bp); @@ -397,40 +397,40 @@ template<typename T> class Vector { // 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: + public: uoffset_t size() const { return EndianScalar(length_); } const uint8_t *Data() const { return reinterpret_cast<const uint8_t *>(&length_ + 1); } - uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); } - - protected: + uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); } + + protected: VectorOfAny(); uoffset_t length_; - - private: - VectorOfAny(const VectorOfAny &); + + private: + VectorOfAny(const VectorOfAny &); VectorOfAny &operator=(const VectorOfAny &); }; -#ifndef FLATBUFFERS_CPP98_STL -template<typename T, typename U> -Vector<Offset<T>> *VectorCast(Vector<Offset<U>> *ptr) { - static_assert(std::is_base_of<T, U>::value, "Unrelated types"); - return reinterpret_cast<Vector<Offset<T>> *>(ptr); -} - -template<typename T, typename U> -const Vector<Offset<T>> *VectorCast(const Vector<Offset<U>> *ptr) { - static_assert(std::is_base_of<T, U>::value, "Unrelated types"); - return reinterpret_cast<const Vector<Offset<T>> *>(ptr); -} -#endif - +#ifndef FLATBUFFERS_CPP98_STL +template<typename T, typename U> +Vector<Offset<T>> *VectorCast(Vector<Offset<U>> *ptr) { + static_assert(std::is_base_of<T, U>::value, "Unrelated types"); + return reinterpret_cast<Vector<Offset<T>> *>(ptr); +} + +template<typename T, typename U> +const Vector<Offset<T>> *VectorCast(const Vector<Offset<U>> *ptr) { + static_assert(std::is_base_of<T, U>::value, "Unrelated types"); + return reinterpret_cast<const Vector<Offset<T>> *>(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). +// of whether it is null or not (the field is not set). template<typename T> static inline size_t VectorLength(const Vector<T> *v) { return v ? v->size() : 0; } @@ -629,31 +629,31 @@ struct String : public Vector<char> { const char *c_str() const { return reinterpret_cast<const char *>(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 { + // 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 { + } + #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. +// 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. + 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() : ""; -} - + 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. @@ -662,231 +662,231 @@ static inline flatbuffers::string_view GetStringView(const String *str) { } #endif // FLATBUFFERS_HAS_STRING_VIEW -// Allocator interface. This is flatbuffers-specific and meant only for -// `vector_downward` usage. -class Allocator { +// 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. + 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); - } + 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]; - } - +// 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<uint8_t *>(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) { +}; + +// 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) { +} + +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) {} - +} + +// 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(); - } + 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) { + 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; - } + 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 <class T> - bool Verify() const { - Verifier verifier(data(), size()); - return verifier.Verify<T>(nullptr); - } - - template <class T> - const T* GetRoot() const { - return flatbuffers::GetRoot<T>(data()); - } - - template <class T> - T* GetRoot() { - return flatbuffers::GetRoot<T>(data()); - } - #endif - // 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 <class T> + bool Verify() const { + Verifier verifier(data(), size()); + return verifier.Verify<T>(nullptr); + } + + template <class T> + const T* GetRoot() const { + return flatbuffers::GetRoot<T>(data()); + } + + template <class T> + T* GetRoot() { + return flatbuffers::GetRoot<T>(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 + // These may change access mode, leave these at end of public section FLATBUFFERS_DELETE_FUNC(DetachedBuffer(const DetachedBuffer &other)); - FLATBUFFERS_DELETE_FUNC( + 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; - } -}; - + + 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<uint8_t> 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. +// 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) {} - + : 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) + vector_downward(vector_downward &&other) #else vector_downward(vector_downward &other) #endif // defined(FLATBUFFERS_CPP98_STL) @@ -899,237 +899,237 @@ class vector_downward { 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; + // 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; - } + 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(); + clear_buffer(); + clear_allocator(); } - void reset() { - clear_buffer(); - clear(); - } - - void clear() { - if (buf_) { - cur_ = buf_ + reserved_; - } else { - reserved_ = 0; - cur_ = nullptr; - } - clear_scratch(); + 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; - } - + + 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<size_t>(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. - uint8_t *release_raw(size_t &allocated_bytes, size_t &offset) { - auto *buf = buf_; - allocated_bytes = reserved_; - offset = static_cast<size_t>(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; - } + 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; + clear(); + return fb; } - size_t ensure_space(size_t len) { - FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_); - if (len > static_cast<size_t>(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; + size_t ensure_space(size_t len) { + FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_); + if (len > static_cast<size_t>(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; + 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_; } - + // Returns nullptr if using the DefaultAllocator. + Allocator *get_custom_allocator() { return allocator_; } + uoffset_t size() const { return static_cast<uoffset_t>(reserved_ - static_cast<size_t>(cur_ - buf_)); } - uoffset_t scratch_size() const { - return static_cast<uoffset_t>(scratch_ - buf_); - } - - size_t capacity() const { return reserved_; } - + uoffset_t scratch_size() const { + return static_cast<uoffset_t>(scratch_ - buf_); + } + + size_t capacity() const { return reserved_; } + uint8_t *data() const { - FLATBUFFERS_ASSERT(cur_); + 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; } + 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<typename T> void push_small(const T &little_endian_t) { - make_space(sizeof(T)); - *reinterpret_cast<T *>(cur_) = little_endian_t; - } - - template<typename T> void scratch_push_small(const T &t) { - ensure_space(sizeof(T)); - *reinterpret_cast<T *>(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. + // Specialized version of push() that avoids memcpy call for small data. + template<typename T> void push_small(const T &little_endian_t) { + make_space(sizeof(T)); + *reinterpret_cast<T *>(cur_) = little_endian_t; + } + + template<typename T> void scratch_push_small(const T &t) { + ensure_space(sizeof(T)); + *reinterpret_cast<T *>(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; + 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. + // 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 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_); - } - + 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_; + 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(); + 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; - } + 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<voffset_t>((field_id + fixed_fields) * sizeof(voffset_t)); + return static_cast<voffset_t>((field_id + fixed_fields) * sizeof(voffset_t)); } -template<typename T, typename Alloc> -const T *data(const std::vector<T, Alloc> &v) { +template<typename T, typename Alloc> +const T *data(const std::vector<T, Alloc> &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<const T *>(&t) : &v.front(); } -template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &v) { +template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &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 *>(&t) : &v.front(); -} - +} + /// @endcond /// @addtogroup flatbuffers_cpp_api @@ -1141,103 +1141,103 @@ template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &v) { /// `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 { +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. + /// 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<largest_scalar_t>()) - : 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) { + : 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. + /// @brief Move constructor for FlatBufferBuilder. #if !defined(FLATBUFFERS_CPP98_STL) - FlatBufferBuilder(FlatBufferBuilder &&other) + FlatBufferBuilder(FlatBufferBuilder &&other) #else FlatBufferBuilder(FlatBufferBuilder &other) #endif // #if !defined(FLATBUFFERS_CPP98_STL) - : buf_(1024, nullptr, false, AlignOf<largest_scalar_t>()), - 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); - } + : buf_(1024, nullptr, false, AlignOf<largest_scalar_t>()), + 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; - } + /// @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 - } - + + 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(); + ClearOffsets(); buf_.clear(); nested = false; finished = false; minalign_ = 1; - if (string_pool) string_pool->clear(); + if (string_pool) string_pool->clear(); } /// @brief The current size of the serialized buffer, counting from the end. @@ -1266,45 +1266,45 @@ class FlatBufferBuilder { /// @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. + /// @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() { + 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. + /// @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`. + /// 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`. + /// `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. + 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_; - } - + Finished(); + return minalign_; + } + /// @cond FLATBUFFERS_INTERNAL void Finished() const { // If you get this assert, you're attempting to get access a buffer @@ -1312,7 +1312,7 @@ class FlatBufferBuilder { // FlatBufferBuilder::Finish with your root table. // If you really need to access an unfinished buffer, call // GetCurrentBufferPointer instead. - FLATBUFFERS_ASSERT(finished); + FLATBUFFERS_ASSERT(finished); } /// @endcond @@ -1323,19 +1323,19 @@ class FlatBufferBuilder { /// serialized. void ForceDefaults(bool fd) { force_defaults_ = fd; } - /// @brief By default vtables are deduped in order to save space. + /// @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; } - + 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 TrackMinAlign(size_t elem_size) { + if (elem_size > minalign_) minalign_ = elem_size; + } + void Align(size_t elem_size) { - TrackMinAlign(elem_size); + TrackMinAlign(elem_size); buf_.fill(PaddingBytes(buf_.size(), elem_size)); } @@ -1344,13 +1344,13 @@ class FlatBufferBuilder { finished = true; } - void PushBytes(const uint8_t *bytes, size_t size) { buf_.push(bytes, size); } + void PushBytes(const uint8_t *bytes, size_t size) { buf_.push(bytes, size); } void PopBytes(size_t amount) { buf_.pop(amount); } template<typename T> void AssertScalarT() { // The code assumes power of 2 sizes and endian-swap-ability. - static_assert(flatbuffers::is_scalar<T>::value, "T must be a scalar type"); + static_assert(flatbuffers::is_scalar<T>::value, "T must be a scalar type"); } // Write a single aligned scalar to the buffer @@ -1358,7 +1358,7 @@ class FlatBufferBuilder { AssertScalarT<T>(); T litle_endian_element = EndianScalar(element); Align(sizeof(T)); - buf_.push_small(litle_endian_element); + buf_.push_small(litle_endian_element); return GetSize(); } @@ -1371,9 +1371,9 @@ class FlatBufferBuilder { // 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); + buf_.scratch_push_small(fl); + num_field_loc++; + max_voffset_ = (std::max)(max_voffset_, field); } // Like PushElement, but additionally tracks the field this represents. @@ -1390,14 +1390,14 @@ class FlatBufferBuilder { } template<typename T> void AddOffset(voffset_t field, Offset<T> off) { - if (off.IsNull()) return; // Don't store. + if (off.IsNull()) return; // Don't store. AddElement(field, ReferTo(off.o), static_cast<uoffset_t>(0)); } template<typename T> void AddStruct(voffset_t field, const T *structptr) { if (!structptr) return; // Default, don't store. Align(AlignOf<T>()); - buf_.push_small(*structptr); + buf_.push_small(*structptr); TrackField(field, GetSize()); } @@ -1412,8 +1412,8 @@ class FlatBufferBuilder { // 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<uoffset_t>(sizeof(uoffset_t)); + FLATBUFFERS_ASSERT(off && off <= GetSize()); + return GetSize() - off + static_cast<uoffset_t>(sizeof(uoffset_t)); } void NotNested() { @@ -1425,9 +1425,9 @@ class FlatBufferBuilder { // 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); + 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 @@ -1441,57 +1441,57 @@ class FlatBufferBuilder { // 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) { + uoffset_t EndTable(uoffset_t start) { // If you get this assert, a corresponding StartTable wasn't called. - FLATBUFFERS_ASSERT(nested); + FLATBUFFERS_ASSERT(nested); // Write the vtable offset, which is the start of any Table. // We fill it's value later. auto vtableoffsetloc = PushElement<soffset_t>(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<voffset_t>(max_voffset_ + sizeof(voffset_t)), - FieldIndexToOffset(0)); - buf_.fill_big(max_voffset_); + // Include space for the last offset and ensure empty tables have a + // minimum size. + max_voffset_ = + (std::max)(static_cast<voffset_t>(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<voffset_t>(buf_.data() + sizeof(voffset_t), - static_cast<voffset_t>(table_object_size)); - WriteScalar<voffset_t>(buf_.data(), max_voffset_); + // Vtable use 16bit offsets. + FLATBUFFERS_ASSERT(table_object_size < 0x10000); + WriteScalar<voffset_t>(buf_.data() + sizeof(voffset_t), + static_cast<voffset_t>(table_object_size)); + WriteScalar<voffset_t>(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<FieldLoc *>(it); + for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc); + it < buf_.scratch_end(); it += sizeof(FieldLoc)) { + auto field_location = reinterpret_cast<FieldLoc *>(it); auto pos = static_cast<voffset_t>(vtableoffsetloc - field_location->off); // If this asserts, it means you've set a field twice. - FLATBUFFERS_ASSERT( - !ReadScalar<voffset_t>(buf_.data() + field_location->id)); + FLATBUFFERS_ASSERT( + !ReadScalar<voffset_t>(buf_.data() + field_location->id)); WriteScalar<voffset_t>(buf_.data() + field_location->id, pos); } - ClearOffsets(); + ClearOffsets(); auto vt1 = reinterpret_cast<voffset_t *>(buf_.data()); auto vt1_size = ReadScalar<voffset_t>(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<uoffset_t *>(it); - auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr)); + if (dedup_vtables_) { + for (auto it = buf_.scratch_data(); it < buf_.scratch_end(); + it += sizeof(uoffset_t)) { + auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it); + auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr)); auto vt2_size = ReadScalar<voffset_t>(vt2); if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue; - vt_use = *vt_offset_ptr; - buf_.pop(GetSize() - vtableoffsetloc); - break; - } + 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); } + 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. @@ -1499,20 +1499,20 @@ class FlatBufferBuilder { // flexibility (storing all vtables at the start of the file). WriteScalar(buf_.data_at(vtableoffsetloc), static_cast<soffset_t>(vt_use) - - static_cast<soffset_t>(vtableoffsetloc)); + static_cast<soffset_t>(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); - } - + 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<typename T> void Required(Offset<T> table, voffset_t field); + template<typename T> void Required(Offset<T> table, voffset_t field); uoffset_t StartStruct(size_t alignment) { Align(alignment); @@ -1521,16 +1521,16 @@ class FlatBufferBuilder { uoffset_t EndStruct() { return GetSize(); } - void ClearOffsets() { - buf_.scratch_pop(num_field_loc * sizeof(FieldLoc)); - num_field_loc = 0; - max_voffset_ = 0; - } + 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); + TrackMinAlign(alignment); buf_.fill(PaddingBytes(GetSize() + len, alignment)); } template<typename T> void PreAlign(size_t len) { @@ -1552,20 +1552,20 @@ class FlatBufferBuilder { return Offset<String>(GetSize()); } - /// @brief Store a string in the buffer, which is null-terminated. + /// @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<String> 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<String> CreateString(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<String> 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. @@ -1573,57 +1573,57 @@ class FlatBufferBuilder { return CreateString(str.c_str(), str.length()); } - // clang-format off - #ifdef FLATBUFFERS_HAS_STRING_VIEW + // 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<String> 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 string_view to copy in to the buffer. - /// @return Returns the offset in the buffer where the string starts. - Offset<String> 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<String> 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<typename T> Offset<String> CreateString(const T &str) { + /// @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<typename T> Offset<String> CreateString(const T &str) { return CreateString(str.data(), 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<String> 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; - } - + } + + /// @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<String> 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, @@ -1634,37 +1634,37 @@ class FlatBufferBuilder { 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<String> 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<String> CreateSharedString(const std::string &str) { - return CreateSharedString(str.c_str(), str.length()); - } + /// @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<String> 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<String> 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<String> CreateSharedString(const String *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 pointer to a `String` struct to add to the buffer. + /// @return Returns the offset in the buffer where the string starts + Offset<String> 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. + FLATBUFFERS_ASSERT(nested); // Hit if no corresponding StartVector. nested = false; return PushElement(static_cast<uoffset_t>(len)); } @@ -1686,12 +1686,12 @@ class FlatBufferBuilder { PreAlign(len * elemsize, alignment); } - // Similar to ForceVectorAlignment but for String fields. - void ForceStringAlignment(size_t len, size_t 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); + PreAlign((len + 1) * sizeof(char), alignment); } - + /// @endcond /// @brief Serialize an array into a FlatBuffer `vector`. @@ -1702,32 +1702,32 @@ class FlatBufferBuilder { /// @return Returns a typed `Offset` into the serialized data indicating /// where the vector is stored. template<typename T> Offset<Vector<T>> 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<T>(); + // If this assert hits, you're specifying a template argument that is + // causing the wrong overload to be selected, remove it. + AssertScalarT<T>(); StartVector(len, sizeof(T)); if (len == 0) { return Offset<Vector<T>>(EndVector(len)); } - // clang-format off - #if FLATBUFFERS_LITTLEENDIAN - PushBytes(reinterpret_cast<const uint8_t *>(v), len * sizeof(T)); - #else - if (sizeof(T) == 1) { - PushBytes(reinterpret_cast<const uint8_t *>(v), len); - } else { - for (auto i = len; i > 0; ) { - PushElement(v[--i]); - } - } - #endif - // clang-format on - return Offset<Vector<T>>(EndVector(len)); - } - - template<typename T> - Offset<Vector<Offset<T>>> CreateVector(const Offset<T> *v, size_t len) { - StartVector(len, sizeof(Offset<T>)); - for (auto i = len; i > 0;) { PushElement(v[--i]); } - return Offset<Vector<Offset<T>>>(EndVector(len)); + // clang-format off + #if FLATBUFFERS_LITTLEENDIAN + PushBytes(reinterpret_cast<const uint8_t *>(v), len * sizeof(T)); + #else + if (sizeof(T) == 1) { + PushBytes(reinterpret_cast<const uint8_t *>(v), len); + } else { + for (auto i = len; i > 0; ) { + PushElement(v[--i]); + } + } + #endif + // clang-format on + return Offset<Vector<T>>(EndVector(len)); + } + + template<typename T> + Offset<Vector<Offset<T>>> CreateVector(const Offset<T> *v, size_t len) { + StartVector(len, sizeof(Offset<T>)); + for (auto i = len; i > 0;) { PushElement(v[--i]); } + return Offset<Vector<Offset<T>>>(EndVector(len)); } /// @brief Serialize a `std::vector` into a FlatBuffer `vector`. @@ -1737,67 +1737,67 @@ class FlatBufferBuilder { /// @return Returns a typed `Offset` into the serialized data indicating /// where the vector is stored. template<typename T> Offset<Vector<T>> CreateVector(const std::vector<T> &v) { - return CreateVector(data(v), v.size()); - } - - // vector<bool> 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<Vector<uint8_t>> CreateVector(const std::vector<bool> &v) { - StartVector(v.size(), sizeof(uint8_t)); - for (auto i = v.size(); i > 0;) { - PushElement(static_cast<uint8_t>(v[--i])); - } - return Offset<Vector<uint8_t>>(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<typename T> Offset<Vector<T>> CreateVector(size_t vector_size, - const std::function<T (size_t i)> &f) { - std::vector<T> 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<typename T, typename F, typename S> - Offset<Vector<T>> CreateVector(size_t vector_size, F f, S *state) { - std::vector<T> 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<std::string>` 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<Vector<Offset<String>>> CreateVectorOfStrings( - const std::vector<std::string> &v) { - std::vector<Offset<String>> offsets(v.size()); - for (size_t i = 0; i < v.size(); i++) offsets[i] = CreateString(v[i]); - return CreateVector(offsets); - } - + return CreateVector(data(v), v.size()); + } + + // vector<bool> 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<Vector<uint8_t>> CreateVector(const std::vector<bool> &v) { + StartVector(v.size(), sizeof(uint8_t)); + for (auto i = v.size(); i > 0;) { + PushElement(static_cast<uint8_t>(v[--i])); + } + return Offset<Vector<uint8_t>>(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<typename T> Offset<Vector<T>> CreateVector(size_t vector_size, + const std::function<T (size_t i)> &f) { + std::vector<T> 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<typename T, typename F, typename S> + Offset<Vector<T>> CreateVector(size_t vector_size, F f, S *state) { + std::vector<T> 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<std::string>` 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<Vector<Offset<String>>> CreateVectorOfStrings( + const std::vector<std::string> &v) { + std::vector<Offset<String>> 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 @@ -1805,24 +1805,24 @@ class FlatBufferBuilder { /// @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<typename T> - Offset<Vector<const T *>> CreateVectorOfStructs(const T *v, size_t len) { + template<typename T> + Offset<Vector<const T *>> CreateVectorOfStructs(const T *v, size_t len) { StartVector(len * sizeof(T) / AlignOf<T>(), AlignOf<T>()); PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len); return Offset<Vector<const T *>>(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. + /// @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<typename T, typename S> + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template<typename T, typename S> Offset<Vector<const T *>> CreateVectorOfNativeStructs( const S *v, size_t len, T((*const pack_func)(const S &))) { FLATBUFFERS_ASSERT(pack_func); @@ -1840,78 +1840,78 @@ class FlatBufferBuilder { /// @return Returns a typed `Offset` into the serialized data indicating /// where the vector is stored. template<typename T, typename S> - Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v, - size_t len) { - extern T Pack(const S &); + Offset<Vector<const T *>> 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. + } + + // 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<typename T> Offset<Vector<const T *>> CreateVectorOfStructs( - size_t vector_size, const std::function<void(size_t i, T *)> &filler) { - T* structs = StartVectorOfStructs<T>(vector_size); - for (size_t i = 0; i < vector_size; i++) { - filler(i, structs); - structs++; - } - return EndVectorOfStructs<T>(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<typename T, typename F, typename S> - Offset<Vector<const T *>> CreateVectorOfStructs(size_t vector_size, F f, - S *state) { - T *structs = StartVectorOfStructs<T>(vector_size); - for (size_t i = 0; i < vector_size; i++) { - f(i, structs, state); - structs++; - } - return EndVectorOfStructs<T>(vector_size); - } - + /// 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<typename T> Offset<Vector<const T *>> CreateVectorOfStructs( + size_t vector_size, const std::function<void(size_t i, T *)> &filler) { + T* structs = StartVectorOfStructs<T>(vector_size); + for (size_t i = 0; i < vector_size; i++) { + filler(i, structs); + structs++; + } + return EndVectorOfStructs<T>(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<typename T, typename F, typename S> + Offset<Vector<const T *>> CreateVectorOfStructs(size_t vector_size, F f, + S *state) { + T *structs = StartVectorOfStructs<T>(vector_size); + for (size_t i = 0; i < vector_size; i++) { + f(i, structs, state); + structs++; + } + return EndVectorOfStructs<T>(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<typename T, typename Alloc> - Offset<Vector<const T *>> CreateVectorOfStructs( - const std::vector<T, Alloc> &v) { - return CreateVectorOfStructs(data(v), v.size()); + template<typename T, typename Alloc> + Offset<Vector<const T *>> CreateVectorOfStructs( + const std::vector<T, Alloc> &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. + /// @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`. + /// 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<typename T, typename S> - Offset<Vector<const T *>> CreateVectorOfNativeStructs( + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template<typename T, typename S> + Offset<Vector<const T *>> CreateVectorOfNativeStructs( const std::vector<S> &v, T((*const pack_func)(const S &))) { return CreateVectorOfNativeStructs<T, S>(data(v), v.size(), pack_func); } @@ -1926,92 +1926,92 @@ class FlatBufferBuilder { /// where the vector is stored. template<typename T, typename S> Offset<Vector<const T *>> CreateVectorOfNativeStructs( - const std::vector<S> &v) { - return CreateVectorOfNativeStructs<T, S>(data(v), v.size()); - } - + const std::vector<S> &v) { + return CreateVectorOfNativeStructs<T, S>(data(v), v.size()); + } + /// @cond FLATBUFFERS_INTERNAL - template<typename T> struct StructKeyComparator { - bool operator()(const T &a, const T &b) const { - return a.KeyCompareLessThan(&b); - } - + template<typename T> 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. + }; + /// @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<typename T> - Offset<Vector<const T *>> CreateVectorOfSortedStructs(std::vector<T> *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. + /// serialize into the buffer as a `vector`. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template<typename T> + Offset<Vector<const T *>> CreateVectorOfSortedStructs(std::vector<T> *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<typename T, typename S> - Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs( - std::vector<S> *v) { - return CreateVectorOfSortedNativeStructs<T, S>(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<typename T> - Offset<Vector<const T *>> CreateVectorOfSortedStructs(T *v, size_t len) { - std::sort(v, v + len, StructKeyComparator<T>()); - 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<typename T, typename S> - Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(S *v, - size_t len) { - extern T Pack(const S &); - typedef T (*Pack_t)(const S &); - std::vector<T> vv(len); + /// serialize into the buffer as a `vector`. + /// @return Returns a typed `Offset` into the serialized data indicating + /// where the vector is stored. + template<typename T, typename S> + Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs( + std::vector<S> *v) { + return CreateVectorOfSortedNativeStructs<T, S>(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<typename T> + Offset<Vector<const T *>> CreateVectorOfSortedStructs(T *v, size_t len) { + std::sort(v, v + len, StructKeyComparator<T>()); + 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<typename T, typename S> + Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(S *v, + size_t len) { + extern T Pack(const S &); + typedef T (*Pack_t)(const S &); + std::vector<T> vv(len); std::transform(v, v + len, vv.begin(), static_cast<Pack_t &>(Pack)); - return CreateVectorOfSortedStructs<T>(vv, len); - } - - /// @cond FLATBUFFERS_INTERNAL - template<typename T> struct TableKeyComparator { - TableKeyComparator(vector_downward &buf) : buf_(buf) {} + return CreateVectorOfSortedStructs<T>(vv, len); + } + + /// @cond FLATBUFFERS_INTERNAL + template<typename T> struct TableKeyComparator { + TableKeyComparator(vector_downward &buf) : buf_(buf) {} TableKeyComparator(const TableKeyComparator &other) : buf_(other.buf_) {} bool operator()(const Offset<T> &a, const Offset<T> &b) const { auto table_a = reinterpret_cast<T *>(buf_.data_at(a.o)); auto table_b = reinterpret_cast<T *>(buf_.data_at(b.o)); return table_a->KeyCompareLessThan(table_b); } - vector_downward &buf_; + vector_downward &buf_; - private: + private: FLATBUFFERS_DELETE_FUNC( TableKeyComparator &operator=(const TableKeyComparator &other)); }; @@ -2025,9 +2025,9 @@ class FlatBufferBuilder { /// @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<typename T> - Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(Offset<T> *v, - size_t len) { + template<typename T> + Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(Offset<T> *v, + size_t len) { std::sort(v, v + len, TableKeyComparator<T>(buf_)); return CreateVector(v, len); } @@ -2039,10 +2039,10 @@ class FlatBufferBuilder { /// 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<typename T> - Offset<Vector<Offset<T>>> CreateVectorOfSortedTables( - std::vector<Offset<T>> *v) { - return CreateVectorOfSortedTables(data(*v), v->size()); + template<typename T> + Offset<Vector<Offset<T>>> CreateVectorOfSortedTables( + std::vector<Offset<T>> *v) { + return CreateVectorOfSortedTables(data(*v), v->size()); } /// @brief Specialized version of `CreateVector` for non-copying use cases. @@ -2056,11 +2056,11 @@ class FlatBufferBuilder { 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; + 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. @@ -2071,20 +2071,20 @@ class FlatBufferBuilder { /// @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<typename T> - Offset<Vector<T>> CreateUninitializedVector(size_t len, T **buf) { - AssertScalarT<T>(); + template<typename T> + Offset<Vector<T>> CreateUninitializedVector(size_t len, T **buf) { + AssertScalarT<T>(); return CreateUninitializedVector(len, sizeof(T), reinterpret_cast<uint8_t **>(buf)); } - template<typename T> + template<typename T> Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len, T **buf) { - return CreateUninitializedVector(len, sizeof(T), - reinterpret_cast<uint8_t **>(buf)); - } - + return CreateUninitializedVector(len, sizeof(T), + reinterpret_cast<uint8_t **>(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. @@ -2097,61 +2097,61 @@ class FlatBufferBuilder { return Offset<Vector<T>>(EndVector(len)); } - /// @brief Write a struct by itself, typically to be part of a union. - template<typename T> Offset<const T *> CreateStruct(const T &structobj) { - NotNested(); - Align(AlignOf<T>()); - buf_.push_small(structobj); - return Offset<const T *>(GetSize()); - } - + /// @brief Write a struct by itself, typically to be part of a union. + template<typename T> Offset<const T *> CreateStruct(const T &structobj) { + NotNested(); + Align(AlignOf<T>()); + buf_.push_small(structobj); + return Offset<const T *>(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<typename T> - void Finish(Offset<T> 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<typename T> - void FinishSizePrefixed(Offset<T> root, - const char *file_identifier = nullptr) { - Finish(root.o, file_identifier, true); - } - + template<typename T> + void Finish(Offset<T> 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<typename T> + void FinishSizePrefixed(Offset<T> 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) { + 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(); + 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), + 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<const uint8_t *>(file_identifier), + FLATBUFFERS_ASSERT(strlen(file_identifier) == kFileIdentifierLength); + PushBytes(reinterpret_cast<const uint8_t *>(file_identifier), kFileIdentifierLength); } - PushElement(ReferTo(root)); // Location of root. - if (size_prefix) { PushElement(GetSize()); } + PushElement(ReferTo(root)); // Location of root. + if (size_prefix) { PushElement(GetSize()); } finished = true; } @@ -2163,11 +2163,11 @@ class FlatBufferBuilder { 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_; + // 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; @@ -2178,38 +2178,38 @@ class FlatBufferBuilder { 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<String> &a, const Offset<String> &b) const { - auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o)); - auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o)); + + bool dedup_vtables_; + + struct StringOffsetCompare { + StringOffsetCompare(const vector_downward &buf) : buf_(&buf) {} + bool operator()(const Offset<String> &a, const Offset<String> &b) const { + auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o)); + auto strb = reinterpret_cast<const String *>(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<Offset<String>, StringOffsetCompare> StringOffsetMap; - StringOffsetMap *string_pool; - - private: - // Allocates space for a vector of structures. - // Must be completed with EndVectorOfStructs(). - template<typename T> T *StartVectorOfStructs(size_t vector_size) { - StartVector(vector_size * sizeof(T) / AlignOf<T>(), AlignOf<T>()); - return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T))); - } - - // End the vector of structues in the flatbuffers. - // Vector should have previously be started with StartVectorOfStructs(). - template<typename T> - Offset<Vector<const T *>> EndVectorOfStructs(size_t vector_size) { - return Offset<Vector<const T *>>(EndVector(vector_size)); - } + } + const vector_downward *buf_; + }; + + // For use with CreateSharedString. Instantiated on first use only. + typedef std::set<Offset<String>, StringOffsetCompare> StringOffsetMap; + StringOffsetMap *string_pool; + + private: + // Allocates space for a vector of structures. + // Must be completed with EndVectorOfStructs(). + template<typename T> T *StartVectorOfStructs(size_t vector_size) { + StartVector(vector_size * sizeof(T) / AlignOf<T>(), AlignOf<T>()); + return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T))); + } + + // End the vector of structues in the flatbuffers. + // Vector should have previously be started with StartVectorOfStructs(). + template<typename T> + Offset<Vector<const T *>> EndVectorOfStructs(size_t vector_size) { + return Offset<Vector<const T *>>(EndVector(vector_size)); + } }; /// @} @@ -2217,102 +2217,102 @@ class FlatBufferBuilder { // Helpers to get a typed pointer to the root object contained in the buffer. template<typename T> T *GetMutableRoot(void *buf) { EndianCheck(); - return reinterpret_cast<T *>( - reinterpret_cast<uint8_t *>(buf) + - EndianScalar(*reinterpret_cast<uoffset_t *>(buf))); + return reinterpret_cast<T *>( + reinterpret_cast<uint8_t *>(buf) + + EndianScalar(*reinterpret_cast<uoffset_t *>(buf))); } template<typename T> const T *GetRoot(const void *buf) { return GetMutableRoot<T>(const_cast<void *>(buf)); } -template<typename T> const T *GetSizePrefixedRoot(const void *buf) { - return GetRoot<T>(reinterpret_cast<const uint8_t *>(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<typename T> -T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) { - return reinterpret_cast<T *>(fbb.GetCurrentBufferPointer() + fbb.GetSize() - - offset.o); -} - -template<typename T> -const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) { - return GetMutableTemporaryPointer<T>(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). +template<typename T> const T *GetSizePrefixedRoot(const void *buf) { + return GetRoot<T>(reinterpret_cast<const uint8_t *>(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<typename T> +T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) { + return reinterpret_cast<T *>(fbb.GetCurrentBufferPointer() + fbb.GetSize() - + offset.o); +} + +template<typename T> +const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) { + return GetMutableTemporaryPointer<T>(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<const char *>(buf) + - ((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t)); -} - + return reinterpret_cast<const char *>(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; + 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, + 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), + : 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 + // clang-format off #ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE - FLATBUFFERS_ASSERT(ok); + FLATBUFFERS_ASSERT(ok); + #endif + #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE + if (!ok) + upper_bound_ = 0; #endif - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - if (!ok) - upper_bound_ = 0; - #endif - // clang-format on + // 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<typename T> bool VerifyAlignment(size_t elem) const { + 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<typename T> bool VerifyAlignment(size_t elem) const { return Check((elem & (sizeof(T) - 1)) == 0 || !check_alignment_); - } - + } + // Verify a range indicated by sizeof(T). - template<typename T> bool Verify(size_t elem) const { - return VerifyAlignment<T>(elem) && Verify(elem, sizeof(T)); + template<typename T> bool Verify(size_t elem) const { + return VerifyAlignment<T>(elem) && Verify(elem, sizeof(T)); } bool VerifyFromPointer(const uint8_t *p, size_t len) { @@ -2320,35 +2320,35 @@ class Verifier FLATBUFFERS_FINAL_CLASS { 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<size_t>(base - buf_) + elem_off, elem_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<size_t>(base - buf_) + elem_off, elem_len); + } + template<typename T> bool Verify(const uint8_t *base, voffset_t elem_off) const { - return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T)); - } - + return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T)); + } + // Verify a pointer (may be NULL) of a table type. template<typename T> bool VerifyTable(const T *table) { return !table || table->Verify(*this); } // Verify a pointer (may be NULL) of any vector type. - template<typename T> bool VerifyVector(const Vector<T> *vec) const { - return !vec || VerifyVectorOrString(reinterpret_cast<const uint8_t *>(vec), - sizeof(T)); + template<typename T> bool VerifyVector(const Vector<T> *vec) const { + return !vec || VerifyVectorOrString(reinterpret_cast<const uint8_t *>(vec), + sizeof(T)); } // Verify a pointer (may be NULL) of a vector to struct. - template<typename T> bool VerifyVector(const Vector<const T *> *vec) const { - return VerifyVector(reinterpret_cast<const Vector<T> *>(vec)); + template<typename T> bool VerifyVector(const Vector<const T *> *vec) const { + return VerifyVector(reinterpret_cast<const Vector<T> *>(vec)); } // Verify a pointer (may be NULL) to string. - bool VerifyString(const String *str) const { - size_t end; + bool VerifyString(const String *str) const { + size_t end; return !str || (VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str), 1, &end) && Verify(end, 1) && // Must have terminator @@ -2356,30 +2356,30 @@ class Verifier FLATBUFFERS_FINAL_CLASS { } // Common code between vectors and strings. - bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size, + bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size, size_t *end = nullptr) const { - auto veco = static_cast<size_t>(vec - buf_); + auto veco = static_cast<size_t>(vec - buf_); // Check we can read the size field. - if (!Verify<uoffset_t>(veco)) return false; + if (!Verify<uoffset_t>(veco)) return false; // Check the whole array. If this is a string, the byte past the array // must be 0. auto size = ReadScalar<uoffset_t>(vec); - auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size; - if (!Check(size < max_elems)) - return false; // Protect against byte_size overflowing. + 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); + 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<Offset<String>> *vec) const { - if (vec) { - for (uoffset_t i = 0; i < vec->size(); i++) { - if (!VerifyString(vec->Get(i))) return false; + if (vec) { + for (uoffset_t i = 0; i < vec->size(); i++) { + if (!VerifyString(vec->Get(i))) return false; } - } - return true; + } + return true; } // Special case for table contents, after the above has been called. @@ -2394,66 +2394,66 @@ class Verifier FLATBUFFERS_FINAL_CLASS { __supress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart( const uint8_t *table) { - // Check the vtable offset. - auto tableo = static_cast<size_t>(table - buf_); - if (!Verify<soffset_t>(tableo)) return false; + // Check the vtable offset. + auto tableo = static_cast<size_t>(table - buf_); + if (!Verify<soffset_t>(tableo)) return false; // This offset may be signed, but doing the subtraction unsigned always - // gives the result we want. - auto vtableo = tableo - static_cast<size_t>(ReadScalar<soffset_t>(table)); - // Check the vtable size field, then check vtable fits in its entirety. - return VerifyComplexity() && Verify<voffset_t>(vtableo) && - VerifyAlignment<voffset_t>(ReadScalar<voffset_t>(buf_ + vtableo)) && - Verify(vtableo, ReadScalar<voffset_t>(buf_ + vtableo)); - } - - template<typename T> - bool VerifyBufferFromStart(const char *identifier, size_t start) { + // gives the result we want. + auto vtableo = tableo - static_cast<size_t>(ReadScalar<soffset_t>(table)); + // Check the vtable size field, then check vtable fits in its entirety. + return VerifyComplexity() && Verify<voffset_t>(vtableo) && + VerifyAlignment<voffset_t>(ReadScalar<voffset_t>(buf_ + vtableo)) && + Verify(vtableo, ReadScalar<voffset_t>(buf_ + vtableo)); + } + + template<typename T> + 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<const T *>(buf_ + start + o)->Verify(*this) - // clang-format off - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - && GetComputedSize() - #endif - ; - // clang-format on - } - + return false; + } + + // Call T::Verify, which must be in the generated code for this type. + auto o = VerifyOffset(start); + return o && reinterpret_cast<const T *>(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<typename T> bool VerifyBuffer() { return VerifyBuffer<T>(nullptr); } - - template<typename T> bool VerifyBuffer(const char *identifier) { - return VerifyBufferFromStart<T>(identifier, 0); - } - - template<typename T> bool VerifySizePrefixedBuffer(const char *identifier) { - return Verify<uoffset_t>(0U) && - ReadScalar<uoffset_t>(buf_) == size_ - sizeof(uoffset_t) && - VerifyBufferFromStart<T>(identifier, sizeof(uoffset_t)); - } - - uoffset_t VerifyOffset(size_t start) const { - if (!Verify<uoffset_t>(start)) return 0; - auto o = ReadScalar<uoffset_t>(buf_ + start); - // May not point to itself. + template<typename T> bool VerifyBuffer() { return VerifyBuffer<T>(nullptr); } + + template<typename T> bool VerifyBuffer(const char *identifier) { + return VerifyBufferFromStart<T>(identifier, 0); + } + + template<typename T> bool VerifySizePrefixedBuffer(const char *identifier) { + return Verify<uoffset_t>(0U) && + ReadScalar<uoffset_t>(buf_) == size_ - sizeof(uoffset_t) && + VerifyBufferFromStart<T>(identifier, sizeof(uoffset_t)); + } + + uoffset_t VerifyOffset(size_t start) const { + if (!Verify<uoffset_t>(start)) return 0; + auto o = ReadScalar<uoffset_t>(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<soffset_t>(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<size_t>(base - buf_) + start); - } - + // Can't wrap around / buffers are max 2GB. + if (!Check(static_cast<soffset_t>(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<size_t>(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 @@ -2470,8 +2470,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS { return true; } - // Returns the message size in bytes - size_t GetComputedSize() const { + // Returns the message size in bytes + size_t GetComputedSize() const { // clang-format off #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE uintptr_t size = upper_bound_; @@ -2485,44 +2485,44 @@ class Verifier FLATBUFFERS_FINAL_CLASS { 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_; + 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<typename T> 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<T>(buf); } - - bool Verify() { - Verifier verifier(buf, len); - return verifier.VerifyBuffer<T>(nullptr); - } - - uint8_t *buf; - uoffset_t len; - bool must_free; -}; - +// 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<typename T> 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<T>(buf); } + + bool Verify() { + Verifier verifier(buf, len); + return verifier.VerifyBuffer<T>(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. @@ -2554,15 +2554,15 @@ class Struct FLATBUFFERS_FINAL_CLASS { // omitted and added at will, but uses an extra indirection to read. class Table { public: - const uint8_t *GetVTable() const { - return data_ - ReadScalar<soffset_t>(data_); - } - + const uint8_t *GetVTable() const { + return data_ - ReadScalar<soffset_t>(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(); + auto vtable = GetVTable(); // The first element is the size of the vtable (fields + type id + itself). auto vtsize = ReadScalar<voffset_t>(vtable); // If the field we're accessing is outside the vtable, we're reading older @@ -2578,8 +2578,8 @@ class Table { template<typename P> P GetPointer(voffset_t field) { auto field_offset = GetOptionalFieldOffset(field); auto p = data_ + field_offset; - return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p)) - : nullptr; + return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p)) + : nullptr; } template<typename P> P GetPointer(voffset_t field) const { return const_cast<Table *>(this)->GetPointer<P>(field); @@ -2599,7 +2599,7 @@ class Table { : Optional<Face>(); } - template<typename T> bool SetField(voffset_t field, T val, T def) { + template<typename T> 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); @@ -2615,8 +2615,8 @@ class Table { 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<uoffset_t>(val - (data_ + field_offset))); + WriteScalar(data_ + field_offset, + static_cast<uoffset_t>(val - (data_ + field_offset))); return true; } @@ -2635,39 +2635,39 @@ class Table { // 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_); + return verifier.VerifyTableStart(data_); } // Verify a particular field. - template<typename T> - bool VerifyField(const Verifier &verifier, voffset_t field) const { + template<typename T> + 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<T>(data_, field_offset); + return !field_offset || verifier.Verify<T>(data_, field_offset); } // VerifyField for required fields. - template<typename T> - bool VerifyFieldRequired(const Verifier &verifier, voffset_t field) const { + template<typename T> + bool VerifyFieldRequired(const Verifier &verifier, voffset_t field) const { auto field_offset = GetOptionalFieldOffset(field); return verifier.Check(field_offset != 0) && - verifier.Verify<T>(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); - } - + verifier.Verify<T>(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 @@ -2691,81 +2691,81 @@ inline flatbuffers::Optional<bool> Table::GetOptional<uint8_t, bool>( template<typename T> void FlatBufferBuilder::Required(Offset<T> table, voffset_t field) { - auto table_ptr = reinterpret_cast<const Table *>(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<const Table *>(root); - auto vtable = table->GetVTable(); - // Either the vtable is before the root or after the root. - auto start = (std::min)(vtable, reinterpret_cast<const uint8_t *>(root)); - // Align to at least sizeof(uoffset_t). - start = reinterpret_cast<const uint8_t *>(reinterpret_cast<uintptr_t>(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_identifier 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<uoffset_t>(start) + start == - reinterpret_cast<const uint8_t *>(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. + auto table_ptr = reinterpret_cast<const Table *>(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<const Table *>(root); + auto vtable = table->GetVTable(); + // Either the vtable is before the root or after the root. + auto start = (std::min)(vtable, reinterpret_cast<const uint8_t *>(root)); + // Align to at least sizeof(uoffset_t). + start = reinterpret_cast<const uint8_t *>(reinterpret_cast<uintptr_t>(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_identifier 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<uoffset_t>(start) + start == + reinterpret_cast<const uint8_t *>(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<uoffset_t>(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<void (void **pointer_adr, hash_value_t hash)> - resolver_function_t; - typedef std::function<hash_value_t (void *pointer)> rehasher_function_t; -#endif -// clang-format on - + +// 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<void (void **pointer_adr, hash_value_t hash)> + resolver_function_t; + typedef std::function<hash_value_t (void *pointer)> 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, @@ -2785,7 +2785,7 @@ bool IsFieldPresent(const T *table, typename T::FlatBuffersVTableOffset field) { // 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<int>(p - names); + if (!strcmp(*p, name)) return static_cast<int>(p - names); return -1; } @@ -2799,102 +2799,102 @@ inline int LookupEnum(const char **names, const char *name) { // by the force_align attribute. // These are used in the generated code only. -// clang-format off +// clang-format off #if defined(_MSC_VER) - #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \ + #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \ __pragma(pack(1)) \ struct __declspec(align(alignment)) - #define FLATBUFFERS_STRUCT_END(name, size) \ + #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) \ + #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \ _Pragma("pack(1)") \ struct __attribute__((aligned(alignment))) - #define FLATBUFFERS_STRUCT_END(name, size) \ + #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! +// 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 { +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). +}; + +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 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 @@ -2905,7 +2905,7 @@ struct TypeTable { // appreciate if you left it in. // Weak linkage is culled by VS & doesn't work on cygwin. -// clang-format off +// clang-format off #if !defined(_WIN32) && !defined(__CYGWIN__) extern volatile __attribute__((weak)) const char *flatbuffer_version_string; @@ -2917,38 +2917,38 @@ volatile __attribute__((weak)) const char *flatbuffer_version_string = #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)); \ - } +#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 - +// clang-format on + #endif // FLATBUFFERS_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/flatc.h b/contrib/libs/flatbuffers/include/flatbuffers/flatc.h index cb160491ac..1466b3651d 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/flatc.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/flatc.h @@ -1,100 +1,100 @@ -/* - * 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. - */ - +/* + * 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_FLATC_H_ #define FLATBUFFERS_FLATC_H_ -#include <functional> -#include <limits> -#include <string> +#include <functional> +#include <limits> +#include <string> #include "flatbuffers.h" #include "idl.h" #include "util.h" - -namespace flatbuffers { - + +namespace flatbuffers { + extern void LogCompilerWarn(const std::string &warn); extern void LogCompilerError(const std::string &err); -class FlatCompiler { - public: - // Output generator for the various programming languages and formats we - // support. - struct Generator { - typedef bool (*GenerateFn)(const flatbuffers::Parser &parser, - const std::string &path, - const std::string &file_name); - typedef std::string (*MakeRuleFn)(const flatbuffers::Parser &parser, - const std::string &path, - const std::string &file_name); - - GenerateFn generate; - const char *generator_opt_short; - const char *generator_opt_long; - const char *lang_name; - bool schema_only; - GenerateFn generateGRPC; - flatbuffers::IDLOptions::Language lang; - const char *generator_help; - MakeRuleFn make_rule; - }; - - typedef void (*WarnFn)(const FlatCompiler *flatc, const std::string &warn, - bool show_exe_name); - - typedef void (*ErrorFn)(const FlatCompiler *flatc, const std::string &err, - bool usage, bool show_exe_name); - - // Parameters required to initialize the FlatCompiler. - struct InitParams { - InitParams() - : generators(nullptr), - num_generators(0), - warn_fn(nullptr), - error_fn(nullptr) {} - - const Generator *generators; - size_t num_generators; - WarnFn warn_fn; - ErrorFn error_fn; - }; - - explicit FlatCompiler(const InitParams ¶ms) : params_(params) {} - - int Compile(int argc, const char **argv); - - std::string GetUsageString(const char *program_name) const; - - private: - void ParseFile(flatbuffers::Parser &parser, const std::string &filename, - const std::string &contents, - std::vector<const char *> &include_directories) const; - +class FlatCompiler { + public: + // Output generator for the various programming languages and formats we + // support. + struct Generator { + typedef bool (*GenerateFn)(const flatbuffers::Parser &parser, + const std::string &path, + const std::string &file_name); + typedef std::string (*MakeRuleFn)(const flatbuffers::Parser &parser, + const std::string &path, + const std::string &file_name); + + GenerateFn generate; + const char *generator_opt_short; + const char *generator_opt_long; + const char *lang_name; + bool schema_only; + GenerateFn generateGRPC; + flatbuffers::IDLOptions::Language lang; + const char *generator_help; + MakeRuleFn make_rule; + }; + + typedef void (*WarnFn)(const FlatCompiler *flatc, const std::string &warn, + bool show_exe_name); + + typedef void (*ErrorFn)(const FlatCompiler *flatc, const std::string &err, + bool usage, bool show_exe_name); + + // Parameters required to initialize the FlatCompiler. + struct InitParams { + InitParams() + : generators(nullptr), + num_generators(0), + warn_fn(nullptr), + error_fn(nullptr) {} + + const Generator *generators; + size_t num_generators; + WarnFn warn_fn; + ErrorFn error_fn; + }; + + explicit FlatCompiler(const InitParams ¶ms) : params_(params) {} + + int Compile(int argc, const char **argv); + + std::string GetUsageString(const char *program_name) const; + + private: + void ParseFile(flatbuffers::Parser &parser, const std::string &filename, + const std::string &contents, + std::vector<const char *> &include_directories) const; + void LoadBinarySchema(Parser &parser, const std::string &filename, const std::string &contents); - void Warn(const std::string &warn, bool show_exe_name = true) const; - - void Error(const std::string &err, bool usage = true, - bool show_exe_name = true) const; - - InitParams params_; -}; - -} // namespace flatbuffers - + void Warn(const std::string &warn, bool show_exe_name = true) const; + + void Error(const std::string &err, bool usage = true, + bool show_exe_name = true) const; + + InitParams params_; +}; + +} // namespace flatbuffers + #endif // FLATBUFFERS_FLATC_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h b/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h index be45e97fdf..d855b67731 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h @@ -1,222 +1,222 @@ -/* - * 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_FLEXBUFFERS_H_ -#define FLATBUFFERS_FLEXBUFFERS_H_ - -#include <map> -// Used to select STL variant. +/* + * 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_FLEXBUFFERS_H_ +#define FLATBUFFERS_FLEXBUFFERS_H_ + +#include <map> +// Used to select STL variant. #include "base.h" -// We use the basic binary writing functions from the regular FlatBuffers. +// We use the basic binary writing functions from the regular FlatBuffers. #include "util.h" - -#ifdef _MSC_VER -# include <intrin.h> -#endif - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4127) // C4127: conditional expression is constant -#endif - -namespace flexbuffers { - -class Reference; -class Map; - -// These are used in the lower 2 bits of a type field to determine the size of -// the elements (and or size field) of the item pointed to (e.g. vector). -enum BitWidth { - BIT_WIDTH_8 = 0, - BIT_WIDTH_16 = 1, - BIT_WIDTH_32 = 2, - BIT_WIDTH_64 = 3, -}; - -// These are used as the upper 6 bits of a type field to indicate the actual -// type. -enum Type { - FBT_NULL = 0, - FBT_INT = 1, - FBT_UINT = 2, - FBT_FLOAT = 3, - // Types above stored inline, types below store an offset. - FBT_KEY = 4, - FBT_STRING = 5, - FBT_INDIRECT_INT = 6, - FBT_INDIRECT_UINT = 7, - FBT_INDIRECT_FLOAT = 8, - FBT_MAP = 9, - FBT_VECTOR = 10, // Untyped. - FBT_VECTOR_INT = 11, // Typed any size (stores no type table). - FBT_VECTOR_UINT = 12, - FBT_VECTOR_FLOAT = 13, - FBT_VECTOR_KEY = 14, + +#ifdef _MSC_VER +# include <intrin.h> +#endif + +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable : 4127) // C4127: conditional expression is constant +#endif + +namespace flexbuffers { + +class Reference; +class Map; + +// These are used in the lower 2 bits of a type field to determine the size of +// the elements (and or size field) of the item pointed to (e.g. vector). +enum BitWidth { + BIT_WIDTH_8 = 0, + BIT_WIDTH_16 = 1, + BIT_WIDTH_32 = 2, + BIT_WIDTH_64 = 3, +}; + +// These are used as the upper 6 bits of a type field to indicate the actual +// type. +enum Type { + FBT_NULL = 0, + FBT_INT = 1, + FBT_UINT = 2, + FBT_FLOAT = 3, + // Types above stored inline, types below store an offset. + FBT_KEY = 4, + FBT_STRING = 5, + FBT_INDIRECT_INT = 6, + FBT_INDIRECT_UINT = 7, + FBT_INDIRECT_FLOAT = 8, + FBT_MAP = 9, + FBT_VECTOR = 10, // Untyped. + FBT_VECTOR_INT = 11, // Typed any size (stores no type table). + FBT_VECTOR_UINT = 12, + FBT_VECTOR_FLOAT = 13, + FBT_VECTOR_KEY = 14, // DEPRECATED, use FBT_VECTOR or FBT_VECTOR_KEY instead. // Read test.cpp/FlexBuffersDeprecatedTest() for details on why. FBT_VECTOR_STRING_DEPRECATED = 15, - FBT_VECTOR_INT2 = 16, // Typed tuple (no type table, no size field). - FBT_VECTOR_UINT2 = 17, - FBT_VECTOR_FLOAT2 = 18, - FBT_VECTOR_INT3 = 19, // Typed triple (no type table, no size field). - FBT_VECTOR_UINT3 = 20, - FBT_VECTOR_FLOAT3 = 21, - FBT_VECTOR_INT4 = 22, // Typed quad (no type table, no size field). - FBT_VECTOR_UINT4 = 23, - FBT_VECTOR_FLOAT4 = 24, - FBT_BLOB = 25, - FBT_BOOL = 26, - FBT_VECTOR_BOOL = - 36, // To Allow the same type of conversion of type to vector type -}; - -inline bool IsInline(Type t) { return t <= FBT_FLOAT || t == FBT_BOOL; } - -inline bool IsTypedVectorElementType(Type t) { - return (t >= FBT_INT && t <= FBT_STRING) || t == FBT_BOOL; -} - -inline bool IsTypedVector(Type t) { + FBT_VECTOR_INT2 = 16, // Typed tuple (no type table, no size field). + FBT_VECTOR_UINT2 = 17, + FBT_VECTOR_FLOAT2 = 18, + FBT_VECTOR_INT3 = 19, // Typed triple (no type table, no size field). + FBT_VECTOR_UINT3 = 20, + FBT_VECTOR_FLOAT3 = 21, + FBT_VECTOR_INT4 = 22, // Typed quad (no type table, no size field). + FBT_VECTOR_UINT4 = 23, + FBT_VECTOR_FLOAT4 = 24, + FBT_BLOB = 25, + FBT_BOOL = 26, + FBT_VECTOR_BOOL = + 36, // To Allow the same type of conversion of type to vector type +}; + +inline bool IsInline(Type t) { return t <= FBT_FLOAT || t == FBT_BOOL; } + +inline bool IsTypedVectorElementType(Type t) { + return (t >= FBT_INT && t <= FBT_STRING) || t == FBT_BOOL; +} + +inline bool IsTypedVector(Type t) { return (t >= FBT_VECTOR_INT && t <= FBT_VECTOR_STRING_DEPRECATED) || - t == FBT_VECTOR_BOOL; -} - -inline bool IsFixedTypedVector(Type t) { - return t >= FBT_VECTOR_INT2 && t <= FBT_VECTOR_FLOAT4; -} - -inline Type ToTypedVector(Type t, size_t fixed_len = 0) { - FLATBUFFERS_ASSERT(IsTypedVectorElementType(t)); - switch (fixed_len) { - case 0: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT); - case 2: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT2); - case 3: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT3); - case 4: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT4); - default: FLATBUFFERS_ASSERT(0); return FBT_NULL; - } -} - -inline Type ToTypedVectorElementType(Type t) { - FLATBUFFERS_ASSERT(IsTypedVector(t)); - return static_cast<Type>(t - FBT_VECTOR_INT + FBT_INT); -} - -inline Type ToFixedTypedVectorElementType(Type t, uint8_t *len) { - FLATBUFFERS_ASSERT(IsFixedTypedVector(t)); - auto fixed_type = t - FBT_VECTOR_INT2; - *len = static_cast<uint8_t>(fixed_type / 3 + - 2); // 3 types each, starting from length 2. - return static_cast<Type>(fixed_type % 3 + FBT_INT); -} - -// TODO: implement proper support for 8/16bit floats, or decide not to -// support them. -typedef int16_t half; -typedef int8_t quarter; - -// TODO: can we do this without conditionals using intrinsics or inline asm -// on some platforms? Given branch prediction the method below should be -// decently quick, but it is the most frequently executed function. -// We could do an (unaligned) 64-bit read if we ifdef out the platforms for -// which that doesn't work (or where we'd read into un-owned memory). -template<typename R, typename T1, typename T2, typename T4, typename T8> -R ReadSizedScalar(const uint8_t *data, uint8_t byte_width) { - return byte_width < 4 - ? (byte_width < 2 - ? static_cast<R>(flatbuffers::ReadScalar<T1>(data)) - : static_cast<R>(flatbuffers::ReadScalar<T2>(data))) - : (byte_width < 8 - ? static_cast<R>(flatbuffers::ReadScalar<T4>(data)) - : static_cast<R>(flatbuffers::ReadScalar<T8>(data))); -} - -inline int64_t ReadInt64(const uint8_t *data, uint8_t byte_width) { - return ReadSizedScalar<int64_t, int8_t, int16_t, int32_t, int64_t>( - data, byte_width); -} - -inline uint64_t ReadUInt64(const uint8_t *data, uint8_t byte_width) { - // This is the "hottest" function (all offset lookups use this), so worth - // optimizing if possible. - // TODO: GCC apparently replaces memcpy by a rep movsb, but only if count is a - // constant, which here it isn't. Test if memcpy is still faster than - // the conditionals in ReadSizedScalar. Can also use inline asm. - // clang-format off + t == FBT_VECTOR_BOOL; +} + +inline bool IsFixedTypedVector(Type t) { + return t >= FBT_VECTOR_INT2 && t <= FBT_VECTOR_FLOAT4; +} + +inline Type ToTypedVector(Type t, size_t fixed_len = 0) { + FLATBUFFERS_ASSERT(IsTypedVectorElementType(t)); + switch (fixed_len) { + case 0: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT); + case 2: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT2); + case 3: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT3); + case 4: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT4); + default: FLATBUFFERS_ASSERT(0); return FBT_NULL; + } +} + +inline Type ToTypedVectorElementType(Type t) { + FLATBUFFERS_ASSERT(IsTypedVector(t)); + return static_cast<Type>(t - FBT_VECTOR_INT + FBT_INT); +} + +inline Type ToFixedTypedVectorElementType(Type t, uint8_t *len) { + FLATBUFFERS_ASSERT(IsFixedTypedVector(t)); + auto fixed_type = t - FBT_VECTOR_INT2; + *len = static_cast<uint8_t>(fixed_type / 3 + + 2); // 3 types each, starting from length 2. + return static_cast<Type>(fixed_type % 3 + FBT_INT); +} + +// TODO: implement proper support for 8/16bit floats, or decide not to +// support them. +typedef int16_t half; +typedef int8_t quarter; + +// TODO: can we do this without conditionals using intrinsics or inline asm +// on some platforms? Given branch prediction the method below should be +// decently quick, but it is the most frequently executed function. +// We could do an (unaligned) 64-bit read if we ifdef out the platforms for +// which that doesn't work (or where we'd read into un-owned memory). +template<typename R, typename T1, typename T2, typename T4, typename T8> +R ReadSizedScalar(const uint8_t *data, uint8_t byte_width) { + return byte_width < 4 + ? (byte_width < 2 + ? static_cast<R>(flatbuffers::ReadScalar<T1>(data)) + : static_cast<R>(flatbuffers::ReadScalar<T2>(data))) + : (byte_width < 8 + ? static_cast<R>(flatbuffers::ReadScalar<T4>(data)) + : static_cast<R>(flatbuffers::ReadScalar<T8>(data))); +} + +inline int64_t ReadInt64(const uint8_t *data, uint8_t byte_width) { + return ReadSizedScalar<int64_t, int8_t, int16_t, int32_t, int64_t>( + data, byte_width); +} + +inline uint64_t ReadUInt64(const uint8_t *data, uint8_t byte_width) { + // This is the "hottest" function (all offset lookups use this), so worth + // optimizing if possible. + // TODO: GCC apparently replaces memcpy by a rep movsb, but only if count is a + // constant, which here it isn't. Test if memcpy is still faster than + // the conditionals in ReadSizedScalar. Can also use inline asm. + // clang-format off #if defined(_MSC_VER) && ((defined(_M_X64) && !defined(_M_ARM64EC)) || defined _M_IX86) - uint64_t u = 0; - __movsb(reinterpret_cast<uint8_t *>(&u), - reinterpret_cast<const uint8_t *>(data), byte_width); - return flatbuffers::EndianScalar(u); - #else - return ReadSizedScalar<uint64_t, uint8_t, uint16_t, uint32_t, uint64_t>( - data, byte_width); - #endif - // clang-format on -} - -inline double ReadDouble(const uint8_t *data, uint8_t byte_width) { - return ReadSizedScalar<double, quarter, half, float, double>(data, - byte_width); -} - -inline const uint8_t *Indirect(const uint8_t *offset, uint8_t byte_width) { - return offset - ReadUInt64(offset, byte_width); -} - -template<typename T> const uint8_t *Indirect(const uint8_t *offset) { - return offset - flatbuffers::ReadScalar<T>(offset); -} - -inline BitWidth WidthU(uint64_t u) { -#define FLATBUFFERS_GET_FIELD_BIT_WIDTH(value, width) \ - { \ - if (!((u) & ~((1ULL << (width)) - 1ULL))) return BIT_WIDTH_##width; \ - } - FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 8); - FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 16); - FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 32); -#undef FLATBUFFERS_GET_FIELD_BIT_WIDTH - return BIT_WIDTH_64; -} - -inline BitWidth WidthI(int64_t i) { - auto u = static_cast<uint64_t>(i) << 1; - return WidthU(i >= 0 ? u : ~u); -} - -inline BitWidth WidthF(double f) { - return static_cast<double>(static_cast<float>(f)) == f ? BIT_WIDTH_32 - : BIT_WIDTH_64; -} - -// Base class of all types below. -// Points into the data buffer and allows access to one type. -class Object { - public: - Object(const uint8_t *data, uint8_t byte_width) - : data_(data), byte_width_(byte_width) {} - - protected: - const uint8_t *data_; - uint8_t byte_width_; -}; - + uint64_t u = 0; + __movsb(reinterpret_cast<uint8_t *>(&u), + reinterpret_cast<const uint8_t *>(data), byte_width); + return flatbuffers::EndianScalar(u); + #else + return ReadSizedScalar<uint64_t, uint8_t, uint16_t, uint32_t, uint64_t>( + data, byte_width); + #endif + // clang-format on +} + +inline double ReadDouble(const uint8_t *data, uint8_t byte_width) { + return ReadSizedScalar<double, quarter, half, float, double>(data, + byte_width); +} + +inline const uint8_t *Indirect(const uint8_t *offset, uint8_t byte_width) { + return offset - ReadUInt64(offset, byte_width); +} + +template<typename T> const uint8_t *Indirect(const uint8_t *offset) { + return offset - flatbuffers::ReadScalar<T>(offset); +} + +inline BitWidth WidthU(uint64_t u) { +#define FLATBUFFERS_GET_FIELD_BIT_WIDTH(value, width) \ + { \ + if (!((u) & ~((1ULL << (width)) - 1ULL))) return BIT_WIDTH_##width; \ + } + FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 8); + FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 16); + FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 32); +#undef FLATBUFFERS_GET_FIELD_BIT_WIDTH + return BIT_WIDTH_64; +} + +inline BitWidth WidthI(int64_t i) { + auto u = static_cast<uint64_t>(i) << 1; + return WidthU(i >= 0 ? u : ~u); +} + +inline BitWidth WidthF(double f) { + return static_cast<double>(static_cast<float>(f)) == f ? BIT_WIDTH_32 + : BIT_WIDTH_64; +} + +// Base class of all types below. +// Points into the data buffer and allows access to one type. +class Object { + public: + Object(const uint8_t *data, uint8_t byte_width) + : data_(data), byte_width_(byte_width) {} + + protected: + const uint8_t *data_; + uint8_t byte_width_; +}; + // Object that has a size, obtained either from size prefix, or elsewhere. -class Sized : public Object { - public: +class Sized : public Object { + public: // Size prefix. Sized(const uint8_t *data, uint8_t byte_width) : Object(data, byte_width), size_(read_size()) {} @@ -226,135 +226,135 @@ class Sized : public Object { size_t size() const { return size_; } // Access size stored in `byte_width_` bytes before data_ pointer. size_t read_size() const { - return static_cast<size_t>(ReadUInt64(data_ - byte_width_, byte_width_)); - } + return static_cast<size_t>(ReadUInt64(data_ - byte_width_, byte_width_)); + } protected: size_t size_; -}; - -class String : public Sized { - public: +}; + +class String : public Sized { + public: // Size prefix. - String(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {} + String(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {} // Manual size. String(const uint8_t *data, uint8_t byte_width, size_t sz) : Sized(data, byte_width, sz) {} - - size_t length() const { return size(); } - const char *c_str() const { return reinterpret_cast<const char *>(data_); } + + size_t length() const { return size(); } + const char *c_str() const { return reinterpret_cast<const char *>(data_); } std::string str() const { return std::string(c_str(), size()); } - - static String EmptyString() { + + static String EmptyString() { static const char *empty_string = ""; return String(reinterpret_cast<const uint8_t *>(empty_string), 1, 0); - } - bool IsTheEmptyString() const { return data_ == EmptyString().data_; } -}; - -class Blob : public Sized { - public: - Blob(const uint8_t *data_buf, uint8_t byte_width) - : Sized(data_buf, byte_width) {} - - static Blob EmptyBlob() { - static const uint8_t empty_blob[] = { 0 /*len*/ }; - return Blob(empty_blob + 1, 1); - } - bool IsTheEmptyBlob() const { return data_ == EmptyBlob().data_; } - const uint8_t *data() const { return data_; } -}; - -class Vector : public Sized { - public: - Vector(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {} - - Reference operator[](size_t i) const; - - static Vector EmptyVector() { - static const uint8_t empty_vector[] = { 0 /*len*/ }; - return Vector(empty_vector + 1, 1); - } - bool IsTheEmptyVector() const { return data_ == EmptyVector().data_; } -}; - -class TypedVector : public Sized { - public: - TypedVector(const uint8_t *data, uint8_t byte_width, Type element_type) - : Sized(data, byte_width), type_(element_type) {} - - Reference operator[](size_t i) const; - - static TypedVector EmptyTypedVector() { - static const uint8_t empty_typed_vector[] = { 0 /*len*/ }; - return TypedVector(empty_typed_vector + 1, 1, FBT_INT); - } - bool IsTheEmptyVector() const { - return data_ == TypedVector::EmptyTypedVector().data_; - } - - Type ElementType() { return type_; } - + } + bool IsTheEmptyString() const { return data_ == EmptyString().data_; } +}; + +class Blob : public Sized { + public: + Blob(const uint8_t *data_buf, uint8_t byte_width) + : Sized(data_buf, byte_width) {} + + static Blob EmptyBlob() { + static const uint8_t empty_blob[] = { 0 /*len*/ }; + return Blob(empty_blob + 1, 1); + } + bool IsTheEmptyBlob() const { return data_ == EmptyBlob().data_; } + const uint8_t *data() const { return data_; } +}; + +class Vector : public Sized { + public: + Vector(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {} + + Reference operator[](size_t i) const; + + static Vector EmptyVector() { + static const uint8_t empty_vector[] = { 0 /*len*/ }; + return Vector(empty_vector + 1, 1); + } + bool IsTheEmptyVector() const { return data_ == EmptyVector().data_; } +}; + +class TypedVector : public Sized { + public: + TypedVector(const uint8_t *data, uint8_t byte_width, Type element_type) + : Sized(data, byte_width), type_(element_type) {} + + Reference operator[](size_t i) const; + + static TypedVector EmptyTypedVector() { + static const uint8_t empty_typed_vector[] = { 0 /*len*/ }; + return TypedVector(empty_typed_vector + 1, 1, FBT_INT); + } + bool IsTheEmptyVector() const { + return data_ == TypedVector::EmptyTypedVector().data_; + } + + Type ElementType() { return type_; } + friend Reference; - private: - Type type_; - - friend Map; -}; - -class FixedTypedVector : public Object { - public: - FixedTypedVector(const uint8_t *data, uint8_t byte_width, Type element_type, - uint8_t len) - : Object(data, byte_width), type_(element_type), len_(len) {} - - Reference operator[](size_t i) const; - - static FixedTypedVector EmptyFixedTypedVector() { - static const uint8_t fixed_empty_vector[] = { 0 /* unused */ }; - return FixedTypedVector(fixed_empty_vector, 1, FBT_INT, 0); - } - bool IsTheEmptyFixedTypedVector() const { - return data_ == FixedTypedVector::EmptyFixedTypedVector().data_; - } - - Type ElementType() { return type_; } - uint8_t size() { return len_; } - - private: - Type type_; - uint8_t len_; -}; - -class Map : public Vector { - public: - Map(const uint8_t *data, uint8_t byte_width) : Vector(data, byte_width) {} - - Reference operator[](const char *key) const; - Reference operator[](const std::string &key) const; - - Vector Values() const { return Vector(data_, byte_width_); } - - TypedVector Keys() const { - const size_t num_prefixed_fields = 3; - auto keys_offset = data_ - byte_width_ * num_prefixed_fields; - return TypedVector(Indirect(keys_offset, byte_width_), - static_cast<uint8_t>( - ReadUInt64(keys_offset + byte_width_, byte_width_)), - FBT_KEY); - } - - static Map EmptyMap() { - static const uint8_t empty_map[] = { - 0 /*keys_len*/, 0 /*keys_offset*/, 1 /*keys_width*/, 0 /*len*/ - }; - return Map(empty_map + 4, 1); - } - - bool IsTheEmptyMap() const { return data_ == EmptyMap().data_; } -}; - + private: + Type type_; + + friend Map; +}; + +class FixedTypedVector : public Object { + public: + FixedTypedVector(const uint8_t *data, uint8_t byte_width, Type element_type, + uint8_t len) + : Object(data, byte_width), type_(element_type), len_(len) {} + + Reference operator[](size_t i) const; + + static FixedTypedVector EmptyFixedTypedVector() { + static const uint8_t fixed_empty_vector[] = { 0 /* unused */ }; + return FixedTypedVector(fixed_empty_vector, 1, FBT_INT, 0); + } + bool IsTheEmptyFixedTypedVector() const { + return data_ == FixedTypedVector::EmptyFixedTypedVector().data_; + } + + Type ElementType() { return type_; } + uint8_t size() { return len_; } + + private: + Type type_; + uint8_t len_; +}; + +class Map : public Vector { + public: + Map(const uint8_t *data, uint8_t byte_width) : Vector(data, byte_width) {} + + Reference operator[](const char *key) const; + Reference operator[](const std::string &key) const; + + Vector Values() const { return Vector(data_, byte_width_); } + + TypedVector Keys() const { + const size_t num_prefixed_fields = 3; + auto keys_offset = data_ - byte_width_ * num_prefixed_fields; + return TypedVector(Indirect(keys_offset, byte_width_), + static_cast<uint8_t>( + ReadUInt64(keys_offset + byte_width_, byte_width_)), + FBT_KEY); + } + + static Map EmptyMap() { + static const uint8_t empty_map[] = { + 0 /*keys_len*/, 0 /*keys_offset*/, 1 /*keys_width*/, 0 /*len*/ + }; + return Map(empty_map + 4, 1); + } + + bool IsTheEmptyMap() const { return data_ == EmptyMap().data_; } +}; + template<typename T> void AppendToString(std::string &s, T &&v, bool keys_quoted) { s += "[ "; @@ -365,220 +365,220 @@ void AppendToString(std::string &s, T &&v, bool keys_quoted) { s += " ]"; } -class Reference { - public: +class Reference { + public: Reference() : data_(nullptr), parent_width_(0), byte_width_(BIT_WIDTH_8), type_(FBT_NULL) {} - Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width, - Type type) - : data_(data), - parent_width_(parent_width), - byte_width_(byte_width), - type_(type) {} - - Reference(const uint8_t *data, uint8_t parent_width, uint8_t packed_type) - : data_(data), parent_width_(parent_width) { - byte_width_ = 1U << static_cast<BitWidth>(packed_type & 3); - type_ = static_cast<Type>(packed_type >> 2); - } - - Type GetType() const { return type_; } - - bool IsNull() const { return type_ == FBT_NULL; } - bool IsBool() const { return type_ == FBT_BOOL; } - bool IsInt() const { return type_ == FBT_INT || type_ == FBT_INDIRECT_INT; } - bool IsUInt() const { - return type_ == FBT_UINT || type_ == FBT_INDIRECT_UINT; - } - bool IsIntOrUint() const { return IsInt() || IsUInt(); } - bool IsFloat() const { - return type_ == FBT_FLOAT || type_ == FBT_INDIRECT_FLOAT; - } - bool IsNumeric() const { return IsIntOrUint() || IsFloat(); } - bool IsString() const { return type_ == FBT_STRING; } - bool IsKey() const { return type_ == FBT_KEY; } - bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; } + Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width, + Type type) + : data_(data), + parent_width_(parent_width), + byte_width_(byte_width), + type_(type) {} + + Reference(const uint8_t *data, uint8_t parent_width, uint8_t packed_type) + : data_(data), parent_width_(parent_width) { + byte_width_ = 1U << static_cast<BitWidth>(packed_type & 3); + type_ = static_cast<Type>(packed_type >> 2); + } + + Type GetType() const { return type_; } + + bool IsNull() const { return type_ == FBT_NULL; } + bool IsBool() const { return type_ == FBT_BOOL; } + bool IsInt() const { return type_ == FBT_INT || type_ == FBT_INDIRECT_INT; } + bool IsUInt() const { + return type_ == FBT_UINT || type_ == FBT_INDIRECT_UINT; + } + bool IsIntOrUint() const { return IsInt() || IsUInt(); } + bool IsFloat() const { + return type_ == FBT_FLOAT || type_ == FBT_INDIRECT_FLOAT; + } + bool IsNumeric() const { return IsIntOrUint() || IsFloat(); } + bool IsString() const { return type_ == FBT_STRING; } + bool IsKey() const { return type_ == FBT_KEY; } + bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; } bool IsUntypedVector() const { return type_ == FBT_VECTOR; } - bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); } + bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); } bool IsFixedTypedVector() const { return flexbuffers::IsFixedTypedVector(type_); } bool IsAnyVector() const { return (IsTypedVector() || IsFixedTypedVector() || IsVector()); } - bool IsMap() const { return type_ == FBT_MAP; } - bool IsBlob() const { return type_ == FBT_BLOB; } - bool AsBool() const { - return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_) + bool IsMap() const { return type_ == FBT_MAP; } + bool IsBlob() const { return type_ == FBT_BLOB; } + bool AsBool() const { + return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_) : AsUInt64()) != 0; - } - - // Reads any type as a int64_t. Never fails, does most sensible conversion. - // Truncates floats, strings are attempted to be parsed for a number, - // vectors/maps return their size. Returns 0 if all else fails. - int64_t AsInt64() const { - if (type_ == FBT_INT) { - // A fast path for the common case. - return ReadInt64(data_, parent_width_); - } else - switch (type_) { - case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_); - case FBT_UINT: return ReadUInt64(data_, parent_width_); - case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_); - case FBT_FLOAT: - return static_cast<int64_t>(ReadDouble(data_, parent_width_)); - case FBT_INDIRECT_FLOAT: - return static_cast<int64_t>(ReadDouble(Indirect(), byte_width_)); - case FBT_NULL: return 0; - case FBT_STRING: return flatbuffers::StringToInt(AsString().c_str()); - case FBT_VECTOR: return static_cast<int64_t>(AsVector().size()); - case FBT_BOOL: return ReadInt64(data_, parent_width_); - default: - // Convert other things to int. - return 0; - } - } - - // TODO: could specialize these to not use AsInt64() if that saves - // extension ops in generated code, and use a faster op than ReadInt64. - int32_t AsInt32() const { return static_cast<int32_t>(AsInt64()); } - int16_t AsInt16() const { return static_cast<int16_t>(AsInt64()); } - int8_t AsInt8() const { return static_cast<int8_t>(AsInt64()); } - - uint64_t AsUInt64() const { - if (type_ == FBT_UINT) { - // A fast path for the common case. - return ReadUInt64(data_, parent_width_); - } else - switch (type_) { - case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_); - case FBT_INT: return ReadInt64(data_, parent_width_); - case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_); - case FBT_FLOAT: - return static_cast<uint64_t>(ReadDouble(data_, parent_width_)); - case FBT_INDIRECT_FLOAT: - return static_cast<uint64_t>(ReadDouble(Indirect(), byte_width_)); - case FBT_NULL: return 0; - case FBT_STRING: return flatbuffers::StringToUInt(AsString().c_str()); - case FBT_VECTOR: return static_cast<uint64_t>(AsVector().size()); - case FBT_BOOL: return ReadUInt64(data_, parent_width_); - default: - // Convert other things to uint. - return 0; - } - } - - uint32_t AsUInt32() const { return static_cast<uint32_t>(AsUInt64()); } - uint16_t AsUInt16() const { return static_cast<uint16_t>(AsUInt64()); } - uint8_t AsUInt8() const { return static_cast<uint8_t>(AsUInt64()); } - - double AsDouble() const { - if (type_ == FBT_FLOAT) { - // A fast path for the common case. - return ReadDouble(data_, parent_width_); - } else - switch (type_) { - case FBT_INDIRECT_FLOAT: return ReadDouble(Indirect(), byte_width_); - case FBT_INT: - return static_cast<double>(ReadInt64(data_, parent_width_)); - case FBT_UINT: - return static_cast<double>(ReadUInt64(data_, parent_width_)); - case FBT_INDIRECT_INT: - return static_cast<double>(ReadInt64(Indirect(), byte_width_)); - case FBT_INDIRECT_UINT: - return static_cast<double>(ReadUInt64(Indirect(), byte_width_)); - case FBT_NULL: return 0.0; + } + + // Reads any type as a int64_t. Never fails, does most sensible conversion. + // Truncates floats, strings are attempted to be parsed for a number, + // vectors/maps return their size. Returns 0 if all else fails. + int64_t AsInt64() const { + if (type_ == FBT_INT) { + // A fast path for the common case. + return ReadInt64(data_, parent_width_); + } else + switch (type_) { + case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_); + case FBT_UINT: return ReadUInt64(data_, parent_width_); + case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_); + case FBT_FLOAT: + return static_cast<int64_t>(ReadDouble(data_, parent_width_)); + case FBT_INDIRECT_FLOAT: + return static_cast<int64_t>(ReadDouble(Indirect(), byte_width_)); + case FBT_NULL: return 0; + case FBT_STRING: return flatbuffers::StringToInt(AsString().c_str()); + case FBT_VECTOR: return static_cast<int64_t>(AsVector().size()); + case FBT_BOOL: return ReadInt64(data_, parent_width_); + default: + // Convert other things to int. + return 0; + } + } + + // TODO: could specialize these to not use AsInt64() if that saves + // extension ops in generated code, and use a faster op than ReadInt64. + int32_t AsInt32() const { return static_cast<int32_t>(AsInt64()); } + int16_t AsInt16() const { return static_cast<int16_t>(AsInt64()); } + int8_t AsInt8() const { return static_cast<int8_t>(AsInt64()); } + + uint64_t AsUInt64() const { + if (type_ == FBT_UINT) { + // A fast path for the common case. + return ReadUInt64(data_, parent_width_); + } else + switch (type_) { + case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_); + case FBT_INT: return ReadInt64(data_, parent_width_); + case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_); + case FBT_FLOAT: + return static_cast<uint64_t>(ReadDouble(data_, parent_width_)); + case FBT_INDIRECT_FLOAT: + return static_cast<uint64_t>(ReadDouble(Indirect(), byte_width_)); + case FBT_NULL: return 0; + case FBT_STRING: return flatbuffers::StringToUInt(AsString().c_str()); + case FBT_VECTOR: return static_cast<uint64_t>(AsVector().size()); + case FBT_BOOL: return ReadUInt64(data_, parent_width_); + default: + // Convert other things to uint. + return 0; + } + } + + uint32_t AsUInt32() const { return static_cast<uint32_t>(AsUInt64()); } + uint16_t AsUInt16() const { return static_cast<uint16_t>(AsUInt64()); } + uint8_t AsUInt8() const { return static_cast<uint8_t>(AsUInt64()); } + + double AsDouble() const { + if (type_ == FBT_FLOAT) { + // A fast path for the common case. + return ReadDouble(data_, parent_width_); + } else + switch (type_) { + case FBT_INDIRECT_FLOAT: return ReadDouble(Indirect(), byte_width_); + case FBT_INT: + return static_cast<double>(ReadInt64(data_, parent_width_)); + case FBT_UINT: + return static_cast<double>(ReadUInt64(data_, parent_width_)); + case FBT_INDIRECT_INT: + return static_cast<double>(ReadInt64(Indirect(), byte_width_)); + case FBT_INDIRECT_UINT: + return static_cast<double>(ReadUInt64(Indirect(), byte_width_)); + case FBT_NULL: return 0.0; case FBT_STRING: { double d; flatbuffers::StringToNumber(AsString().c_str(), &d); return d; } - case FBT_VECTOR: return static_cast<double>(AsVector().size()); - case FBT_BOOL: - return static_cast<double>(ReadUInt64(data_, parent_width_)); - default: - // Convert strings and other things to float. - return 0; - } - } - - float AsFloat() const { return static_cast<float>(AsDouble()); } - - const char *AsKey() const { + case FBT_VECTOR: return static_cast<double>(AsVector().size()); + case FBT_BOOL: + return static_cast<double>(ReadUInt64(data_, parent_width_)); + default: + // Convert strings and other things to float. + return 0; + } + } + + float AsFloat() const { return static_cast<float>(AsDouble()); } + + const char *AsKey() const { if (type_ == FBT_KEY || type_ == FBT_STRING) { - return reinterpret_cast<const char *>(Indirect()); - } else { - return ""; - } - } - + return reinterpret_cast<const char *>(Indirect()); + } else { + return ""; + } + } + // This function returns the empty string if you try to read something that // is not a string or key. - String AsString() const { - if (type_ == FBT_STRING) { - return String(Indirect(), byte_width_); + String AsString() const { + if (type_ == FBT_STRING) { + return String(Indirect(), byte_width_); } else if (type_ == FBT_KEY) { auto key = Indirect(); return String(key, byte_width_, strlen(reinterpret_cast<const char *>(key))); - } else { - return String::EmptyString(); - } - } - - // Unlike AsString(), this will convert any type to a std::string. + } else { + return String::EmptyString(); + } + } + + // Unlike AsString(), this will convert any type to a std::string. std::string ToString() const { - std::string s; - ToString(false, false, s); - return s; - } - - // Convert any type to a JSON-like string. strings_quoted determines if - // string values at the top level receive "" quotes (inside other values - // they always do). keys_quoted determines if keys are quoted, at any level. - // TODO(wvo): add further options to have indentation/newlines. - void ToString(bool strings_quoted, bool keys_quoted, std::string &s) const { - if (type_ == FBT_STRING) { - String str(Indirect(), byte_width_); - if (strings_quoted) { - flatbuffers::EscapeString(str.c_str(), str.length(), &s, true, false); - } else { - s.append(str.c_str(), str.length()); - } - } else if (IsKey()) { - auto str = AsKey(); - if (keys_quoted) { - flatbuffers::EscapeString(str, strlen(str), &s, true, false); - } else { - s += str; - } - } else if (IsInt()) { - s += flatbuffers::NumToString(AsInt64()); - } else if (IsUInt()) { - s += flatbuffers::NumToString(AsUInt64()); - } else if (IsFloat()) { - s += flatbuffers::NumToString(AsDouble()); - } else if (IsNull()) { - s += "null"; - } else if (IsBool()) { - s += AsBool() ? "true" : "false"; - } else if (IsMap()) { - s += "{ "; - auto m = AsMap(); - auto keys = m.Keys(); - auto vals = m.Values(); - for (size_t i = 0; i < keys.size(); i++) { - keys[i].ToString(true, keys_quoted, s); - s += ": "; - vals[i].ToString(true, keys_quoted, s); - if (i < keys.size() - 1) s += ", "; - } - s += " }"; - } else if (IsVector()) { + std::string s; + ToString(false, false, s); + return s; + } + + // Convert any type to a JSON-like string. strings_quoted determines if + // string values at the top level receive "" quotes (inside other values + // they always do). keys_quoted determines if keys are quoted, at any level. + // TODO(wvo): add further options to have indentation/newlines. + void ToString(bool strings_quoted, bool keys_quoted, std::string &s) const { + if (type_ == FBT_STRING) { + String str(Indirect(), byte_width_); + if (strings_quoted) { + flatbuffers::EscapeString(str.c_str(), str.length(), &s, true, false); + } else { + s.append(str.c_str(), str.length()); + } + } else if (IsKey()) { + auto str = AsKey(); + if (keys_quoted) { + flatbuffers::EscapeString(str, strlen(str), &s, true, false); + } else { + s += str; + } + } else if (IsInt()) { + s += flatbuffers::NumToString(AsInt64()); + } else if (IsUInt()) { + s += flatbuffers::NumToString(AsUInt64()); + } else if (IsFloat()) { + s += flatbuffers::NumToString(AsDouble()); + } else if (IsNull()) { + s += "null"; + } else if (IsBool()) { + s += AsBool() ? "true" : "false"; + } else if (IsMap()) { + s += "{ "; + auto m = AsMap(); + auto keys = m.Keys(); + auto vals = m.Values(); + for (size_t i = 0; i < keys.size(); i++) { + keys[i].ToString(true, keys_quoted, s); + s += ": "; + vals[i].ToString(true, keys_quoted, s); + if (i < keys.size() - 1) s += ", "; + } + s += " }"; + } else if (IsVector()) { AppendToString<Vector>(s, AsVector(), keys_quoted); } else if (IsTypedVector()) { AppendToString<TypedVector>(s, AsTypedVector(), keys_quoted); @@ -588,33 +588,33 @@ class Reference { auto blob = AsBlob(); flatbuffers::EscapeString(reinterpret_cast<const char *>(blob.data()), blob.size(), &s, true, false); - } else { - s += "(?)"; - } - } - - // This function returns the empty blob if you try to read a not-blob. - // Strings can be viewed as blobs too. - Blob AsBlob() const { - if (type_ == FBT_BLOB || type_ == FBT_STRING) { - return Blob(Indirect(), byte_width_); - } else { - return Blob::EmptyBlob(); - } - } - - // This function returns the empty vector if you try to read a not-vector. - // Maps can be viewed as vectors too. - Vector AsVector() const { - if (type_ == FBT_VECTOR || type_ == FBT_MAP) { - return Vector(Indirect(), byte_width_); - } else { - return Vector::EmptyVector(); - } - } - - TypedVector AsTypedVector() const { - if (IsTypedVector()) { + } else { + s += "(?)"; + } + } + + // This function returns the empty blob if you try to read a not-blob. + // Strings can be viewed as blobs too. + Blob AsBlob() const { + if (type_ == FBT_BLOB || type_ == FBT_STRING) { + return Blob(Indirect(), byte_width_); + } else { + return Blob::EmptyBlob(); + } + } + + // This function returns the empty vector if you try to read a not-vector. + // Maps can be viewed as vectors too. + Vector AsVector() const { + if (type_ == FBT_VECTOR || type_ == FBT_MAP) { + return Vector(Indirect(), byte_width_); + } else { + return Vector::EmptyVector(); + } + } + + TypedVector AsTypedVector() const { + if (IsTypedVector()) { auto tv = TypedVector(Indirect(), byte_width_, ToTypedVectorElementType(type_)); if (tv.type_ == FBT_STRING) { @@ -627,149 +627,149 @@ class Reference { tv.type_ = FBT_KEY; } return tv; - } else { - return TypedVector::EmptyTypedVector(); - } - } - - FixedTypedVector AsFixedTypedVector() const { - if (IsFixedTypedVector()) { - uint8_t len = 0; - auto vtype = ToFixedTypedVectorElementType(type_, &len); - return FixedTypedVector(Indirect(), byte_width_, vtype, len); - } else { - return FixedTypedVector::EmptyFixedTypedVector(); - } - } - - Map AsMap() const { - if (type_ == FBT_MAP) { - return Map(Indirect(), byte_width_); - } else { - return Map::EmptyMap(); - } - } - + } else { + return TypedVector::EmptyTypedVector(); + } + } + + FixedTypedVector AsFixedTypedVector() const { + if (IsFixedTypedVector()) { + uint8_t len = 0; + auto vtype = ToFixedTypedVectorElementType(type_, &len); + return FixedTypedVector(Indirect(), byte_width_, vtype, len); + } else { + return FixedTypedVector::EmptyFixedTypedVector(); + } + } + + Map AsMap() const { + if (type_ == FBT_MAP) { + return Map(Indirect(), byte_width_); + } else { + return Map::EmptyMap(); + } + } + template<typename T> T As() const; - - // Experimental: Mutation functions. - // These allow scalars in an already created buffer to be updated in-place. - // Since by default scalars are stored in the smallest possible space, - // the new value may not fit, in which case these functions return false. - // To avoid this, you can construct the values you intend to mutate using - // Builder::ForceMinimumBitWidth. - bool MutateInt(int64_t i) { - if (type_ == FBT_INT) { - return Mutate(data_, i, parent_width_, WidthI(i)); - } else if (type_ == FBT_INDIRECT_INT) { - return Mutate(Indirect(), i, byte_width_, WidthI(i)); - } else if (type_ == FBT_UINT) { - auto u = static_cast<uint64_t>(i); - return Mutate(data_, u, parent_width_, WidthU(u)); - } else if (type_ == FBT_INDIRECT_UINT) { - auto u = static_cast<uint64_t>(i); - return Mutate(Indirect(), u, byte_width_, WidthU(u)); - } else { - return false; - } - } - - bool MutateBool(bool b) { - return type_ == FBT_BOOL && Mutate(data_, b, parent_width_, BIT_WIDTH_8); - } - - bool MutateUInt(uint64_t u) { - if (type_ == FBT_UINT) { - return Mutate(data_, u, parent_width_, WidthU(u)); - } else if (type_ == FBT_INDIRECT_UINT) { - return Mutate(Indirect(), u, byte_width_, WidthU(u)); - } else if (type_ == FBT_INT) { - auto i = static_cast<int64_t>(u); - return Mutate(data_, i, parent_width_, WidthI(i)); - } else if (type_ == FBT_INDIRECT_INT) { - auto i = static_cast<int64_t>(u); - return Mutate(Indirect(), i, byte_width_, WidthI(i)); - } else { - return false; - } - } - - bool MutateFloat(float f) { - if (type_ == FBT_FLOAT) { - return MutateF(data_, f, parent_width_, BIT_WIDTH_32); - } else if (type_ == FBT_INDIRECT_FLOAT) { - return MutateF(Indirect(), f, byte_width_, BIT_WIDTH_32); - } else { - return false; - } - } - - bool MutateFloat(double d) { - if (type_ == FBT_FLOAT) { - return MutateF(data_, d, parent_width_, WidthF(d)); - } else if (type_ == FBT_INDIRECT_FLOAT) { - return MutateF(Indirect(), d, byte_width_, WidthF(d)); - } else { - return false; - } - } - - bool MutateString(const char *str, size_t len) { - auto s = AsString(); - if (s.IsTheEmptyString()) return false; - // This is very strict, could allow shorter strings, but that creates - // garbage. - if (s.length() != len) return false; - memcpy(const_cast<char *>(s.c_str()), str, len); - return true; - } - bool MutateString(const char *str) { return MutateString(str, strlen(str)); } - bool MutateString(const std::string &str) { - return MutateString(str.data(), str.length()); - } - - private: - const uint8_t *Indirect() const { - return flexbuffers::Indirect(data_, parent_width_); - } - - template<typename T> - bool Mutate(const uint8_t *dest, T t, size_t byte_width, - BitWidth value_width) { - auto fits = static_cast<size_t>(static_cast<size_t>(1U) << value_width) <= - byte_width; - if (fits) { - t = flatbuffers::EndianScalar(t); - memcpy(const_cast<uint8_t *>(dest), &t, byte_width); - } - return fits; - } - - template<typename T> - bool MutateF(const uint8_t *dest, T t, size_t byte_width, - BitWidth value_width) { - if (byte_width == sizeof(double)) - return Mutate(dest, static_cast<double>(t), byte_width, value_width); - if (byte_width == sizeof(float)) - return Mutate(dest, static_cast<float>(t), byte_width, value_width); - FLATBUFFERS_ASSERT(false); - return false; - } - - const uint8_t *data_; - uint8_t parent_width_; - uint8_t byte_width_; - Type type_; -}; - -// Template specialization for As(). + + // Experimental: Mutation functions. + // These allow scalars in an already created buffer to be updated in-place. + // Since by default scalars are stored in the smallest possible space, + // the new value may not fit, in which case these functions return false. + // To avoid this, you can construct the values you intend to mutate using + // Builder::ForceMinimumBitWidth. + bool MutateInt(int64_t i) { + if (type_ == FBT_INT) { + return Mutate(data_, i, parent_width_, WidthI(i)); + } else if (type_ == FBT_INDIRECT_INT) { + return Mutate(Indirect(), i, byte_width_, WidthI(i)); + } else if (type_ == FBT_UINT) { + auto u = static_cast<uint64_t>(i); + return Mutate(data_, u, parent_width_, WidthU(u)); + } else if (type_ == FBT_INDIRECT_UINT) { + auto u = static_cast<uint64_t>(i); + return Mutate(Indirect(), u, byte_width_, WidthU(u)); + } else { + return false; + } + } + + bool MutateBool(bool b) { + return type_ == FBT_BOOL && Mutate(data_, b, parent_width_, BIT_WIDTH_8); + } + + bool MutateUInt(uint64_t u) { + if (type_ == FBT_UINT) { + return Mutate(data_, u, parent_width_, WidthU(u)); + } else if (type_ == FBT_INDIRECT_UINT) { + return Mutate(Indirect(), u, byte_width_, WidthU(u)); + } else if (type_ == FBT_INT) { + auto i = static_cast<int64_t>(u); + return Mutate(data_, i, parent_width_, WidthI(i)); + } else if (type_ == FBT_INDIRECT_INT) { + auto i = static_cast<int64_t>(u); + return Mutate(Indirect(), i, byte_width_, WidthI(i)); + } else { + return false; + } + } + + bool MutateFloat(float f) { + if (type_ == FBT_FLOAT) { + return MutateF(data_, f, parent_width_, BIT_WIDTH_32); + } else if (type_ == FBT_INDIRECT_FLOAT) { + return MutateF(Indirect(), f, byte_width_, BIT_WIDTH_32); + } else { + return false; + } + } + + bool MutateFloat(double d) { + if (type_ == FBT_FLOAT) { + return MutateF(data_, d, parent_width_, WidthF(d)); + } else if (type_ == FBT_INDIRECT_FLOAT) { + return MutateF(Indirect(), d, byte_width_, WidthF(d)); + } else { + return false; + } + } + + bool MutateString(const char *str, size_t len) { + auto s = AsString(); + if (s.IsTheEmptyString()) return false; + // This is very strict, could allow shorter strings, but that creates + // garbage. + if (s.length() != len) return false; + memcpy(const_cast<char *>(s.c_str()), str, len); + return true; + } + bool MutateString(const char *str) { return MutateString(str, strlen(str)); } + bool MutateString(const std::string &str) { + return MutateString(str.data(), str.length()); + } + + private: + const uint8_t *Indirect() const { + return flexbuffers::Indirect(data_, parent_width_); + } + + template<typename T> + bool Mutate(const uint8_t *dest, T t, size_t byte_width, + BitWidth value_width) { + auto fits = static_cast<size_t>(static_cast<size_t>(1U) << value_width) <= + byte_width; + if (fits) { + t = flatbuffers::EndianScalar(t); + memcpy(const_cast<uint8_t *>(dest), &t, byte_width); + } + return fits; + } + + template<typename T> + bool MutateF(const uint8_t *dest, T t, size_t byte_width, + BitWidth value_width) { + if (byte_width == sizeof(double)) + return Mutate(dest, static_cast<double>(t), byte_width, value_width); + if (byte_width == sizeof(float)) + return Mutate(dest, static_cast<float>(t), byte_width, value_width); + FLATBUFFERS_ASSERT(false); + return false; + } + + const uint8_t *data_; + uint8_t parent_width_; + uint8_t byte_width_; + Type type_; +}; + +// Template specialization for As(). template<> inline bool Reference::As<bool>() const { return AsBool(); } - + template<> inline int8_t Reference::As<int8_t>() const { return AsInt8(); } template<> inline int16_t Reference::As<int16_t>() const { return AsInt16(); } template<> inline int32_t Reference::As<int32_t>() const { return AsInt32(); } template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); } - + template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); } template<> inline uint16_t Reference::As<uint16_t>() const { return AsUInt16(); @@ -780,488 +780,488 @@ template<> inline uint32_t Reference::As<uint32_t>() const { template<> inline uint64_t Reference::As<uint64_t>() const { return AsUInt64(); } - + template<> inline double Reference::As<double>() const { return AsDouble(); } template<> inline float Reference::As<float>() const { return AsFloat(); } - + template<> inline String Reference::As<String>() const { return AsString(); } template<> inline std::string Reference::As<std::string>() const { - return AsString().str(); -} - + return AsString().str(); +} + template<> inline Blob Reference::As<Blob>() const { return AsBlob(); } template<> inline Vector Reference::As<Vector>() const { return AsVector(); } template<> inline TypedVector Reference::As<TypedVector>() const { - return AsTypedVector(); -} + return AsTypedVector(); +} template<> inline FixedTypedVector Reference::As<FixedTypedVector>() const { - return AsFixedTypedVector(); -} + return AsFixedTypedVector(); +} template<> inline Map Reference::As<Map>() const { return AsMap(); } - -inline uint8_t PackedType(BitWidth bit_width, Type type) { - return static_cast<uint8_t>(bit_width | (type << 2)); -} - -inline uint8_t NullPackedType() { return PackedType(BIT_WIDTH_8, FBT_NULL); } - -// Vector accessors. -// Note: if you try to access outside of bounds, you get a Null value back -// instead. Normally this would be an assert, but since this is "dynamically -// typed" data, you may not want that (someone sends you a 2d vector and you -// wanted 3d). -// The Null converts seamlessly into a default value for any other type. -// TODO(wvo): Could introduce an #ifdef that makes this into an assert? -inline Reference Vector::operator[](size_t i) const { - auto len = size(); - if (i >= len) return Reference(nullptr, 1, NullPackedType()); - auto packed_type = (data_ + len * byte_width_)[i]; - auto elem = data_ + i * byte_width_; - return Reference(elem, byte_width_, packed_type); -} - -inline Reference TypedVector::operator[](size_t i) const { - auto len = size(); - if (i >= len) return Reference(nullptr, 1, NullPackedType()); - auto elem = data_ + i * byte_width_; - return Reference(elem, byte_width_, 1, type_); -} - -inline Reference FixedTypedVector::operator[](size_t i) const { - if (i >= len_) return Reference(nullptr, 1, NullPackedType()); - auto elem = data_ + i * byte_width_; - return Reference(elem, byte_width_, 1, type_); -} - -template<typename T> int KeyCompare(const void *key, const void *elem) { - auto str_elem = reinterpret_cast<const char *>( - Indirect<T>(reinterpret_cast<const uint8_t *>(elem))); - auto skey = reinterpret_cast<const char *>(key); - return strcmp(skey, str_elem); -} - -inline Reference Map::operator[](const char *key) const { - auto keys = Keys(); - // We can't pass keys.byte_width_ to the comparison function, so we have - // to pick the right one ahead of time. - int (*comp)(const void *, const void *) = nullptr; - switch (keys.byte_width_) { - case 1: comp = KeyCompare<uint8_t>; break; - case 2: comp = KeyCompare<uint16_t>; break; - case 4: comp = KeyCompare<uint32_t>; break; - case 8: comp = KeyCompare<uint64_t>; break; - } - auto res = std::bsearch(key, keys.data_, keys.size(), keys.byte_width_, comp); - if (!res) return Reference(nullptr, 1, NullPackedType()); - auto i = (reinterpret_cast<uint8_t *>(res) - keys.data_) / keys.byte_width_; - return (*static_cast<const Vector *>(this))[i]; -} - -inline Reference Map::operator[](const std::string &key) const { - return (*this)[key.c_str()]; -} - -inline Reference GetRoot(const uint8_t *buffer, size_t size) { - // See Finish() below for the serialization counterpart of this. - // The root starts at the end of the buffer, so we parse backwards from there. - auto end = buffer + size; - auto byte_width = *--end; - auto packed_type = *--end; - end -= byte_width; // The root data item. - return Reference(end, byte_width, packed_type); -} - -inline Reference GetRoot(const std::vector<uint8_t> &buffer) { - return GetRoot(flatbuffers::vector_data(buffer), buffer.size()); -} - -// Flags that configure how the Builder behaves. -// The "Share" flags determine if the Builder automatically tries to pool -// this type. Pooling can reduce the size of serialized data if there are -// multiple maps of the same kind, at the expense of slightly slower -// serialization (the cost of lookups) and more memory use (std::set). -// By default this is on for keys, but off for strings. -// Turn keys off if you have e.g. only one map. -// Turn strings on if you expect many non-unique string values. -// Additionally, sharing key vectors can save space if you have maps with -// identical field populations. -enum BuilderFlag { - BUILDER_FLAG_NONE = 0, - BUILDER_FLAG_SHARE_KEYS = 1, - BUILDER_FLAG_SHARE_STRINGS = 2, - BUILDER_FLAG_SHARE_KEYS_AND_STRINGS = 3, - BUILDER_FLAG_SHARE_KEY_VECTORS = 4, - BUILDER_FLAG_SHARE_ALL = 7, -}; - -class Builder FLATBUFFERS_FINAL_CLASS { - public: - Builder(size_t initial_size = 256, - BuilderFlag flags = BUILDER_FLAG_SHARE_KEYS) - : buf_(initial_size), - finished_(false), + +inline uint8_t PackedType(BitWidth bit_width, Type type) { + return static_cast<uint8_t>(bit_width | (type << 2)); +} + +inline uint8_t NullPackedType() { return PackedType(BIT_WIDTH_8, FBT_NULL); } + +// Vector accessors. +// Note: if you try to access outside of bounds, you get a Null value back +// instead. Normally this would be an assert, but since this is "dynamically +// typed" data, you may not want that (someone sends you a 2d vector and you +// wanted 3d). +// The Null converts seamlessly into a default value for any other type. +// TODO(wvo): Could introduce an #ifdef that makes this into an assert? +inline Reference Vector::operator[](size_t i) const { + auto len = size(); + if (i >= len) return Reference(nullptr, 1, NullPackedType()); + auto packed_type = (data_ + len * byte_width_)[i]; + auto elem = data_ + i * byte_width_; + return Reference(elem, byte_width_, packed_type); +} + +inline Reference TypedVector::operator[](size_t i) const { + auto len = size(); + if (i >= len) return Reference(nullptr, 1, NullPackedType()); + auto elem = data_ + i * byte_width_; + return Reference(elem, byte_width_, 1, type_); +} + +inline Reference FixedTypedVector::operator[](size_t i) const { + if (i >= len_) return Reference(nullptr, 1, NullPackedType()); + auto elem = data_ + i * byte_width_; + return Reference(elem, byte_width_, 1, type_); +} + +template<typename T> int KeyCompare(const void *key, const void *elem) { + auto str_elem = reinterpret_cast<const char *>( + Indirect<T>(reinterpret_cast<const uint8_t *>(elem))); + auto skey = reinterpret_cast<const char *>(key); + return strcmp(skey, str_elem); +} + +inline Reference Map::operator[](const char *key) const { + auto keys = Keys(); + // We can't pass keys.byte_width_ to the comparison function, so we have + // to pick the right one ahead of time. + int (*comp)(const void *, const void *) = nullptr; + switch (keys.byte_width_) { + case 1: comp = KeyCompare<uint8_t>; break; + case 2: comp = KeyCompare<uint16_t>; break; + case 4: comp = KeyCompare<uint32_t>; break; + case 8: comp = KeyCompare<uint64_t>; break; + } + auto res = std::bsearch(key, keys.data_, keys.size(), keys.byte_width_, comp); + if (!res) return Reference(nullptr, 1, NullPackedType()); + auto i = (reinterpret_cast<uint8_t *>(res) - keys.data_) / keys.byte_width_; + return (*static_cast<const Vector *>(this))[i]; +} + +inline Reference Map::operator[](const std::string &key) const { + return (*this)[key.c_str()]; +} + +inline Reference GetRoot(const uint8_t *buffer, size_t size) { + // See Finish() below for the serialization counterpart of this. + // The root starts at the end of the buffer, so we parse backwards from there. + auto end = buffer + size; + auto byte_width = *--end; + auto packed_type = *--end; + end -= byte_width; // The root data item. + return Reference(end, byte_width, packed_type); +} + +inline Reference GetRoot(const std::vector<uint8_t> &buffer) { + return GetRoot(flatbuffers::vector_data(buffer), buffer.size()); +} + +// Flags that configure how the Builder behaves. +// The "Share" flags determine if the Builder automatically tries to pool +// this type. Pooling can reduce the size of serialized data if there are +// multiple maps of the same kind, at the expense of slightly slower +// serialization (the cost of lookups) and more memory use (std::set). +// By default this is on for keys, but off for strings. +// Turn keys off if you have e.g. only one map. +// Turn strings on if you expect many non-unique string values. +// Additionally, sharing key vectors can save space if you have maps with +// identical field populations. +enum BuilderFlag { + BUILDER_FLAG_NONE = 0, + BUILDER_FLAG_SHARE_KEYS = 1, + BUILDER_FLAG_SHARE_STRINGS = 2, + BUILDER_FLAG_SHARE_KEYS_AND_STRINGS = 3, + BUILDER_FLAG_SHARE_KEY_VECTORS = 4, + BUILDER_FLAG_SHARE_ALL = 7, +}; + +class Builder FLATBUFFERS_FINAL_CLASS { + public: + Builder(size_t initial_size = 256, + BuilderFlag flags = BUILDER_FLAG_SHARE_KEYS) + : buf_(initial_size), + finished_(false), has_duplicate_keys_(false), - flags_(flags), - force_min_bit_width_(BIT_WIDTH_8), - key_pool(KeyOffsetCompare(buf_)), - string_pool(StringOffsetCompare(buf_)) { - buf_.clear(); - } - + flags_(flags), + force_min_bit_width_(BIT_WIDTH_8), + key_pool(KeyOffsetCompare(buf_)), + string_pool(StringOffsetCompare(buf_)) { + buf_.clear(); + } + #ifdef FLATBUFFERS_DEFAULT_DECLARATION Builder(Builder &&) = default; Builder &operator=(Builder &&) = default; #endif - /// @brief Get the serialized buffer (after you call `Finish()`). - /// @return Returns a vector owned by this class. - const std::vector<uint8_t> &GetBuffer() const { - Finished(); - return buf_; - } - - // Size of the buffer. Does not include unfinished values. - size_t GetSize() const { return buf_.size(); } - - // Reset all state so we can re-use the buffer. - void Clear() { - buf_.clear(); - stack_.clear(); - finished_ = false; - // flags_ remains as-is; - force_min_bit_width_ = BIT_WIDTH_8; - key_pool.clear(); - string_pool.clear(); - } - - // All value constructing functions below have two versions: one that - // takes a key (for placement inside a map) and one that doesn't (for inside - // vectors and elsewhere). - - void Null() { stack_.push_back(Value()); } - void Null(const char *key) { - Key(key); - Null(); - } - - void Int(int64_t i) { stack_.push_back(Value(i, FBT_INT, WidthI(i))); } - void Int(const char *key, int64_t i) { - Key(key); - Int(i); - } - - void UInt(uint64_t u) { stack_.push_back(Value(u, FBT_UINT, WidthU(u))); } - void UInt(const char *key, uint64_t u) { - Key(key); - UInt(u); - } - - void Float(float f) { stack_.push_back(Value(f)); } - void Float(const char *key, float f) { - Key(key); - Float(f); - } - - void Double(double f) { stack_.push_back(Value(f)); } - void Double(const char *key, double d) { - Key(key); - Double(d); - } - - void Bool(bool b) { stack_.push_back(Value(b)); } - void Bool(const char *key, bool b) { - Key(key); - Bool(b); - } - - void IndirectInt(int64_t i) { PushIndirect(i, FBT_INDIRECT_INT, WidthI(i)); } - void IndirectInt(const char *key, int64_t i) { - Key(key); - IndirectInt(i); - } - - void IndirectUInt(uint64_t u) { - PushIndirect(u, FBT_INDIRECT_UINT, WidthU(u)); - } - void IndirectUInt(const char *key, uint64_t u) { - Key(key); - IndirectUInt(u); - } - - void IndirectFloat(float f) { - PushIndirect(f, FBT_INDIRECT_FLOAT, BIT_WIDTH_32); - } - void IndirectFloat(const char *key, float f) { - Key(key); - IndirectFloat(f); - } - - void IndirectDouble(double f) { - PushIndirect(f, FBT_INDIRECT_FLOAT, WidthF(f)); - } - void IndirectDouble(const char *key, double d) { - Key(key); - IndirectDouble(d); - } - - size_t Key(const char *str, size_t len) { - auto sloc = buf_.size(); - WriteBytes(str, len + 1); - if (flags_ & BUILDER_FLAG_SHARE_KEYS) { - auto it = key_pool.find(sloc); - if (it != key_pool.end()) { - // Already in the buffer. Remove key we just serialized, and use - // existing offset instead. - buf_.resize(sloc); - sloc = *it; - } else { - key_pool.insert(sloc); - } - } - stack_.push_back(Value(static_cast<uint64_t>(sloc), FBT_KEY, BIT_WIDTH_8)); - return sloc; - } - - size_t Key(const char *str) { return Key(str, strlen(str)); } - size_t Key(const std::string &str) { return Key(str.c_str(), str.size()); } - - size_t String(const char *str, size_t len) { - auto reset_to = buf_.size(); - auto sloc = CreateBlob(str, len, 1, FBT_STRING); - if (flags_ & BUILDER_FLAG_SHARE_STRINGS) { - StringOffset so(sloc, len); - auto it = string_pool.find(so); - if (it != string_pool.end()) { - // Already in the buffer. Remove string we just serialized, and use - // existing offset instead. - buf_.resize(reset_to); - sloc = it->first; - stack_.back().u_ = sloc; - } else { - string_pool.insert(so); - } - } - return sloc; - } - size_t String(const char *str) { return String(str, strlen(str)); } - size_t String(const std::string &str) { - return String(str.c_str(), str.size()); - } - void String(const flexbuffers::String &str) { - String(str.c_str(), str.length()); - } - - void String(const char *key, const char *str) { - Key(key); - String(str); - } - void String(const char *key, const std::string &str) { - Key(key); - String(str); - } - void String(const char *key, const flexbuffers::String &str) { - Key(key); - String(str); - } - - size_t Blob(const void *data, size_t len) { - return CreateBlob(data, len, 0, FBT_BLOB); - } - size_t Blob(const std::vector<uint8_t> &v) { - return CreateBlob(flatbuffers::vector_data(v), v.size(), 0, FBT_BLOB); - } - - // TODO(wvo): support all the FlexBuffer types (like flexbuffers::String), - // e.g. Vector etc. Also in overloaded versions. - // Also some FlatBuffers types? - - size_t StartVector() { return stack_.size(); } - size_t StartVector(const char *key) { - Key(key); - return stack_.size(); - } - size_t StartMap() { return stack_.size(); } - size_t StartMap(const char *key) { - Key(key); - return stack_.size(); - } - - // TODO(wvo): allow this to specify an aligment greater than the natural - // alignment. - size_t EndVector(size_t start, bool typed, bool fixed) { - auto vec = CreateVector(start, stack_.size() - start, 1, typed, fixed); - // Remove temp elements and return vector. - stack_.resize(start); - stack_.push_back(vec); - return static_cast<size_t>(vec.u_); - } - - size_t EndMap(size_t start) { - // We should have interleaved keys and values on the stack. - // Make sure it is an even number: - auto len = stack_.size() - start; - FLATBUFFERS_ASSERT(!(len & 1)); - len /= 2; - // Make sure keys are all strings: - for (auto key = start; key < stack_.size(); key += 2) { - FLATBUFFERS_ASSERT(stack_[key].type_ == FBT_KEY); - } + /// @brief Get the serialized buffer (after you call `Finish()`). + /// @return Returns a vector owned by this class. + const std::vector<uint8_t> &GetBuffer() const { + Finished(); + return buf_; + } + + // Size of the buffer. Does not include unfinished values. + size_t GetSize() const { return buf_.size(); } + + // Reset all state so we can re-use the buffer. + void Clear() { + buf_.clear(); + stack_.clear(); + finished_ = false; + // flags_ remains as-is; + force_min_bit_width_ = BIT_WIDTH_8; + key_pool.clear(); + string_pool.clear(); + } + + // All value constructing functions below have two versions: one that + // takes a key (for placement inside a map) and one that doesn't (for inside + // vectors and elsewhere). + + void Null() { stack_.push_back(Value()); } + void Null(const char *key) { + Key(key); + Null(); + } + + void Int(int64_t i) { stack_.push_back(Value(i, FBT_INT, WidthI(i))); } + void Int(const char *key, int64_t i) { + Key(key); + Int(i); + } + + void UInt(uint64_t u) { stack_.push_back(Value(u, FBT_UINT, WidthU(u))); } + void UInt(const char *key, uint64_t u) { + Key(key); + UInt(u); + } + + void Float(float f) { stack_.push_back(Value(f)); } + void Float(const char *key, float f) { + Key(key); + Float(f); + } + + void Double(double f) { stack_.push_back(Value(f)); } + void Double(const char *key, double d) { + Key(key); + Double(d); + } + + void Bool(bool b) { stack_.push_back(Value(b)); } + void Bool(const char *key, bool b) { + Key(key); + Bool(b); + } + + void IndirectInt(int64_t i) { PushIndirect(i, FBT_INDIRECT_INT, WidthI(i)); } + void IndirectInt(const char *key, int64_t i) { + Key(key); + IndirectInt(i); + } + + void IndirectUInt(uint64_t u) { + PushIndirect(u, FBT_INDIRECT_UINT, WidthU(u)); + } + void IndirectUInt(const char *key, uint64_t u) { + Key(key); + IndirectUInt(u); + } + + void IndirectFloat(float f) { + PushIndirect(f, FBT_INDIRECT_FLOAT, BIT_WIDTH_32); + } + void IndirectFloat(const char *key, float f) { + Key(key); + IndirectFloat(f); + } + + void IndirectDouble(double f) { + PushIndirect(f, FBT_INDIRECT_FLOAT, WidthF(f)); + } + void IndirectDouble(const char *key, double d) { + Key(key); + IndirectDouble(d); + } + + size_t Key(const char *str, size_t len) { + auto sloc = buf_.size(); + WriteBytes(str, len + 1); + if (flags_ & BUILDER_FLAG_SHARE_KEYS) { + auto it = key_pool.find(sloc); + if (it != key_pool.end()) { + // Already in the buffer. Remove key we just serialized, and use + // existing offset instead. + buf_.resize(sloc); + sloc = *it; + } else { + key_pool.insert(sloc); + } + } + stack_.push_back(Value(static_cast<uint64_t>(sloc), FBT_KEY, BIT_WIDTH_8)); + return sloc; + } + + size_t Key(const char *str) { return Key(str, strlen(str)); } + size_t Key(const std::string &str) { return Key(str.c_str(), str.size()); } + + size_t String(const char *str, size_t len) { + auto reset_to = buf_.size(); + auto sloc = CreateBlob(str, len, 1, FBT_STRING); + if (flags_ & BUILDER_FLAG_SHARE_STRINGS) { + StringOffset so(sloc, len); + auto it = string_pool.find(so); + if (it != string_pool.end()) { + // Already in the buffer. Remove string we just serialized, and use + // existing offset instead. + buf_.resize(reset_to); + sloc = it->first; + stack_.back().u_ = sloc; + } else { + string_pool.insert(so); + } + } + return sloc; + } + size_t String(const char *str) { return String(str, strlen(str)); } + size_t String(const std::string &str) { + return String(str.c_str(), str.size()); + } + void String(const flexbuffers::String &str) { + String(str.c_str(), str.length()); + } + + void String(const char *key, const char *str) { + Key(key); + String(str); + } + void String(const char *key, const std::string &str) { + Key(key); + String(str); + } + void String(const char *key, const flexbuffers::String &str) { + Key(key); + String(str); + } + + size_t Blob(const void *data, size_t len) { + return CreateBlob(data, len, 0, FBT_BLOB); + } + size_t Blob(const std::vector<uint8_t> &v) { + return CreateBlob(flatbuffers::vector_data(v), v.size(), 0, FBT_BLOB); + } + + // TODO(wvo): support all the FlexBuffer types (like flexbuffers::String), + // e.g. Vector etc. Also in overloaded versions. + // Also some FlatBuffers types? + + size_t StartVector() { return stack_.size(); } + size_t StartVector(const char *key) { + Key(key); + return stack_.size(); + } + size_t StartMap() { return stack_.size(); } + size_t StartMap(const char *key) { + Key(key); + return stack_.size(); + } + + // TODO(wvo): allow this to specify an aligment greater than the natural + // alignment. + size_t EndVector(size_t start, bool typed, bool fixed) { + auto vec = CreateVector(start, stack_.size() - start, 1, typed, fixed); + // Remove temp elements and return vector. + stack_.resize(start); + stack_.push_back(vec); + return static_cast<size_t>(vec.u_); + } + + size_t EndMap(size_t start) { + // We should have interleaved keys and values on the stack. + // Make sure it is an even number: + auto len = stack_.size() - start; + FLATBUFFERS_ASSERT(!(len & 1)); + len /= 2; + // Make sure keys are all strings: + for (auto key = start; key < stack_.size(); key += 2) { + FLATBUFFERS_ASSERT(stack_[key].type_ == FBT_KEY); + } // Now sort values, so later we can do a binary search lookup. - // We want to sort 2 array elements at a time. - struct TwoValue { - Value key; - Value val; - }; - // TODO(wvo): strict aliasing? - // TODO(wvo): allow the caller to indicate the data is already sorted - // for maximum efficiency? With an assert to check sortedness to make sure - // we're not breaking binary search. - // Or, we can track if the map is sorted as keys are added which would be - // be quite cheap (cheaper than checking it here), so we can skip this - // step automatically when appliccable, and encourage people to write in - // sorted fashion. - // std::sort is typically already a lot faster on sorted data though. - auto dict = - reinterpret_cast<TwoValue *>(flatbuffers::vector_data(stack_) + start); - std::sort(dict, dict + len, - [&](const TwoValue &a, const TwoValue &b) -> bool { - auto as = reinterpret_cast<const char *>( - flatbuffers::vector_data(buf_) + a.key.u_); - auto bs = reinterpret_cast<const char *>( - flatbuffers::vector_data(buf_) + b.key.u_); - auto comp = strcmp(as, bs); + // We want to sort 2 array elements at a time. + struct TwoValue { + Value key; + Value val; + }; + // TODO(wvo): strict aliasing? + // TODO(wvo): allow the caller to indicate the data is already sorted + // for maximum efficiency? With an assert to check sortedness to make sure + // we're not breaking binary search. + // Or, we can track if the map is sorted as keys are added which would be + // be quite cheap (cheaper than checking it here), so we can skip this + // step automatically when appliccable, and encourage people to write in + // sorted fashion. + // std::sort is typically already a lot faster on sorted data though. + auto dict = + reinterpret_cast<TwoValue *>(flatbuffers::vector_data(stack_) + start); + std::sort(dict, dict + len, + [&](const TwoValue &a, const TwoValue &b) -> bool { + auto as = reinterpret_cast<const char *>( + flatbuffers::vector_data(buf_) + a.key.u_); + auto bs = reinterpret_cast<const char *>( + flatbuffers::vector_data(buf_) + b.key.u_); + auto comp = strcmp(as, bs); // We want to disallow duplicate keys, since this results in a // map where values cannot be found. // But we can't assert here (since we don't want to fail on // random JSON input) or have an error mechanism. // Instead, we set has_duplicate_keys_ in the builder to // signal this. - // TODO: Have to check for pointer equality, as some sort - // implementation apparently call this function with the same - // element?? Why? + // TODO: Have to check for pointer equality, as some sort + // implementation apparently call this function with the same + // element?? Why? if (!comp && &a != &b) has_duplicate_keys_ = true; - return comp < 0; - }); - // First create a vector out of all keys. - // TODO(wvo): if kBuilderFlagShareKeyVectors is true, see if we can share - // the first vector. - auto keys = CreateVector(start, len, 2, true, false); - auto vec = CreateVector(start + 1, len, 2, false, false, &keys); - // Remove temp elements and return map. - stack_.resize(start); - stack_.push_back(vec); - return static_cast<size_t>(vec.u_); - } - + return comp < 0; + }); + // First create a vector out of all keys. + // TODO(wvo): if kBuilderFlagShareKeyVectors is true, see if we can share + // the first vector. + auto keys = CreateVector(start, len, 2, true, false); + auto vec = CreateVector(start + 1, len, 2, false, false, &keys); + // Remove temp elements and return map. + stack_.resize(start); + stack_.push_back(vec); + return static_cast<size_t>(vec.u_); + } + // Call this after EndMap to see if the map had any duplicate keys. // Any map with such keys won't be able to retrieve all values. bool HasDuplicateKeys() const { return has_duplicate_keys_; } - template<typename F> size_t Vector(F f) { - auto start = StartVector(); - f(); - return EndVector(start, false, false); - } - template<typename F, typename T> size_t Vector(F f, T &state) { - auto start = StartVector(); - f(state); - return EndVector(start, false, false); - } - template<typename F> size_t Vector(const char *key, F f) { - auto start = StartVector(key); - f(); - return EndVector(start, false, false); - } - template<typename F, typename T> - size_t Vector(const char *key, F f, T &state) { - auto start = StartVector(key); - f(state); - return EndVector(start, false, false); - } - - template<typename T> void Vector(const T *elems, size_t len) { - if (flatbuffers::is_scalar<T>::value) { - // This path should be a lot quicker and use less space. - ScalarVector(elems, len, false); - } else { - auto start = StartVector(); - for (size_t i = 0; i < len; i++) Add(elems[i]); - EndVector(start, false, false); - } - } - template<typename T> - void Vector(const char *key, const T *elems, size_t len) { - Key(key); - Vector(elems, len); - } - template<typename T> void Vector(const std::vector<T> &vec) { - Vector(flatbuffers::vector_data(vec), vec.size()); - } - - template<typename F> size_t TypedVector(F f) { - auto start = StartVector(); - f(); - return EndVector(start, true, false); - } - template<typename F, typename T> size_t TypedVector(F f, T &state) { - auto start = StartVector(); - f(state); - return EndVector(start, true, false); - } - template<typename F> size_t TypedVector(const char *key, F f) { - auto start = StartVector(key); - f(); - return EndVector(start, true, false); - } - template<typename F, typename T> - size_t TypedVector(const char *key, F f, T &state) { - auto start = StartVector(key); - f(state); - return EndVector(start, true, false); - } - - template<typename T> size_t FixedTypedVector(const T *elems, size_t len) { - // We only support a few fixed vector lengths. Anything bigger use a - // regular typed vector. - FLATBUFFERS_ASSERT(len >= 2 && len <= 4); - // And only scalar values. - static_assert(flatbuffers::is_scalar<T>::value, "Unrelated types"); - return ScalarVector(elems, len, true); - } - - template<typename T> - size_t FixedTypedVector(const char *key, const T *elems, size_t len) { - Key(key); - return FixedTypedVector(elems, len); - } - - template<typename F> size_t Map(F f) { - auto start = StartMap(); - f(); - return EndMap(start); - } - template<typename F, typename T> size_t Map(F f, T &state) { - auto start = StartMap(); - f(state); - return EndMap(start); - } - template<typename F> size_t Map(const char *key, F f) { - auto start = StartMap(key); - f(); - return EndMap(start); - } - template<typename F, typename T> size_t Map(const char *key, F f, T &state) { - auto start = StartMap(key); - f(state); - return EndMap(start); - } - template<typename T> void Map(const std::map<std::string, T> &map) { - auto start = StartMap(); - for (auto it = map.begin(); it != map.end(); ++it) - Add(it->first.c_str(), it->second); - EndMap(start); - } - + template<typename F> size_t Vector(F f) { + auto start = StartVector(); + f(); + return EndVector(start, false, false); + } + template<typename F, typename T> size_t Vector(F f, T &state) { + auto start = StartVector(); + f(state); + return EndVector(start, false, false); + } + template<typename F> size_t Vector(const char *key, F f) { + auto start = StartVector(key); + f(); + return EndVector(start, false, false); + } + template<typename F, typename T> + size_t Vector(const char *key, F f, T &state) { + auto start = StartVector(key); + f(state); + return EndVector(start, false, false); + } + + template<typename T> void Vector(const T *elems, size_t len) { + if (flatbuffers::is_scalar<T>::value) { + // This path should be a lot quicker and use less space. + ScalarVector(elems, len, false); + } else { + auto start = StartVector(); + for (size_t i = 0; i < len; i++) Add(elems[i]); + EndVector(start, false, false); + } + } + template<typename T> + void Vector(const char *key, const T *elems, size_t len) { + Key(key); + Vector(elems, len); + } + template<typename T> void Vector(const std::vector<T> &vec) { + Vector(flatbuffers::vector_data(vec), vec.size()); + } + + template<typename F> size_t TypedVector(F f) { + auto start = StartVector(); + f(); + return EndVector(start, true, false); + } + template<typename F, typename T> size_t TypedVector(F f, T &state) { + auto start = StartVector(); + f(state); + return EndVector(start, true, false); + } + template<typename F> size_t TypedVector(const char *key, F f) { + auto start = StartVector(key); + f(); + return EndVector(start, true, false); + } + template<typename F, typename T> + size_t TypedVector(const char *key, F f, T &state) { + auto start = StartVector(key); + f(state); + return EndVector(start, true, false); + } + + template<typename T> size_t FixedTypedVector(const T *elems, size_t len) { + // We only support a few fixed vector lengths. Anything bigger use a + // regular typed vector. + FLATBUFFERS_ASSERT(len >= 2 && len <= 4); + // And only scalar values. + static_assert(flatbuffers::is_scalar<T>::value, "Unrelated types"); + return ScalarVector(elems, len, true); + } + + template<typename T> + size_t FixedTypedVector(const char *key, const T *elems, size_t len) { + Key(key); + return FixedTypedVector(elems, len); + } + + template<typename F> size_t Map(F f) { + auto start = StartMap(); + f(); + return EndMap(start); + } + template<typename F, typename T> size_t Map(F f, T &state) { + auto start = StartMap(); + f(state); + return EndMap(start); + } + template<typename F> size_t Map(const char *key, F f) { + auto start = StartMap(key); + f(); + return EndMap(start); + } + template<typename F, typename T> size_t Map(const char *key, F f, T &state) { + auto start = StartMap(key); + f(state); + return EndMap(start); + } + template<typename T> void Map(const std::map<std::string, T> &map) { + auto start = StartMap(); + for (auto it = map.begin(); it != map.end(); ++it) + Add(it->first.c_str(), it->second); + EndMap(start); + } + // If you wish to share a value explicitly (a value not shared automatically // through one of the BUILDER_FLAG_SHARE_* flags) you can do so with these // functions. Or if you wish to turn those flags off for performance reasons @@ -1280,357 +1280,357 @@ class Builder FLATBUFFERS_FINAL_CLASS { ReuseValue(v); } - // Overloaded Add that tries to call the correct function above. - void Add(int8_t i) { Int(i); } - void Add(int16_t i) { Int(i); } - void Add(int32_t i) { Int(i); } - void Add(int64_t i) { Int(i); } - void Add(uint8_t u) { UInt(u); } - void Add(uint16_t u) { UInt(u); } - void Add(uint32_t u) { UInt(u); } - void Add(uint64_t u) { UInt(u); } - void Add(float f) { Float(f); } - void Add(double d) { Double(d); } - void Add(bool b) { Bool(b); } - void Add(const char *str) { String(str); } - void Add(const std::string &str) { String(str); } - void Add(const flexbuffers::String &str) { String(str); } - - template<typename T> void Add(const std::vector<T> &vec) { Vector(vec); } - - template<typename T> void Add(const char *key, const T &t) { - Key(key); - Add(t); - } - - template<typename T> void Add(const std::map<std::string, T> &map) { - Map(map); - } - - template<typename T> void operator+=(const T &t) { Add(t); } - - // This function is useful in combination with the Mutate* functions above. - // It forces elements of vectors and maps to have a minimum size, such that - // they can later be updated without failing. - // Call with no arguments to reset. - void ForceMinimumBitWidth(BitWidth bw = BIT_WIDTH_8) { - force_min_bit_width_ = bw; - } - - void Finish() { - // If you hit this assert, you likely have objects that were never included - // in a parent. You need to have exactly one root to finish a buffer. - // Check your Start/End calls are matched, and all objects are inside - // some other object. - FLATBUFFERS_ASSERT(stack_.size() == 1); - - // Write root value. - auto byte_width = Align(stack_[0].ElemWidth(buf_.size(), 0)); - WriteAny(stack_[0], byte_width); - // Write root type. - Write(stack_[0].StoredPackedType(), 1); - // Write root size. Normally determined by parent, but root has no parent :) - Write(byte_width, 1); - - finished_ = true; - } - - private: - 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 - // Builder::Finish with your root object. - FLATBUFFERS_ASSERT(finished_); - } - - // Align to prepare for writing a scalar with a certain size. - uint8_t Align(BitWidth alignment) { - auto byte_width = 1U << alignment; - buf_.insert(buf_.end(), flatbuffers::PaddingBytes(buf_.size(), byte_width), - 0); - return static_cast<uint8_t>(byte_width); - } - - void WriteBytes(const void *val, size_t size) { - buf_.insert(buf_.end(), reinterpret_cast<const uint8_t *>(val), - reinterpret_cast<const uint8_t *>(val) + size); - } - - template<typename T> void Write(T val, size_t byte_width) { - FLATBUFFERS_ASSERT(sizeof(T) >= byte_width); - val = flatbuffers::EndianScalar(val); - WriteBytes(&val, byte_width); - } - - void WriteDouble(double f, uint8_t byte_width) { - switch (byte_width) { - case 8: Write(f, byte_width); break; - case 4: Write(static_cast<float>(f), byte_width); break; - // case 2: Write(static_cast<half>(f), byte_width); break; - // case 1: Write(static_cast<quarter>(f), byte_width); break; - default: FLATBUFFERS_ASSERT(0); - } - } - - void WriteOffset(uint64_t o, uint8_t byte_width) { - auto reloff = buf_.size() - o; - FLATBUFFERS_ASSERT(byte_width == 8 || reloff < 1ULL << (byte_width * 8)); - Write(reloff, byte_width); - } - - template<typename T> void PushIndirect(T val, Type type, BitWidth bit_width) { - auto byte_width = Align(bit_width); - auto iloc = buf_.size(); - Write(val, byte_width); - stack_.push_back(Value(static_cast<uint64_t>(iloc), type, bit_width)); - } - - static BitWidth WidthB(size_t byte_width) { - switch (byte_width) { - case 1: return BIT_WIDTH_8; - case 2: return BIT_WIDTH_16; - case 4: return BIT_WIDTH_32; - case 8: return BIT_WIDTH_64; - default: FLATBUFFERS_ASSERT(false); return BIT_WIDTH_64; - } - } - - template<typename T> static Type GetScalarType() { - static_assert(flatbuffers::is_scalar<T>::value, "Unrelated types"); - return flatbuffers::is_floating_point<T>::value - ? FBT_FLOAT - : flatbuffers::is_same<T, bool>::value - ? FBT_BOOL - : (flatbuffers::is_unsigned<T>::value ? FBT_UINT - : FBT_INT); - } - + // Overloaded Add that tries to call the correct function above. + void Add(int8_t i) { Int(i); } + void Add(int16_t i) { Int(i); } + void Add(int32_t i) { Int(i); } + void Add(int64_t i) { Int(i); } + void Add(uint8_t u) { UInt(u); } + void Add(uint16_t u) { UInt(u); } + void Add(uint32_t u) { UInt(u); } + void Add(uint64_t u) { UInt(u); } + void Add(float f) { Float(f); } + void Add(double d) { Double(d); } + void Add(bool b) { Bool(b); } + void Add(const char *str) { String(str); } + void Add(const std::string &str) { String(str); } + void Add(const flexbuffers::String &str) { String(str); } + + template<typename T> void Add(const std::vector<T> &vec) { Vector(vec); } + + template<typename T> void Add(const char *key, const T &t) { + Key(key); + Add(t); + } + + template<typename T> void Add(const std::map<std::string, T> &map) { + Map(map); + } + + template<typename T> void operator+=(const T &t) { Add(t); } + + // This function is useful in combination with the Mutate* functions above. + // It forces elements of vectors and maps to have a minimum size, such that + // they can later be updated without failing. + // Call with no arguments to reset. + void ForceMinimumBitWidth(BitWidth bw = BIT_WIDTH_8) { + force_min_bit_width_ = bw; + } + + void Finish() { + // If you hit this assert, you likely have objects that were never included + // in a parent. You need to have exactly one root to finish a buffer. + // Check your Start/End calls are matched, and all objects are inside + // some other object. + FLATBUFFERS_ASSERT(stack_.size() == 1); + + // Write root value. + auto byte_width = Align(stack_[0].ElemWidth(buf_.size(), 0)); + WriteAny(stack_[0], byte_width); + // Write root type. + Write(stack_[0].StoredPackedType(), 1); + // Write root size. Normally determined by parent, but root has no parent :) + Write(byte_width, 1); + + finished_ = true; + } + + private: + 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 + // Builder::Finish with your root object. + FLATBUFFERS_ASSERT(finished_); + } + + // Align to prepare for writing a scalar with a certain size. + uint8_t Align(BitWidth alignment) { + auto byte_width = 1U << alignment; + buf_.insert(buf_.end(), flatbuffers::PaddingBytes(buf_.size(), byte_width), + 0); + return static_cast<uint8_t>(byte_width); + } + + void WriteBytes(const void *val, size_t size) { + buf_.insert(buf_.end(), reinterpret_cast<const uint8_t *>(val), + reinterpret_cast<const uint8_t *>(val) + size); + } + + template<typename T> void Write(T val, size_t byte_width) { + FLATBUFFERS_ASSERT(sizeof(T) >= byte_width); + val = flatbuffers::EndianScalar(val); + WriteBytes(&val, byte_width); + } + + void WriteDouble(double f, uint8_t byte_width) { + switch (byte_width) { + case 8: Write(f, byte_width); break; + case 4: Write(static_cast<float>(f), byte_width); break; + // case 2: Write(static_cast<half>(f), byte_width); break; + // case 1: Write(static_cast<quarter>(f), byte_width); break; + default: FLATBUFFERS_ASSERT(0); + } + } + + void WriteOffset(uint64_t o, uint8_t byte_width) { + auto reloff = buf_.size() - o; + FLATBUFFERS_ASSERT(byte_width == 8 || reloff < 1ULL << (byte_width * 8)); + Write(reloff, byte_width); + } + + template<typename T> void PushIndirect(T val, Type type, BitWidth bit_width) { + auto byte_width = Align(bit_width); + auto iloc = buf_.size(); + Write(val, byte_width); + stack_.push_back(Value(static_cast<uint64_t>(iloc), type, bit_width)); + } + + static BitWidth WidthB(size_t byte_width) { + switch (byte_width) { + case 1: return BIT_WIDTH_8; + case 2: return BIT_WIDTH_16; + case 4: return BIT_WIDTH_32; + case 8: return BIT_WIDTH_64; + default: FLATBUFFERS_ASSERT(false); return BIT_WIDTH_64; + } + } + + template<typename T> static Type GetScalarType() { + static_assert(flatbuffers::is_scalar<T>::value, "Unrelated types"); + return flatbuffers::is_floating_point<T>::value + ? FBT_FLOAT + : flatbuffers::is_same<T, bool>::value + ? FBT_BOOL + : (flatbuffers::is_unsigned<T>::value ? FBT_UINT + : FBT_INT); + } + public: // This was really intended to be private, except for LastValue/ReuseValue. - struct Value { - union { - int64_t i_; - uint64_t u_; - double f_; - }; - - Type type_; - - // For scalars: of itself, for vector: of its elements, for string: length. - BitWidth min_bit_width_; - - Value() : i_(0), type_(FBT_NULL), min_bit_width_(BIT_WIDTH_8) {} - - Value(bool b) - : u_(static_cast<uint64_t>(b)), - type_(FBT_BOOL), - min_bit_width_(BIT_WIDTH_8) {} - - Value(int64_t i, Type t, BitWidth bw) - : i_(i), type_(t), min_bit_width_(bw) {} - Value(uint64_t u, Type t, BitWidth bw) - : u_(u), type_(t), min_bit_width_(bw) {} - + struct Value { + union { + int64_t i_; + uint64_t u_; + double f_; + }; + + Type type_; + + // For scalars: of itself, for vector: of its elements, for string: length. + BitWidth min_bit_width_; + + Value() : i_(0), type_(FBT_NULL), min_bit_width_(BIT_WIDTH_8) {} + + Value(bool b) + : u_(static_cast<uint64_t>(b)), + type_(FBT_BOOL), + min_bit_width_(BIT_WIDTH_8) {} + + Value(int64_t i, Type t, BitWidth bw) + : i_(i), type_(t), min_bit_width_(bw) {} + Value(uint64_t u, Type t, BitWidth bw) + : u_(u), type_(t), min_bit_width_(bw) {} + Value(float f) : f_(static_cast<double>(f)), type_(FBT_FLOAT), min_bit_width_(BIT_WIDTH_32) {} - Value(double f) : f_(f), type_(FBT_FLOAT), min_bit_width_(WidthF(f)) {} - - uint8_t StoredPackedType(BitWidth parent_bit_width_ = BIT_WIDTH_8) const { - return PackedType(StoredWidth(parent_bit_width_), type_); - } - - BitWidth ElemWidth(size_t buf_size, size_t elem_index) const { - if (IsInline(type_)) { - return min_bit_width_; - } else { - // We have an absolute offset, but want to store a relative offset - // elem_index elements beyond the current buffer end. Since whether - // the relative offset fits in a certain byte_width depends on - // the size of the elements before it (and their alignment), we have - // to test for each size in turn. - for (size_t byte_width = 1; - byte_width <= sizeof(flatbuffers::largest_scalar_t); - byte_width *= 2) { - // Where are we going to write this offset? - auto offset_loc = buf_size + - flatbuffers::PaddingBytes(buf_size, byte_width) + - elem_index * byte_width; - // Compute relative offset. - auto offset = offset_loc - u_; - // Does it fit? - auto bit_width = WidthU(offset); - if (static_cast<size_t>(static_cast<size_t>(1U) << bit_width) == - byte_width) - return bit_width; - } - FLATBUFFERS_ASSERT(false); // Must match one of the sizes above. - return BIT_WIDTH_64; - } - } - - BitWidth StoredWidth(BitWidth parent_bit_width_ = BIT_WIDTH_8) const { - if (IsInline(type_)) { - return (std::max)(min_bit_width_, parent_bit_width_); - } else { - return min_bit_width_; - } - } - }; - + Value(double f) : f_(f), type_(FBT_FLOAT), min_bit_width_(WidthF(f)) {} + + uint8_t StoredPackedType(BitWidth parent_bit_width_ = BIT_WIDTH_8) const { + return PackedType(StoredWidth(parent_bit_width_), type_); + } + + BitWidth ElemWidth(size_t buf_size, size_t elem_index) const { + if (IsInline(type_)) { + return min_bit_width_; + } else { + // We have an absolute offset, but want to store a relative offset + // elem_index elements beyond the current buffer end. Since whether + // the relative offset fits in a certain byte_width depends on + // the size of the elements before it (and their alignment), we have + // to test for each size in turn. + for (size_t byte_width = 1; + byte_width <= sizeof(flatbuffers::largest_scalar_t); + byte_width *= 2) { + // Where are we going to write this offset? + auto offset_loc = buf_size + + flatbuffers::PaddingBytes(buf_size, byte_width) + + elem_index * byte_width; + // Compute relative offset. + auto offset = offset_loc - u_; + // Does it fit? + auto bit_width = WidthU(offset); + if (static_cast<size_t>(static_cast<size_t>(1U) << bit_width) == + byte_width) + return bit_width; + } + FLATBUFFERS_ASSERT(false); // Must match one of the sizes above. + return BIT_WIDTH_64; + } + } + + BitWidth StoredWidth(BitWidth parent_bit_width_ = BIT_WIDTH_8) const { + if (IsInline(type_)) { + return (std::max)(min_bit_width_, parent_bit_width_); + } else { + return min_bit_width_; + } + } + }; + private: - void WriteAny(const Value &val, uint8_t byte_width) { - switch (val.type_) { - case FBT_NULL: - case FBT_INT: Write(val.i_, byte_width); break; - case FBT_BOOL: - case FBT_UINT: Write(val.u_, byte_width); break; - case FBT_FLOAT: WriteDouble(val.f_, byte_width); break; - default: WriteOffset(val.u_, byte_width); break; - } - } - - size_t CreateBlob(const void *data, size_t len, size_t trailing, Type type) { - auto bit_width = WidthU(len); - auto byte_width = Align(bit_width); - Write<uint64_t>(len, byte_width); - auto sloc = buf_.size(); - WriteBytes(data, len + trailing); - stack_.push_back(Value(static_cast<uint64_t>(sloc), type, bit_width)); - return sloc; - } - - template<typename T> - size_t ScalarVector(const T *elems, size_t len, bool fixed) { - auto vector_type = GetScalarType<T>(); - auto byte_width = sizeof(T); - auto bit_width = WidthB(byte_width); - // If you get this assert, you're trying to write a vector with a size - // field that is bigger than the scalars you're trying to write (e.g. a - // byte vector > 255 elements). For such types, write a "blob" instead. - // TODO: instead of asserting, could write vector with larger elements - // instead, though that would be wasteful. - FLATBUFFERS_ASSERT(WidthU(len) <= bit_width); + void WriteAny(const Value &val, uint8_t byte_width) { + switch (val.type_) { + case FBT_NULL: + case FBT_INT: Write(val.i_, byte_width); break; + case FBT_BOOL: + case FBT_UINT: Write(val.u_, byte_width); break; + case FBT_FLOAT: WriteDouble(val.f_, byte_width); break; + default: WriteOffset(val.u_, byte_width); break; + } + } + + size_t CreateBlob(const void *data, size_t len, size_t trailing, Type type) { + auto bit_width = WidthU(len); + auto byte_width = Align(bit_width); + Write<uint64_t>(len, byte_width); + auto sloc = buf_.size(); + WriteBytes(data, len + trailing); + stack_.push_back(Value(static_cast<uint64_t>(sloc), type, bit_width)); + return sloc; + } + + template<typename T> + size_t ScalarVector(const T *elems, size_t len, bool fixed) { + auto vector_type = GetScalarType<T>(); + auto byte_width = sizeof(T); + auto bit_width = WidthB(byte_width); + // If you get this assert, you're trying to write a vector with a size + // field that is bigger than the scalars you're trying to write (e.g. a + // byte vector > 255 elements). For such types, write a "blob" instead. + // TODO: instead of asserting, could write vector with larger elements + // instead, though that would be wasteful. + FLATBUFFERS_ASSERT(WidthU(len) <= bit_width); Align(bit_width); - if (!fixed) Write<uint64_t>(len, byte_width); - auto vloc = buf_.size(); - for (size_t i = 0; i < len; i++) Write(elems[i], byte_width); - stack_.push_back(Value(static_cast<uint64_t>(vloc), - ToTypedVector(vector_type, fixed ? len : 0), - bit_width)); - return vloc; - } - - Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed, - bool fixed, const Value *keys = nullptr) { + if (!fixed) Write<uint64_t>(len, byte_width); + auto vloc = buf_.size(); + for (size_t i = 0; i < len; i++) Write(elems[i], byte_width); + stack_.push_back(Value(static_cast<uint64_t>(vloc), + ToTypedVector(vector_type, fixed ? len : 0), + bit_width)); + return vloc; + } + + Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed, + bool fixed, const Value *keys = nullptr) { FLATBUFFERS_ASSERT( !fixed || typed); // typed=false, fixed=true combination is not supported. - // Figure out smallest bit width we can store this vector with. - auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len)); - auto prefix_elems = 1; - if (keys) { - // If this vector is part of a map, we will pre-fix an offset to the keys - // to this vector. - bit_width = (std::max)(bit_width, keys->ElemWidth(buf_.size(), 0)); - prefix_elems += 2; - } - Type vector_type = FBT_KEY; - // Check bit widths and types for all elements. - for (size_t i = start; i < stack_.size(); i += step) { + // Figure out smallest bit width we can store this vector with. + auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len)); + auto prefix_elems = 1; + if (keys) { + // If this vector is part of a map, we will pre-fix an offset to the keys + // to this vector. + bit_width = (std::max)(bit_width, keys->ElemWidth(buf_.size(), 0)); + prefix_elems += 2; + } + Type vector_type = FBT_KEY; + // Check bit widths and types for all elements. + for (size_t i = start; i < stack_.size(); i += step) { auto elem_width = stack_[i].ElemWidth(buf_.size(), i - start + prefix_elems); - bit_width = (std::max)(bit_width, elem_width); - if (typed) { - if (i == start) { - vector_type = stack_[i].type_; - } else { - // If you get this assert, you are writing a typed vector with - // elements that are not all the same type. - FLATBUFFERS_ASSERT(vector_type == stack_[i].type_); - } - } - } - // If you get this assert, your fixed types are not one of: - // Int / UInt / Float / Key. - FLATBUFFERS_ASSERT(!fixed || IsTypedVectorElementType(vector_type)); - auto byte_width = Align(bit_width); - // Write vector. First the keys width/offset if available, and size. - if (keys) { - WriteOffset(keys->u_, byte_width); - Write<uint64_t>(1ULL << keys->min_bit_width_, byte_width); - } - if (!fixed) Write<uint64_t>(vec_len, byte_width); - // Then the actual data. - auto vloc = buf_.size(); - for (size_t i = start; i < stack_.size(); i += step) { - WriteAny(stack_[i], byte_width); - } - // Then the types. - if (!typed) { - for (size_t i = start; i < stack_.size(); i += step) { - buf_.push_back(stack_[i].StoredPackedType(bit_width)); - } - } - return Value(static_cast<uint64_t>(vloc), - keys ? FBT_MAP - : (typed ? ToTypedVector(vector_type, fixed ? vec_len : 0) - : FBT_VECTOR), - bit_width); - } - - // You shouldn't really be copying instances of this class. - Builder(const Builder &); - Builder &operator=(const Builder &); - - std::vector<uint8_t> buf_; - std::vector<Value> stack_; - - bool finished_; + bit_width = (std::max)(bit_width, elem_width); + if (typed) { + if (i == start) { + vector_type = stack_[i].type_; + } else { + // If you get this assert, you are writing a typed vector with + // elements that are not all the same type. + FLATBUFFERS_ASSERT(vector_type == stack_[i].type_); + } + } + } + // If you get this assert, your fixed types are not one of: + // Int / UInt / Float / Key. + FLATBUFFERS_ASSERT(!fixed || IsTypedVectorElementType(vector_type)); + auto byte_width = Align(bit_width); + // Write vector. First the keys width/offset if available, and size. + if (keys) { + WriteOffset(keys->u_, byte_width); + Write<uint64_t>(1ULL << keys->min_bit_width_, byte_width); + } + if (!fixed) Write<uint64_t>(vec_len, byte_width); + // Then the actual data. + auto vloc = buf_.size(); + for (size_t i = start; i < stack_.size(); i += step) { + WriteAny(stack_[i], byte_width); + } + // Then the types. + if (!typed) { + for (size_t i = start; i < stack_.size(); i += step) { + buf_.push_back(stack_[i].StoredPackedType(bit_width)); + } + } + return Value(static_cast<uint64_t>(vloc), + keys ? FBT_MAP + : (typed ? ToTypedVector(vector_type, fixed ? vec_len : 0) + : FBT_VECTOR), + bit_width); + } + + // You shouldn't really be copying instances of this class. + Builder(const Builder &); + Builder &operator=(const Builder &); + + std::vector<uint8_t> buf_; + std::vector<Value> stack_; + + bool finished_; bool has_duplicate_keys_; - - BuilderFlag flags_; - - BitWidth force_min_bit_width_; - - struct KeyOffsetCompare { - explicit KeyOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {} - bool operator()(size_t a, size_t b) const { - auto stra = - reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) + a); - auto strb = - reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) + b); - return strcmp(stra, strb) < 0; - } - const std::vector<uint8_t> *buf_; - }; - - typedef std::pair<size_t, size_t> StringOffset; - struct StringOffsetCompare { + + BuilderFlag flags_; + + BitWidth force_min_bit_width_; + + struct KeyOffsetCompare { + explicit KeyOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {} + bool operator()(size_t a, size_t b) const { + auto stra = + reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) + a); + auto strb = + reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) + b); + return strcmp(stra, strb) < 0; + } + const std::vector<uint8_t> *buf_; + }; + + typedef std::pair<size_t, size_t> StringOffset; + struct StringOffsetCompare { explicit StringOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {} - bool operator()(const StringOffset &a, const StringOffset &b) const { - auto stra = reinterpret_cast<const char *>( - flatbuffers::vector_data(*buf_) + a.first); - auto strb = reinterpret_cast<const char *>( - flatbuffers::vector_data(*buf_) + b.first); - return strncmp(stra, strb, (std::min)(a.second, b.second) + 1) < 0; - } - const std::vector<uint8_t> *buf_; - }; - - typedef std::set<size_t, KeyOffsetCompare> KeyOffsetMap; - typedef std::set<StringOffset, StringOffsetCompare> StringOffsetMap; - - KeyOffsetMap key_pool; - StringOffsetMap string_pool; -}; - -} // namespace flexbuffers - + bool operator()(const StringOffset &a, const StringOffset &b) const { + auto stra = reinterpret_cast<const char *>( + flatbuffers::vector_data(*buf_) + a.first); + auto strb = reinterpret_cast<const char *>( + flatbuffers::vector_data(*buf_) + b.first); + return strncmp(stra, strb, (std::min)(a.second, b.second) + 1) < 0; + } + const std::vector<uint8_t> *buf_; + }; + + typedef std::set<size_t, KeyOffsetCompare> KeyOffsetMap; + typedef std::set<StringOffset, StringOffsetCompare> StringOffsetMap; + + KeyOffsetMap key_pool; + StringOffsetMap string_pool; +}; + +} // namespace flexbuffers + #if defined(_MSC_VER) # pragma warning(pop) #endif - -#endif // FLATBUFFERS_FLEXBUFFERS_H_ + +#endif // FLATBUFFERS_FLEXBUFFERS_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/grpc.h b/contrib/libs/flatbuffers/include/flatbuffers/grpc.h index b6b38d0642..da7830e7dc 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/grpc.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/grpc.h @@ -1,179 +1,179 @@ -/* - * 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_GRPC_H_ -#define FLATBUFFERS_GRPC_H_ - -// Helper functionality to glue FlatBuffers and GRPC. - +/* + * 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_GRPC_H_ +#define FLATBUFFERS_GRPC_H_ + +// Helper functionality to glue FlatBuffers and GRPC. + #include "flatbuffers.h" -#include "grpc/byte_buffer_reader.h" +#include "grpc/byte_buffer_reader.h" #include "grpcpp/support/byte_buffer.h" - -namespace flatbuffers { -namespace grpc { - -// Message is a typed wrapper around a buffer that manages the underlying -// `grpc_slice` and also provides flatbuffers-specific helpers such as `Verify` -// and `GetRoot`. Since it is backed by a `grpc_slice`, the underlying buffer -// is refcounted and ownership is be managed automatically. -template<class T> class Message { - public: - Message() : slice_(grpc_empty_slice()) {} - - Message(grpc_slice slice, bool add_ref) - : slice_(add_ref ? grpc_slice_ref(slice) : slice) {} - - Message &operator=(const Message &other) = delete; - - Message(Message &&other) : slice_(other.slice_) { - other.slice_ = grpc_empty_slice(); - } - - Message(const Message &other) = delete; - - Message &operator=(Message &&other) { - grpc_slice_unref(slice_); - slice_ = other.slice_; - other.slice_ = grpc_empty_slice(); - return *this; - } - - ~Message() { grpc_slice_unref(slice_); } - - const uint8_t *mutable_data() const { return GRPC_SLICE_START_PTR(slice_); } - - const uint8_t *data() const { return GRPC_SLICE_START_PTR(slice_); } - - size_t size() const { return GRPC_SLICE_LENGTH(slice_); } - - bool Verify() const { - Verifier verifier(data(), size()); - return verifier.VerifyBuffer<T>(nullptr); - } - - T *GetMutableRoot() { return flatbuffers::GetMutableRoot<T>(mutable_data()); } - - const T *GetRoot() const { return flatbuffers::GetRoot<T>(data()); } - - // This is only intended for serializer use, or if you know what you're doing - const grpc_slice &BorrowSlice() const { return slice_; } - - private: - grpc_slice slice_; -}; - -class MessageBuilder; - -// SliceAllocator is a gRPC-specific allocator that uses the `grpc_slice` -// refcounted slices to manage memory ownership. This makes it easy and -// efficient to transfer buffers to gRPC. -class SliceAllocator : public Allocator { - public: - SliceAllocator() : slice_(grpc_empty_slice()) {} - - SliceAllocator(const SliceAllocator &other) = delete; - SliceAllocator &operator=(const SliceAllocator &other) = delete; - + +namespace flatbuffers { +namespace grpc { + +// Message is a typed wrapper around a buffer that manages the underlying +// `grpc_slice` and also provides flatbuffers-specific helpers such as `Verify` +// and `GetRoot`. Since it is backed by a `grpc_slice`, the underlying buffer +// is refcounted and ownership is be managed automatically. +template<class T> class Message { + public: + Message() : slice_(grpc_empty_slice()) {} + + Message(grpc_slice slice, bool add_ref) + : slice_(add_ref ? grpc_slice_ref(slice) : slice) {} + + Message &operator=(const Message &other) = delete; + + Message(Message &&other) : slice_(other.slice_) { + other.slice_ = grpc_empty_slice(); + } + + Message(const Message &other) = delete; + + Message &operator=(Message &&other) { + grpc_slice_unref(slice_); + slice_ = other.slice_; + other.slice_ = grpc_empty_slice(); + return *this; + } + + ~Message() { grpc_slice_unref(slice_); } + + const uint8_t *mutable_data() const { return GRPC_SLICE_START_PTR(slice_); } + + const uint8_t *data() const { return GRPC_SLICE_START_PTR(slice_); } + + size_t size() const { return GRPC_SLICE_LENGTH(slice_); } + + bool Verify() const { + Verifier verifier(data(), size()); + return verifier.VerifyBuffer<T>(nullptr); + } + + T *GetMutableRoot() { return flatbuffers::GetMutableRoot<T>(mutable_data()); } + + const T *GetRoot() const { return flatbuffers::GetRoot<T>(data()); } + + // This is only intended for serializer use, or if you know what you're doing + const grpc_slice &BorrowSlice() const { return slice_; } + + private: + grpc_slice slice_; +}; + +class MessageBuilder; + +// SliceAllocator is a gRPC-specific allocator that uses the `grpc_slice` +// refcounted slices to manage memory ownership. This makes it easy and +// efficient to transfer buffers to gRPC. +class SliceAllocator : public Allocator { + public: + SliceAllocator() : slice_(grpc_empty_slice()) {} + + SliceAllocator(const SliceAllocator &other) = delete; + SliceAllocator &operator=(const SliceAllocator &other) = delete; + SliceAllocator(SliceAllocator &&other) : slice_(grpc_empty_slice()) { - // default-construct and swap idiom - swap(other); - } - - SliceAllocator &operator=(SliceAllocator &&other) { - // move-construct and swap idiom - SliceAllocator temp(std::move(other)); - swap(temp); - return *this; - } - - void swap(SliceAllocator &other) { - using std::swap; - swap(slice_, other.slice_); - } - - virtual ~SliceAllocator() { grpc_slice_unref(slice_); } - - virtual uint8_t *allocate(size_t size) override { - FLATBUFFERS_ASSERT(GRPC_SLICE_IS_EMPTY(slice_)); - slice_ = grpc_slice_malloc(size); - return GRPC_SLICE_START_PTR(slice_); - } - - virtual void deallocate(uint8_t *p, size_t size) override { - FLATBUFFERS_ASSERT(p == GRPC_SLICE_START_PTR(slice_)); - FLATBUFFERS_ASSERT(size == GRPC_SLICE_LENGTH(slice_)); - grpc_slice_unref(slice_); - slice_ = grpc_empty_slice(); - } - - 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) override { - FLATBUFFERS_ASSERT(old_p == GRPC_SLICE_START_PTR(slice_)); - FLATBUFFERS_ASSERT(old_size == GRPC_SLICE_LENGTH(slice_)); - FLATBUFFERS_ASSERT(new_size > old_size); - grpc_slice old_slice = slice_; - grpc_slice new_slice = grpc_slice_malloc(new_size); - uint8_t *new_p = GRPC_SLICE_START_PTR(new_slice); - memcpy_downward(old_p, old_size, new_p, new_size, in_use_back, - in_use_front); - slice_ = new_slice; - grpc_slice_unref(old_slice); - return new_p; - } - - private: - grpc_slice &get_slice(uint8_t *p, size_t size) { - FLATBUFFERS_ASSERT(p == GRPC_SLICE_START_PTR(slice_)); - FLATBUFFERS_ASSERT(size == GRPC_SLICE_LENGTH(slice_)); - return slice_; - } - - grpc_slice slice_; - - friend class MessageBuilder; -}; - -// SliceAllocatorMember is a hack to ensure that the MessageBuilder's -// slice_allocator_ member is constructed before the FlatBufferBuilder, since -// the allocator is used in the FlatBufferBuilder ctor. -namespace detail { -struct SliceAllocatorMember { - SliceAllocator slice_allocator_; -}; -} // namespace detail - -// MessageBuilder is a gRPC-specific FlatBufferBuilder that uses SliceAllocator -// to allocate gRPC buffers. -class MessageBuilder : private detail::SliceAllocatorMember, - public FlatBufferBuilder { - public: - explicit MessageBuilder(uoffset_t initial_size = 1024) - : FlatBufferBuilder(initial_size, &slice_allocator_, false) {} - - MessageBuilder(const MessageBuilder &other) = delete; - MessageBuilder &operator=(const MessageBuilder &other) = delete; - - MessageBuilder(MessageBuilder &&other) + // default-construct and swap idiom + swap(other); + } + + SliceAllocator &operator=(SliceAllocator &&other) { + // move-construct and swap idiom + SliceAllocator temp(std::move(other)); + swap(temp); + return *this; + } + + void swap(SliceAllocator &other) { + using std::swap; + swap(slice_, other.slice_); + } + + virtual ~SliceAllocator() { grpc_slice_unref(slice_); } + + virtual uint8_t *allocate(size_t size) override { + FLATBUFFERS_ASSERT(GRPC_SLICE_IS_EMPTY(slice_)); + slice_ = grpc_slice_malloc(size); + return GRPC_SLICE_START_PTR(slice_); + } + + virtual void deallocate(uint8_t *p, size_t size) override { + FLATBUFFERS_ASSERT(p == GRPC_SLICE_START_PTR(slice_)); + FLATBUFFERS_ASSERT(size == GRPC_SLICE_LENGTH(slice_)); + grpc_slice_unref(slice_); + slice_ = grpc_empty_slice(); + } + + 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) override { + FLATBUFFERS_ASSERT(old_p == GRPC_SLICE_START_PTR(slice_)); + FLATBUFFERS_ASSERT(old_size == GRPC_SLICE_LENGTH(slice_)); + FLATBUFFERS_ASSERT(new_size > old_size); + grpc_slice old_slice = slice_; + grpc_slice new_slice = grpc_slice_malloc(new_size); + uint8_t *new_p = GRPC_SLICE_START_PTR(new_slice); + memcpy_downward(old_p, old_size, new_p, new_size, in_use_back, + in_use_front); + slice_ = new_slice; + grpc_slice_unref(old_slice); + return new_p; + } + + private: + grpc_slice &get_slice(uint8_t *p, size_t size) { + FLATBUFFERS_ASSERT(p == GRPC_SLICE_START_PTR(slice_)); + FLATBUFFERS_ASSERT(size == GRPC_SLICE_LENGTH(slice_)); + return slice_; + } + + grpc_slice slice_; + + friend class MessageBuilder; +}; + +// SliceAllocatorMember is a hack to ensure that the MessageBuilder's +// slice_allocator_ member is constructed before the FlatBufferBuilder, since +// the allocator is used in the FlatBufferBuilder ctor. +namespace detail { +struct SliceAllocatorMember { + SliceAllocator slice_allocator_; +}; +} // namespace detail + +// MessageBuilder is a gRPC-specific FlatBufferBuilder that uses SliceAllocator +// to allocate gRPC buffers. +class MessageBuilder : private detail::SliceAllocatorMember, + public FlatBufferBuilder { + public: + explicit MessageBuilder(uoffset_t initial_size = 1024) + : FlatBufferBuilder(initial_size, &slice_allocator_, false) {} + + MessageBuilder(const MessageBuilder &other) = delete; + MessageBuilder &operator=(const MessageBuilder &other) = delete; + + MessageBuilder(MessageBuilder &&other) : FlatBufferBuilder(1024, &slice_allocator_, false) { - // Default construct and swap idiom. - Swap(other); - } - + // Default construct and swap idiom. + Swap(other); + } + /// Create a MessageBuilder from a FlatBufferBuilder. explicit MessageBuilder(FlatBufferBuilder &&src, void (*dealloc)(void *, @@ -200,132 +200,132 @@ class MessageBuilder : private detail::SliceAllocatorMember, return *this; } - MessageBuilder &operator=(MessageBuilder &&other) { - // Move construct a temporary and swap - MessageBuilder temp(std::move(other)); - Swap(temp); - return *this; - } - - void Swap(MessageBuilder &other) { - slice_allocator_.swap(other.slice_allocator_); - FlatBufferBuilder::Swap(other); + MessageBuilder &operator=(MessageBuilder &&other) { + // Move construct a temporary and swap + MessageBuilder temp(std::move(other)); + Swap(temp); + return *this; + } + + void Swap(MessageBuilder &other) { + slice_allocator_.swap(other.slice_allocator_); + FlatBufferBuilder::Swap(other); // After swapping the FlatBufferBuilder, we swap back the allocator, which // restores the original allocator back in place. This is necessary because // MessageBuilder's allocator is its own member (SliceAllocatorMember). The // allocator passed to FlatBufferBuilder::vector_downward must point to this // member. - buf_.swap_allocator(other.buf_); - } - - // Releases the ownership of the buffer pointer. - // Returns the size, offset, and the original grpc_slice that - // allocated the buffer. Also see grpc_slice_unref(). - uint8_t *ReleaseRaw(size_t &size, size_t &offset, grpc_slice &slice) { - uint8_t *buf = FlatBufferBuilder::ReleaseRaw(size, offset); - slice = slice_allocator_.slice_; - slice_allocator_.slice_ = grpc_empty_slice(); - return buf; - } - - ~MessageBuilder() {} - - // GetMessage extracts the subslice of the buffer corresponding to the - // flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer - // ownership. - template<class T> Message<T> GetMessage() { + buf_.swap_allocator(other.buf_); + } + + // Releases the ownership of the buffer pointer. + // Returns the size, offset, and the original grpc_slice that + // allocated the buffer. Also see grpc_slice_unref(). + uint8_t *ReleaseRaw(size_t &size, size_t &offset, grpc_slice &slice) { + uint8_t *buf = FlatBufferBuilder::ReleaseRaw(size, offset); + slice = slice_allocator_.slice_; + slice_allocator_.slice_ = grpc_empty_slice(); + return buf; + } + + ~MessageBuilder() {} + + // GetMessage extracts the subslice of the buffer corresponding to the + // flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer + // ownership. + template<class T> Message<T> GetMessage() { auto buf_data = buf_.scratch_data(); // pointer to memory auto buf_size = buf_.capacity(); // size of memory auto msg_data = buf_.data(); // pointer to msg auto msg_size = buf_.size(); // size of msg - // Do some sanity checks on data/size - FLATBUFFERS_ASSERT(msg_data); - FLATBUFFERS_ASSERT(msg_size); - FLATBUFFERS_ASSERT(msg_data >= buf_data); - FLATBUFFERS_ASSERT(msg_data + msg_size <= buf_data + buf_size); - // Calculate offsets from the buffer start - auto begin = msg_data - buf_data; - auto end = begin + msg_size; - // Get the slice we are working with (no refcount change) - grpc_slice slice = slice_allocator_.get_slice(buf_data, buf_size); - // Extract a subslice of the existing slice (increment refcount) - grpc_slice subslice = grpc_slice_sub(slice, begin, end); - // Wrap the subslice in a `Message<T>`, but don't increment refcount - Message<T> msg(subslice, false); - return msg; - } - - template<class T> Message<T> ReleaseMessage() { - Message<T> msg = GetMessage<T>(); - Reset(); - return msg; - } - - private: - // SliceAllocator slice_allocator_; // part of SliceAllocatorMember -}; - -} // namespace grpc -} // namespace flatbuffers - -namespace grpc { - -template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> { - public: - static grpc::Status Serialize(const flatbuffers::grpc::Message<T> &msg, - grpc_byte_buffer **buffer, bool *own_buffer) { - // We are passed in a `Message<T>`, which is a wrapper around a - // `grpc_slice`. We extract it here using `BorrowSlice()`. The const cast + // Do some sanity checks on data/size + FLATBUFFERS_ASSERT(msg_data); + FLATBUFFERS_ASSERT(msg_size); + FLATBUFFERS_ASSERT(msg_data >= buf_data); + FLATBUFFERS_ASSERT(msg_data + msg_size <= buf_data + buf_size); + // Calculate offsets from the buffer start + auto begin = msg_data - buf_data; + auto end = begin + msg_size; + // Get the slice we are working with (no refcount change) + grpc_slice slice = slice_allocator_.get_slice(buf_data, buf_size); + // Extract a subslice of the existing slice (increment refcount) + grpc_slice subslice = grpc_slice_sub(slice, begin, end); + // Wrap the subslice in a `Message<T>`, but don't increment refcount + Message<T> msg(subslice, false); + return msg; + } + + template<class T> Message<T> ReleaseMessage() { + Message<T> msg = GetMessage<T>(); + Reset(); + return msg; + } + + private: + // SliceAllocator slice_allocator_; // part of SliceAllocatorMember +}; + +} // namespace grpc +} // namespace flatbuffers + +namespace grpc { + +template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> { + public: + static grpc::Status Serialize(const flatbuffers::grpc::Message<T> &msg, + grpc_byte_buffer **buffer, bool *own_buffer) { + // We are passed in a `Message<T>`, which is a wrapper around a + // `grpc_slice`. We extract it here using `BorrowSlice()`. The const cast // is necessary because the `grpc_raw_byte_buffer_create` func expects - // non-const slices in order to increment their refcounts. - grpc_slice *slice = const_cast<grpc_slice *>(&msg.BorrowSlice()); - // Now use `grpc_raw_byte_buffer_create` to package the single slice into a - // `grpc_byte_buffer`, incrementing the refcount in the process. - *buffer = grpc_raw_byte_buffer_create(slice, 1); - *own_buffer = true; - return grpc::Status::OK; - } - - // Deserialize by pulling the + // non-const slices in order to increment their refcounts. + grpc_slice *slice = const_cast<grpc_slice *>(&msg.BorrowSlice()); + // Now use `grpc_raw_byte_buffer_create` to package the single slice into a + // `grpc_byte_buffer`, incrementing the refcount in the process. + *buffer = grpc_raw_byte_buffer_create(slice, 1); + *own_buffer = true; + return grpc::Status::OK; + } + + // Deserialize by pulling the static grpc::Status Deserialize(ByteBuffer *buf, - flatbuffers::grpc::Message<T> *msg) { + flatbuffers::grpc::Message<T> *msg) { grpc_byte_buffer *buffer = *reinterpret_cast<grpc_byte_buffer **>(buf); - if (!buffer) { - return ::grpc::Status(::grpc::StatusCode::INTERNAL, "No payload"); - } - // Check if this is a single uncompressed slice. - if ((buffer->type == GRPC_BB_RAW) && - (buffer->data.raw.compression == GRPC_COMPRESS_NONE) && - (buffer->data.raw.slice_buffer.count == 1)) { - // If it is, then we can reference the `grpc_slice` directly. - grpc_slice slice = buffer->data.raw.slice_buffer.slices[0]; - // We wrap a `Message<T>` around the slice, incrementing the refcount. - *msg = flatbuffers::grpc::Message<T>(slice, true); - } else { - // Otherwise, we need to use `grpc_byte_buffer_reader_readall` to read - // `buffer` into a single contiguous `grpc_slice`. The gRPC reader gives - // us back a new slice with the refcount already incremented. - grpc_byte_buffer_reader reader; - grpc_byte_buffer_reader_init(&reader, buffer); - grpc_slice slice = grpc_byte_buffer_reader_readall(&reader); - grpc_byte_buffer_reader_destroy(&reader); + if (!buffer) { + return ::grpc::Status(::grpc::StatusCode::INTERNAL, "No payload"); + } + // Check if this is a single uncompressed slice. + if ((buffer->type == GRPC_BB_RAW) && + (buffer->data.raw.compression == GRPC_COMPRESS_NONE) && + (buffer->data.raw.slice_buffer.count == 1)) { + // If it is, then we can reference the `grpc_slice` directly. + grpc_slice slice = buffer->data.raw.slice_buffer.slices[0]; + // We wrap a `Message<T>` around the slice, incrementing the refcount. + *msg = flatbuffers::grpc::Message<T>(slice, true); + } else { + // Otherwise, we need to use `grpc_byte_buffer_reader_readall` to read + // `buffer` into a single contiguous `grpc_slice`. The gRPC reader gives + // us back a new slice with the refcount already incremented. + grpc_byte_buffer_reader reader; + grpc_byte_buffer_reader_init(&reader, buffer); + grpc_slice slice = grpc_byte_buffer_reader_readall(&reader); + grpc_byte_buffer_reader_destroy(&reader); // We wrap a `Message<T>` around the slice, but don't increment refcount - *msg = flatbuffers::grpc::Message<T>(slice, false); - } - grpc_byte_buffer_destroy(buffer); -#if FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION - return ::grpc::Status::OK; -#else - if (msg->Verify()) { - return ::grpc::Status::OK; - } else { - return ::grpc::Status(::grpc::StatusCode::INTERNAL, - "Message verification failed"); - } -#endif - } -}; - -} // namespace grpc - -#endif // FLATBUFFERS_GRPC_H_ + *msg = flatbuffers::grpc::Message<T>(slice, false); + } + grpc_byte_buffer_destroy(buffer); +#if FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION + return ::grpc::Status::OK; +#else + if (msg->Verify()) { + return ::grpc::Status::OK; + } else { + return ::grpc::Status(::grpc::StatusCode::INTERNAL, + "Message verification failed"); + } +#endif + } +}; + +} // namespace grpc + +#endif // FLATBUFFERS_GRPC_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/hash.h b/contrib/libs/flatbuffers/include/flatbuffers/hash.h index d25caa423a..52cc628cdf 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/hash.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/hash.h @@ -24,17 +24,17 @@ namespace flatbuffers { -template<typename T> struct FnvTraits { +template<typename T> struct FnvTraits { static const T kFnvPrime; static const T kOffsetBasis; }; -template<> struct FnvTraits<uint32_t> { +template<> struct FnvTraits<uint32_t> { static const uint32_t kFnvPrime = 0x01000193; static const uint32_t kOffsetBasis = 0x811C9DC5; }; -template<> struct FnvTraits<uint64_t> { +template<> struct FnvTraits<uint64_t> { static const uint64_t kFnvPrime = 0x00000100000001b3ULL; static const uint64_t kOffsetBasis = 0xcbf29ce484222645ULL; }; @@ -58,48 +58,48 @@ template<typename T> T HashFnv1a(const char *input) { } template<> inline uint16_t HashFnv1<uint16_t>(const char *input) { - uint32_t hash = HashFnv1<uint32_t>(input); - return (hash >> 16) ^ (hash & 0xffff); -} - + uint32_t hash = HashFnv1<uint32_t>(input); + return (hash >> 16) ^ (hash & 0xffff); +} + template<> inline uint16_t HashFnv1a<uint16_t>(const char *input) { - uint32_t hash = HashFnv1a<uint32_t>(input); - return (hash >> 16) ^ (hash & 0xffff); -} - + uint32_t hash = HashFnv1a<uint32_t>(input); + return (hash >> 16) ^ (hash & 0xffff); +} + template<typename T> struct NamedHashFunction { const char *name; - typedef T (*HashFunction)(const char *); + typedef T (*HashFunction)(const char *); HashFunction function; }; -const NamedHashFunction<uint16_t> kHashFunctions16[] = { +const NamedHashFunction<uint16_t> kHashFunctions16[] = { { "fnv1_16", HashFnv1<uint16_t> }, - { "fnv1a_16", HashFnv1a<uint16_t> }, -}; - + { "fnv1a_16", HashFnv1a<uint16_t> }, +}; + const NamedHashFunction<uint32_t> kHashFunctions32[] = { - { "fnv1_32", HashFnv1<uint32_t> }, + { "fnv1_32", HashFnv1<uint32_t> }, { "fnv1a_32", HashFnv1a<uint32_t> }, }; const NamedHashFunction<uint64_t> kHashFunctions64[] = { - { "fnv1_64", HashFnv1<uint64_t> }, + { "fnv1_64", HashFnv1<uint64_t> }, { "fnv1a_64", HashFnv1a<uint64_t> }, }; -inline NamedHashFunction<uint16_t>::HashFunction FindHashFunction16( - const char *name) { - std::size_t size = sizeof(kHashFunctions16) / sizeof(kHashFunctions16[0]); - for (std::size_t i = 0; i < size; ++i) { - if (std::strcmp(name, kHashFunctions16[i].name) == 0) { - return kHashFunctions16[i].function; - } - } - return nullptr; -} - +inline NamedHashFunction<uint16_t>::HashFunction FindHashFunction16( + const char *name) { + std::size_t size = sizeof(kHashFunctions16) / sizeof(kHashFunctions16[0]); + for (std::size_t i = 0; i < size; ++i) { + if (std::strcmp(name, kHashFunctions16[i].name) == 0) { + return kHashFunctions16[i].function; + } + } + return nullptr; +} + inline NamedHashFunction<uint32_t>::HashFunction FindHashFunction32( const char *name) { std::size_t size = sizeof(kHashFunctions32) / sizeof(kHashFunctions32[0]); diff --git a/contrib/libs/flatbuffers/include/flatbuffers/idl.h b/contrib/libs/flatbuffers/include/flatbuffers/idl.h index 651761d922..a82ff8a694 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/idl.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/idl.h @@ -18,7 +18,7 @@ #define FLATBUFFERS_IDL_H_ #include <map> -#include <memory> +#include <memory> #include <stack> #include "base.h" @@ -27,10 +27,10 @@ #include "hash.h" #include "reflection.h" -#if !defined(FLATBUFFERS_CPP98_STL) -# include <functional> -#endif // !defined(FLATBUFFERS_CPP98_STL) - +#if !defined(FLATBUFFERS_CPP98_STL) +# include <functional> +#endif // !defined(FLATBUFFERS_CPP98_STL) + // This file defines the data types representing a parsed IDL (Interface // Definition Language) / schema file. @@ -45,7 +45,7 @@ namespace flatbuffers { // The order of these matters for Is*() functions below. // Additionally, Parser::ParseType assumes bool..string is a contiguous range // of type tokens. -// clang-format off +// clang-format off #define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \ TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) \ TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) /* begin scalar/int */ \ @@ -75,14 +75,14 @@ namespace flatbuffers { // - Go type. // - C# / .Net type. // - Python type. -// - Rust type. +// - Rust type. // - Kotlin type. // using these macros, we can now write code dealing with types just once, e.g. /* switch (type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ RTYPE, KTYPE) \ case BASE_TYPE_ ## ENUM: \ // do something specific to CTYPE here @@ -133,11 +133,11 @@ inline bool IsInteger(BaseType t) { return t >= BASE_TYPE_UTYPE && t <= BASE_TYPE_ULONG; } inline bool IsFloat (BaseType t) { return t == BASE_TYPE_FLOAT || t == BASE_TYPE_DOUBLE; } -inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG || - t == BASE_TYPE_ULONG; } -inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; } -inline bool IsOneByte(BaseType t) { return t >= BASE_TYPE_UTYPE && - t <= BASE_TYPE_UCHAR; } +inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG || + t == BASE_TYPE_ULONG; } +inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; } +inline bool IsOneByte(BaseType t) { return t >= BASE_TYPE_UTYPE && + t <= BASE_TYPE_UCHAR; } inline bool IsUnsigned(BaseType t) { return (t == BASE_TYPE_UTYPE) || (t == BASE_TYPE_UCHAR) || @@ -145,25 +145,25 @@ inline bool IsUnsigned(BaseType t) { (t == BASE_TYPE_ULONG); } -// clang-format on +// clang-format on extern const char *const kTypeNames[]; extern const char kTypeSizes[]; -inline size_t SizeOf(BaseType t) { return kTypeSizes[t]; } +inline size_t SizeOf(BaseType t) { return kTypeSizes[t]; } struct StructDef; struct EnumDef; -class Parser; +class Parser; // Represents any type in the IDL, which is a combination of the BaseType // and additional information for vectors/structs_. struct Type { - explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr, + explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr, EnumDef *_ed = nullptr, uint16_t _fixed_length = 0) - : base_type(_base_type), - element(BASE_TYPE_NONE), - struct_def(_sd), + : base_type(_base_type), + element(BASE_TYPE_NONE), + struct_def(_sd), enum_def(_ed), fixed_length(_fixed_length) {} @@ -190,9 +190,9 @@ struct Type { // Represents a parsed scalar value, it's type, and field offset. struct Value { - Value() - : constant("0"), - offset(static_cast<voffset_t>(~(static_cast<voffset_t>(0U)))) {} + Value() + : constant("0"), + offset(static_cast<voffset_t>(~(static_cast<voffset_t>(0U)))) {} Type type; std::string constant; voffset_t offset; @@ -203,11 +203,11 @@ struct Value { template<typename T> class SymbolTable { public: ~SymbolTable() { - for (auto it = vec.begin(); it != vec.end(); ++it) { delete *it; } + for (auto it = vec.begin(); it != vec.end(); ++it) { delete *it; } } bool Add(const std::string &name, T *e) { - vector_emplace_back(&vec, e); + vector_emplace_back(&vec, e); auto it = dict.find(name); if (it != dict.end()) return true; dict[name] = e; @@ -221,7 +221,7 @@ template<typename T> class SymbolTable { dict.erase(it); dict[newname] = obj; } else { - FLATBUFFERS_ASSERT(false); + FLATBUFFERS_ASSERT(false); } } @@ -230,14 +230,14 @@ template<typename T> class SymbolTable { return it == dict.end() ? nullptr : it->second; } - public: - std::map<std::string, T *> dict; // quick lookup - std::vector<T *> vec; // Used to iterate in order of insertion + public: + std::map<std::string, T *> dict; // quick lookup + std::vector<T *> vec; // Used to iterate in order of insertion }; // A name space, as set in the schema. struct Namespace { - Namespace() : from_table(0) {} + Namespace() : from_table(0) {} // Given a (potentially unqualified) name, return the "fully qualified" name // which has a full namespaced descriptor. @@ -245,9 +245,9 @@ struct Namespace { // the current namespace has. std::string GetFullyQualifiedName(const std::string &name, size_t max_components = 1000) const; - - std::vector<std::string> components; - size_t from_table; // Part of the namespace corresponds to a message/table. + + std::vector<std::string> components; + size_t from_table; // Part of the namespace corresponds to a message/table. }; inline bool operator<(const Namespace &a, const Namespace &b) { @@ -261,17 +261,17 @@ inline bool operator<(const Namespace &a, const Namespace &b) { // Base class for all definition types (fields, structs_, enums_). struct Definition { - Definition() - : generated(false), - defined_namespace(nullptr), - serialized_location(0), - index(-1), - refcount(1) {} - - flatbuffers::Offset< - flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> - SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const; - + Definition() + : generated(false), + defined_namespace(nullptr), + serialized_location(0), + index(-1), + refcount(1) {} + + flatbuffers::Offset< + flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> + SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const; + bool DeserializeAttributes(Parser &parser, const Vector<Offset<reflection::KeyValue>> *attrs); @@ -285,22 +285,22 @@ struct Definition { // For use with Serialize() uoffset_t serialized_location; int index; // Inside the vector it is stored. - int refcount; + int refcount; }; struct FieldDef : public Definition { - FieldDef() - : deprecated(false), - key(false), + FieldDef() + : deprecated(false), + key(false), shared(false), - native_inline(false), - flexbuffer(false), + native_inline(false), + flexbuffer(false), presence(kDefault), - nested_flatbuffer(NULL), - padding(0) {} + nested_flatbuffer(NULL), + padding(0) {} - Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id, - const Parser &parser) const; + Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id, + const Parser &parser) const; bool Deserialize(Parser &parser, const reflection::Field *field); @@ -318,14 +318,14 @@ struct FieldDef : public Definition { } Value value; - bool deprecated; // Field is allowed to be present in old data, but can't be. - // written in new data nor accessed in new code. - bool key; // Field functions as a key for creating sorted vectors. + bool deprecated; // Field is allowed to be present in old data, but can't be. + // written in new data nor accessed in new code. + bool key; // Field functions as a key for creating sorted vectors. bool shared; // Field will be using string pooling (i.e. CreateSharedString) // as default serialization behavior if field is a string. - bool native_inline; // Field will be defined inline (instead of as a pointer) - // for native tables if field is a struct. - bool flexbuffer; // This field contains FlexBuffer data. + bool native_inline; // Field will be defined inline (instead of as a pointer) + // for native tables if field is a struct. + bool flexbuffer; // This field contains FlexBuffer data. enum Presence { // Field must always be present. @@ -346,18 +346,18 @@ struct FieldDef : public Definition { } Presence presence; - StructDef *nested_flatbuffer; // This field contains nested FlatBuffer data. - size_t padding; // Bytes to always pad after this field. + StructDef *nested_flatbuffer; // This field contains nested FlatBuffer data. + size_t padding; // Bytes to always pad after this field. }; struct StructDef : public Definition { StructDef() - : fixed(false), - predecl(true), - sortbysize(true), - has_key(false), - minalign(1), - bytesize(0) {} + : fixed(false), + predecl(true), + sortbysize(true), + has_key(false), + minalign(1), + bytesize(0) {} void PadLastField(size_t min_align) { auto padding = PaddingBytes(bytesize, min_align); @@ -365,21 +365,21 @@ struct StructDef : public Definition { if (fields.vec.size()) fields.vec.back()->padding = padding; } - Offset<reflection::Object> Serialize(FlatBufferBuilder *builder, - const Parser &parser) const; + Offset<reflection::Object> Serialize(FlatBufferBuilder *builder, + const Parser &parser) const; bool Deserialize(Parser &parser, const reflection::Object *object); SymbolTable<FieldDef> fields; - + bool fixed; // If it's struct, not a table. bool predecl; // If it's used before it was defined. bool sortbysize; // Whether fields come in the declaration or size order. bool has_key; // It has a key field. size_t minalign; // What the whole object needs to be aligned to. size_t bytesize; // Size if fixed. - - flatbuffers::unique_ptr<std::string> original_location; + + flatbuffers::unique_ptr<std::string> original_location; }; struct EnumDef; @@ -516,30 +516,30 @@ inline bool operator!=(const EnumVal &lhs, const EnumVal &rhs) { return !(lhs == rhs); } -inline bool EqualByName(const Type &a, const Type &b) { - return a.base_type == b.base_type && a.element == b.element && - (a.struct_def == b.struct_def || - a.struct_def->name == b.struct_def->name) && - (a.enum_def == b.enum_def || a.enum_def->name == b.enum_def->name); -} - -struct RPCCall : public Definition { +inline bool EqualByName(const Type &a, const Type &b) { + return a.base_type == b.base_type && a.element == b.element && + (a.struct_def == b.struct_def || + a.struct_def->name == b.struct_def->name) && + (a.enum_def == b.enum_def || a.enum_def->name == b.enum_def->name); +} + +struct RPCCall : public Definition { Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; - + bool Deserialize(Parser &parser, const reflection::RPCCall *call); - StructDef *request, *response; -}; - -struct ServiceDef : public Definition { + StructDef *request, *response; +}; + +struct ServiceDef : public Definition { Offset<reflection::Service> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; bool Deserialize(Parser &parser, const reflection::Service *service); - - SymbolTable<RPCCall> calls; -}; - + + SymbolTable<RPCCall> calls; +}; + // Container of options that may apply to any of the source/text generators. struct IDLOptions { bool gen_jvmstatic; @@ -555,35 +555,35 @@ struct IDLOptions { bool mutable_buffer; bool one_file; bool proto_mode; - bool proto_oneof_union; + bool proto_oneof_union; bool generate_all; bool skip_unexpected_fields_in_json; - bool generate_name_strings; - bool generate_object_based_api; - bool gen_compare; - std::string cpp_object_api_pointer_type; - std::string cpp_object_api_string_type; + bool generate_name_strings; + bool generate_object_based_api; + bool gen_compare; + std::string cpp_object_api_pointer_type; + std::string cpp_object_api_string_type; bool cpp_object_api_string_flexible_constructor; bool cpp_direct_copy; - bool gen_nullable; + bool gen_nullable; bool java_checkerframework; bool gen_generated; - std::string object_prefix; - std::string object_suffix; - bool union_value_namespacing; - bool allow_non_utf8; - bool natural_utf8; - std::string include_prefix; - bool keep_include_path; - bool binary_schema_comments; - bool binary_schema_builtins; + std::string object_prefix; + std::string object_suffix; + bool union_value_namespacing; + bool allow_non_utf8; + bool natural_utf8; + std::string include_prefix; + bool keep_include_path; + bool binary_schema_comments; + bool binary_schema_builtins; bool binary_schema_gen_embed; - std::string go_import; - std::string go_namespace; - bool protobuf_ascii_alike; - bool size_prefixed; - std::string root_type; - bool force_defaults; + std::string go_import; + std::string go_namespace; + bool protobuf_ascii_alike; + bool size_prefixed; + std::string root_type; + bool force_defaults; bool java_primitive_has_method; bool cs_gen_json_serializer; std::vector<std::string> cpp_includes; @@ -595,44 +595,44 @@ struct IDLOptions { bool no_warnings; // Possible options for the more general generator below. - enum Language { - kJava = 1 << 0, - kCSharp = 1 << 1, - kGo = 1 << 2, - kCpp = 1 << 3, - kPython = 1 << 5, - kPhp = 1 << 6, - kJson = 1 << 7, - kBinary = 1 << 8, - kTs = 1 << 9, - kJsonSchema = 1 << 10, - kDart = 1 << 11, - kLua = 1 << 12, - kLobster = 1 << 13, - kRust = 1 << 14, + enum Language { + kJava = 1 << 0, + kCSharp = 1 << 1, + kGo = 1 << 2, + kCpp = 1 << 3, + kPython = 1 << 5, + kPhp = 1 << 6, + kJson = 1 << 7, + kBinary = 1 << 8, + kTs = 1 << 9, + kJsonSchema = 1 << 10, + kDart = 1 << 11, + kLua = 1 << 12, + kLobster = 1 << 13, + kRust = 1 << 14, kKotlin = 1 << 15, kSwift = 1 << 16, kCppYandexMapsIter = 1 << 17, - kMAX - }; + kMAX + }; Language lang; - enum MiniReflect { kNone, kTypes, kTypesAndNames }; - - MiniReflect mini_reflect; - + enum MiniReflect { kNone, kTypes, kTypesAndNames }; + + MiniReflect mini_reflect; + // If set, require all fields in a table to be explicitly numbered. bool require_explicit_ids; - // The corresponding language bit will be set if a language is included - // for code generation. - unsigned long lang_to_generate; - + // The corresponding language bit will be set if a language is included + // for code generation. + unsigned long lang_to_generate; + // If set (default behavior), empty string fields will be set to nullptr to // make the flatbuffer more compact. bool set_empty_strings_to_null; - + // If set (default behavior), empty vector fields will be set to nullptr to // make the flatbuffer more compact. bool set_empty_vectors_to_null; @@ -641,91 +641,91 @@ struct IDLOptions { : gen_jvmstatic(false), use_flexbuffers(false), strict_json(false), - output_default_scalars_in_json(false), - indent_step(2), - output_enum_identifiers(true), - prefixed_enums(true), - scoped_enums(false), - include_dependence_headers(true), - mutable_buffer(false), - one_file(false), - proto_mode(false), - proto_oneof_union(false), - generate_all(false), - skip_unexpected_fields_in_json(false), - generate_name_strings(false), - generate_object_based_api(false), - gen_compare(false), - cpp_object_api_pointer_type("std::unique_ptr"), + output_default_scalars_in_json(false), + indent_step(2), + output_enum_identifiers(true), + prefixed_enums(true), + scoped_enums(false), + include_dependence_headers(true), + mutable_buffer(false), + one_file(false), + proto_mode(false), + proto_oneof_union(false), + generate_all(false), + skip_unexpected_fields_in_json(false), + generate_name_strings(false), + generate_object_based_api(false), + gen_compare(false), + cpp_object_api_pointer_type("std::unique_ptr"), cpp_object_api_string_flexible_constructor(false), cpp_direct_copy(true), - gen_nullable(false), + gen_nullable(false), java_checkerframework(false), gen_generated(false), - object_suffix("T"), - union_value_namespacing(true), - allow_non_utf8(false), - natural_utf8(false), - keep_include_path(false), - binary_schema_comments(false), - binary_schema_builtins(false), + object_suffix("T"), + union_value_namespacing(true), + allow_non_utf8(false), + natural_utf8(false), + keep_include_path(false), + binary_schema_comments(false), + binary_schema_builtins(false), binary_schema_gen_embed(false), - protobuf_ascii_alike(false), - size_prefixed(false), - force_defaults(false), + protobuf_ascii_alike(false), + size_prefixed(false), + force_defaults(false), java_primitive_has_method(false), cs_gen_json_serializer(false), cpp_static_reflection(false), filename_suffix("_generated"), filename_extension(), no_warnings(false), - lang(IDLOptions::kJava), - mini_reflect(IDLOptions::kNone), + lang(IDLOptions::kJava), + mini_reflect(IDLOptions::kNone), require_explicit_ids(false), - lang_to_generate(0), + lang_to_generate(0), set_empty_strings_to_null(true), set_empty_vectors_to_null(true) {} }; -// This encapsulates where the parser is in the current source file. -struct ParserState { - ParserState() +// This encapsulates where the parser is in the current source file. +struct ParserState { + ParserState() : cursor_(nullptr), line_start_(nullptr), line_(0), token_(-1), attr_is_trivial_ascii_string_(true) {} - - protected: - void ResetState(const char *source) { - cursor_ = source; - line_ = 0; - MarkNewLine(); - } - - void MarkNewLine() { - line_start_ = cursor_; - line_ += 1; - } - - int64_t CursorPosition() const { - FLATBUFFERS_ASSERT(cursor_ && line_start_ && cursor_ >= line_start_); - return static_cast<int64_t>(cursor_ - line_start_); - } - - const char *cursor_; - const char *line_start_; - int line_; // the current line being parsed - int token_; - + + protected: + void ResetState(const char *source) { + cursor_ = source; + line_ = 0; + MarkNewLine(); + } + + void MarkNewLine() { + line_start_ = cursor_; + line_ += 1; + } + + int64_t CursorPosition() const { + FLATBUFFERS_ASSERT(cursor_ && line_start_ && cursor_ >= line_start_); + return static_cast<int64_t>(cursor_ - line_start_); + } + + const char *cursor_; + const char *line_start_; + int line_; // the current line being parsed + int token_; + // Flag: text in attribute_ is true ASCII string without escape // sequences. Only printable ASCII (without [\t\r\n]). // Used for number-in-string (and base64 string in future). bool attr_is_trivial_ascii_string_; - std::string attribute_; - std::vector<std::string> doc_comment_; -}; - + std::string attribute_; + std::vector<std::string> doc_comment_; +}; + // A way to make error propagation less error prone by requiring values to be // checked. // Once you create a value of this type you must either: @@ -736,7 +736,7 @@ struct ParserState { class CheckedError { public: explicit CheckedError(bool error) - : is_error_(error), has_been_checked_(false) {} + : is_error_(error), has_been_checked_(false) {} CheckedError &operator=(const CheckedError &other) { is_error_ = other.is_error_; @@ -749,12 +749,12 @@ class CheckedError { *this = other; // Use assignment operator. } - ~CheckedError() { FLATBUFFERS_ASSERT(has_been_checked_); } + ~CheckedError() { FLATBUFFERS_ASSERT(has_been_checked_); } - bool Check() { - has_been_checked_ = true; - return is_error_; - } + bool Check() { + has_been_checked_ = true; + return is_error_; + } private: bool is_error_; @@ -763,58 +763,58 @@ class CheckedError { // Additionally, in GCC we can get these errors statically, for additional // assurance: -// clang-format off +// clang-format off #ifdef __GNUC__ #define FLATBUFFERS_CHECKED_ERROR CheckedError \ __attribute__((warn_unused_result)) #else #define FLATBUFFERS_CHECKED_ERROR CheckedError #endif -// clang-format on +// clang-format on -class Parser : public ParserState { +class Parser : public ParserState { public: explicit Parser(const IDLOptions &options = IDLOptions()) - : current_namespace_(nullptr), - empty_namespace_(nullptr), + : current_namespace_(nullptr), + empty_namespace_(nullptr), flex_builder_(256, flexbuffers::BUILDER_FLAG_SHARE_ALL), - root_struct_def_(nullptr), - opts(options), - uses_flexbuffers_(false), + root_struct_def_(nullptr), + opts(options), + uses_flexbuffers_(false), advanced_features_(0), - source_(nullptr), + source_(nullptr), anonymous_counter_(0), parse_depth_counter_(0) { if (opts.force_defaults) { builder_.ForceDefaults(true); } - // Start out with the empty namespace being current. - empty_namespace_ = new Namespace(); - namespaces_.push_back(empty_namespace_); - current_namespace_ = empty_namespace_; - known_attributes_["deprecated"] = true; - known_attributes_["required"] = true; - known_attributes_["key"] = true; + // Start out with the empty namespace being current. + empty_namespace_ = new Namespace(); + namespaces_.push_back(empty_namespace_); + current_namespace_ = empty_namespace_; + known_attributes_["deprecated"] = true; + known_attributes_["required"] = true; + known_attributes_["key"] = true; known_attributes_["shared"] = true; - known_attributes_["hash"] = true; - known_attributes_["id"] = true; - known_attributes_["force_align"] = true; - known_attributes_["bit_flags"] = true; - known_attributes_["original_order"] = true; - known_attributes_["nested_flatbuffer"] = true; - known_attributes_["csharp_partial"] = true; - known_attributes_["streaming"] = true; - known_attributes_["idempotent"] = true; - known_attributes_["cpp_type"] = true; - known_attributes_["cpp_ptr_type"] = true; - known_attributes_["cpp_ptr_type_get"] = true; - known_attributes_["cpp_str_type"] = true; + known_attributes_["hash"] = true; + known_attributes_["id"] = true; + known_attributes_["force_align"] = true; + known_attributes_["bit_flags"] = true; + known_attributes_["original_order"] = true; + known_attributes_["nested_flatbuffer"] = true; + known_attributes_["csharp_partial"] = true; + known_attributes_["streaming"] = true; + known_attributes_["idempotent"] = true; + known_attributes_["cpp_type"] = true; + known_attributes_["cpp_ptr_type"] = true; + known_attributes_["cpp_ptr_type_get"] = true; + known_attributes_["cpp_str_type"] = true; known_attributes_["cpp_str_flex_ctor"] = true; - known_attributes_["native_inline"] = true; - known_attributes_["native_custom_alloc"] = true; - known_attributes_["native_type"] = true; + known_attributes_["native_inline"] = true; + known_attributes_["native_custom_alloc"] = true; + known_attributes_["native_type"] = true; known_attributes_["native_type_pack_name"] = true; - known_attributes_["native_default"] = true; - known_attributes_["flexbuffer"] = true; - known_attributes_["private"] = true; + known_attributes_["native_default"] = true; + known_attributes_["flexbuffer"] = true; + known_attributes_["private"] = true; } ~Parser() { @@ -832,8 +832,8 @@ class Parser : public ParserState { // directory. // If the source was loaded from a file and isn't an include file, // supply its name in source_filename. - // All paths specified in this call must be in posix format, if you accept - // paths from user input, please call PosixPath on them first. + // All paths specified in this call must be in posix format, if you accept + // paths from user input, please call PosixPath on them first. bool Parse(const char *_source, const char **include_paths = nullptr, const char *source_filename = nullptr); @@ -863,18 +863,18 @@ class Parser : public ParserState { Type *DeserializeType(const reflection::Type *type); - // Checks that the schema represented by this parser is a safe evolution - // of the schema provided. Returns non-empty error on any problems. - std::string ConformTo(const Parser &base); + // Checks that the schema represented by this parser is a safe evolution + // of the schema provided. Returns non-empty error on any problems. + std::string ConformTo(const Parser &base); - // Similar to Parse(), but now only accepts JSON to be parsed into a - // FlexBuffer. - bool ParseFlexBuffer(const char *source, const char *source_filename, - flexbuffers::Builder *builder); - - StructDef *LookupStruct(const std::string &id) const; + // Similar to Parse(), but now only accepts JSON to be parsed into a + // FlexBuffer. + bool ParseFlexBuffer(const char *source, const char *source_filename, + flexbuffers::Builder *builder); + + StructDef *LookupStruct(const std::string &id) const; StructDef *LookupStructThruParentNamespaces(const std::string &id) const; - + std::string UnqualifiedName(const std::string &fullQualifiedName); FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg); @@ -884,18 +884,18 @@ class Parser : public ParserState { // @param opts Options used to parce a schema and generate code. static bool SupportsOptionalScalars(const flatbuffers::IDLOptions &opts); - private: + private: class ParseDepthGuard; - void Message(const std::string &msg); - void Warning(const std::string &msg); - FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val); + void Message(const std::string &msg); + void Warning(const std::string &msg); + FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val); FLATBUFFERS_CHECKED_ERROR Next(); FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark(); - bool Is(int t) const; - bool IsIdent(const char *id) const; + bool Is(int t) const; + bool IsIdent(const char *id) const; FLATBUFFERS_CHECKED_ERROR Expect(int t); - std::string TokenToStringId(int t) const; + std::string TokenToStringId(int t) const; EnumDef *LookupEnum(const std::string &id); FLATBUFFERS_CHECKED_ERROR ParseNamespacing(std::string *id, std::string *last); @@ -906,15 +906,15 @@ class Parser : public ParserState { FieldDef **dest); FLATBUFFERS_CHECKED_ERROR ParseField(StructDef &struct_def); FLATBUFFERS_CHECKED_ERROR ParseString(Value &val, bool use_string_pooling); - FLATBUFFERS_CHECKED_ERROR ParseComma(); + FLATBUFFERS_CHECKED_ERROR ParseComma(); FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field, - size_t parent_fieldn, + size_t parent_fieldn, const StructDef *parent_struct_def, uoffset_t count, bool inside_vector = false); template<typename F> - FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn, - const StructDef *struct_def, + FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn, + const StructDef *struct_def, F body); FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def, std::string *value, uoffset_t *ovalue); @@ -929,12 +929,12 @@ class Parser : public ParserState { FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer( Value &val, FieldDef *field, size_t fieldn, const StructDef *parent_struct_def); - FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes); + FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes); FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken, bool check, Value &e, BaseType req, bool *destmatch); FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef *field); - FLATBUFFERS_CHECKED_ERROR TokenError(); + FLATBUFFERS_CHECKED_ERROR TokenError(); FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e, bool check_now); FLATBUFFERS_CHECKED_ERROR ParseFunction(const std::string *name, Value &e); @@ -948,9 +948,9 @@ class Parser : public ParserState { FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name, StructDef **dest); FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, bool is_union, - EnumDef **dest); + EnumDef **dest); FLATBUFFERS_CHECKED_ERROR ParseDecl(); - FLATBUFFERS_CHECKED_ERROR ParseService(); + FLATBUFFERS_CHECKED_ERROR ParseService(); FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def, bool isextend, bool inside_oneof); FLATBUFFERS_CHECKED_ERROR ParseProtoOption(); @@ -961,14 +961,14 @@ class Parser : public ParserState { FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue(); FLATBUFFERS_CHECKED_ERROR ParseFlexBufferNumericConstant( flexbuffers::Builder *builder); - FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder); - FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source, - const char *source_filename); - FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source, + FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder); + FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source, + const char *source_filename); + FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source, const char **include_paths, const char *source_filename); FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source, - const char **include_paths, + const char **include_paths, const char *source_filename, const char *include_filename); FLATBUFFERS_CHECKED_ERROR DoParseJson(); @@ -982,19 +982,19 @@ class Parser : public ParserState { bool SupportsAdvancedArrayFeatures() const; bool SupportsOptionalScalars() const; bool SupportsDefaultVectorsAndStrings() const; - Namespace *UniqueNamespace(Namespace *ns); - - FLATBUFFERS_CHECKED_ERROR RecurseError(); + Namespace *UniqueNamespace(Namespace *ns); + + FLATBUFFERS_CHECKED_ERROR RecurseError(); template<typename F> CheckedError Recurse(F f); - + public: - SymbolTable<Type> types_; + SymbolTable<Type> types_; SymbolTable<StructDef> structs_; SymbolTable<EnumDef> enums_; - SymbolTable<ServiceDef> services_; + SymbolTable<ServiceDef> services_; std::vector<Namespace *> namespaces_; - Namespace *current_namespace_; - Namespace *empty_namespace_; + Namespace *current_namespace_; + Namespace *empty_namespace_; std::string error_; // User readable error_ if Parse() == false FlatBufferBuilder builder_; // any data contained in the file @@ -1006,18 +1006,18 @@ class Parser : public ParserState { std::map<uint64_t, std::string> included_files_; std::map<std::string, std::set<std::string>> files_included_per_file_; - std::vector<std::string> native_included_files_; + std::vector<std::string> native_included_files_; + + std::map<std::string, bool> known_attributes_; - std::map<std::string, bool> known_attributes_; - IDLOptions opts; - bool uses_flexbuffers_; + bool uses_flexbuffers_; uint64_t advanced_features_; private: - const char *source_; - + const char *source_; + std::string file_being_parsed_; std::vector<std::pair<Value, FieldDef *>> field_stack_; @@ -1038,8 +1038,8 @@ extern std::string MakeScreamingCamel(const std::string &in); // if it is less than 0, no linefeeds will be generated either. // See idl_gen_text.cpp. // strict_json adds "quotes" around field names if true. -// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8 -// byte arrays in String values), returns false. +// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8 +// byte arrays in String values), returns false. extern bool GenerateTextFromTable(const Parser &parser, const void *table, const std::string &tablename, std::string *text); @@ -1069,8 +1069,8 @@ extern bool GenerateCSharp(const Parser &parser, const std::string &path, const std::string &file_name); extern bool GenerateDart(const Parser &parser, const std::string &path, - const std::string &file_name); - + const std::string &file_name); + // Generate Java files from the definitions in the Parser object. // See idl_gen_java.cpp. extern bool GenerateJava(const Parser &parser, const std::string &path, @@ -1089,30 +1089,30 @@ extern bool GenerateGo(const Parser &parser, const std::string &path, // Generate Php code from the definitions in the Parser object. // See idl_gen_php. extern bool GeneratePhp(const Parser &parser, const std::string &path, - const std::string &file_name); + const std::string &file_name); // Generate Python files from the definitions in the Parser object. // See idl_gen_python.cpp. extern bool GeneratePython(const Parser &parser, const std::string &path, const std::string &file_name); -// Generate Lobster files from the definitions in the Parser object. -// See idl_gen_lobster.cpp. +// Generate Lobster files from the definitions in the Parser object. +// See idl_gen_lobster.cpp. extern bool GenerateLobster(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Lua files from the definitions in the Parser object. -// See idl_gen_lua.cpp. + const std::string &file_name); + +// Generate Lua files from the definitions in the Parser object. +// See idl_gen_lua.cpp. extern bool GenerateLua(const Parser &parser, const std::string &path, const std::string &file_name); - -// Generate Rust files from the definitions in the Parser object. -// See idl_gen_rust.cpp. + +// Generate Rust files from the definitions in the Parser object. +// See idl_gen_rust.cpp. extern bool GenerateRust(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Json schema file -// See idl_gen_json_schema.cpp. + const std::string &file_name); + +// Generate Json schema file +// See idl_gen_json_schema.cpp. extern bool GenerateJsonSchema(const Parser &parser, const std::string &path, const std::string &file_name); @@ -1150,16 +1150,16 @@ extern std::string TSMakeRule(const Parser &parser, const std::string &path, extern std::string CPPMakeRule(const Parser &parser, const std::string &path, const std::string &file_name); -// Generate a make rule for the generated Dart code -// see idl_gen_dart.cpp +// Generate a make rule for the generated Dart code +// see idl_gen_dart.cpp extern std::string DartMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a make rule for the generated Rust code. -// See idl_gen_rust.cpp. + const std::string &file_name); + +// Generate a make rule for the generated Rust code. +// See idl_gen_rust.cpp. extern std::string RustMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name); - + const std::string &file_name); + // Generate a make rule for generated Java or C# files. // See code_generators.cpp. extern std::string JavaCSharpMakeRule(const Parser &parser, @@ -1176,21 +1176,21 @@ extern std::string TextMakeRule(const Parser &parser, const std::string &path, extern std::string BinaryMakeRule(const Parser &parser, const std::string &path, const std::string &file_name); -// Generate GRPC Cpp interfaces. -// See idl_gen_grpc.cpp. +// Generate GRPC Cpp interfaces. +// See idl_gen_grpc.cpp. bool GenerateCppGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate GRPC Go interfaces. -// See idl_gen_grpc.cpp. + const std::string &file_name); + +// Generate GRPC Go interfaces. +// See idl_gen_grpc.cpp. bool GenerateGoGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate GRPC Java classes. -// See idl_gen_grpc.cpp + const std::string &file_name); + +// Generate GRPC Java classes. +// See idl_gen_grpc.cpp bool GenerateJavaGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); - + const std::string &file_name); + // Generate GRPC Python interfaces. // See idl_gen_grpc.cpp. bool GeneratePythonGRPC(const Parser &parser, const std::string &path, diff --git a/contrib/libs/flatbuffers/include/flatbuffers/minireflect.h b/contrib/libs/flatbuffers/include/flatbuffers/minireflect.h index a7cb4fbea7..d95dd24b7e 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/minireflect.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/minireflect.h @@ -1,258 +1,258 @@ -/* - * 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_MINIREFLECT_H_ -#define FLATBUFFERS_MINIREFLECT_H_ - +/* + * 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_MINIREFLECT_H_ +#define FLATBUFFERS_MINIREFLECT_H_ + #include "flatbuffers.h" #include "util.h" - -namespace flatbuffers { - -// Utilities that can be used with the "mini reflection" tables present -// in generated code with --reflect-types (only types) or --reflect-names -// (also names). -// This allows basic reflection functionality such as pretty-printing -// that does not require the use of the schema parser or loading of binary -// schema files at runtime (reflection.h). - -// For any of the functions below that take `const TypeTable *`, you pass -// `FooTypeTable()` if the type of the root is `Foo`. - -// First, a generic iterator that can be used by multiple algorithms. - -struct IterationVisitor { - // These mark the scope of a table or struct. - virtual void StartSequence() {} - virtual void EndSequence() {} + +namespace flatbuffers { + +// Utilities that can be used with the "mini reflection" tables present +// in generated code with --reflect-types (only types) or --reflect-names +// (also names). +// This allows basic reflection functionality such as pretty-printing +// that does not require the use of the schema parser or loading of binary +// schema files at runtime (reflection.h). + +// For any of the functions below that take `const TypeTable *`, you pass +// `FooTypeTable()` if the type of the root is `Foo`. + +// First, a generic iterator that can be used by multiple algorithms. + +struct IterationVisitor { + // These mark the scope of a table or struct. + virtual void StartSequence() {} + virtual void EndSequence() {} // Called for each field regardless of whether it is present or not. - // If not present, val == nullptr. set_idx is the index of all set fields. - virtual void Field(size_t /*field_idx*/, size_t /*set_idx*/, - ElementaryType /*type*/, bool /*is_vector*/, - const TypeTable * /*type_table*/, const char * /*name*/, - const uint8_t * /*val*/) {} - // Called for a value that is actually present, after a field, or as part - // of a vector. - virtual void UType(uint8_t, const char *) {} - virtual void Bool(bool) {} - virtual void Char(int8_t, const char *) {} - virtual void UChar(uint8_t, const char *) {} - virtual void Short(int16_t, const char *) {} - virtual void UShort(uint16_t, const char *) {} - virtual void Int(int32_t, const char *) {} - virtual void UInt(uint32_t, const char *) {} - virtual void Long(int64_t) {} - virtual void ULong(uint64_t) {} - virtual void Float(float) {} - virtual void Double(double) {} - virtual void String(const String *) {} - virtual void Unknown(const uint8_t *) {} // From a future version. - // These mark the scope of a vector. - virtual void StartVector() {} - virtual void EndVector() {} - virtual void Element(size_t /*i*/, ElementaryType /*type*/, - const TypeTable * /*type_table*/, - const uint8_t * /*val*/) {} - virtual ~IterationVisitor() {} -}; - -inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) { - switch (type) { - case ET_UTYPE: - case ET_BOOL: - case ET_CHAR: - case ET_UCHAR: return 1; - case ET_SHORT: - case ET_USHORT: return 2; - case ET_INT: - case ET_UINT: - case ET_FLOAT: - case ET_STRING: return 4; - case ET_LONG: - case ET_ULONG: - case ET_DOUBLE: return 8; - case ET_SEQUENCE: - switch (type_table->st) { - case ST_TABLE: - case ST_UNION: return 4; + // If not present, val == nullptr. set_idx is the index of all set fields. + virtual void Field(size_t /*field_idx*/, size_t /*set_idx*/, + ElementaryType /*type*/, bool /*is_vector*/, + const TypeTable * /*type_table*/, const char * /*name*/, + const uint8_t * /*val*/) {} + // Called for a value that is actually present, after a field, or as part + // of a vector. + virtual void UType(uint8_t, const char *) {} + virtual void Bool(bool) {} + virtual void Char(int8_t, const char *) {} + virtual void UChar(uint8_t, const char *) {} + virtual void Short(int16_t, const char *) {} + virtual void UShort(uint16_t, const char *) {} + virtual void Int(int32_t, const char *) {} + virtual void UInt(uint32_t, const char *) {} + virtual void Long(int64_t) {} + virtual void ULong(uint64_t) {} + virtual void Float(float) {} + virtual void Double(double) {} + virtual void String(const String *) {} + virtual void Unknown(const uint8_t *) {} // From a future version. + // These mark the scope of a vector. + virtual void StartVector() {} + virtual void EndVector() {} + virtual void Element(size_t /*i*/, ElementaryType /*type*/, + const TypeTable * /*type_table*/, + const uint8_t * /*val*/) {} + virtual ~IterationVisitor() {} +}; + +inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) { + switch (type) { + case ET_UTYPE: + case ET_BOOL: + case ET_CHAR: + case ET_UCHAR: return 1; + case ET_SHORT: + case ET_USHORT: return 2; + case ET_INT: + case ET_UINT: + case ET_FLOAT: + case ET_STRING: return 4; + case ET_LONG: + case ET_ULONG: + case ET_DOUBLE: return 8; + case ET_SEQUENCE: + switch (type_table->st) { + case ST_TABLE: + case ST_UNION: return 4; case ST_STRUCT: return static_cast<size_t>(type_table->values[type_table->num_elems]); - default: FLATBUFFERS_ASSERT(false); return 1; - } - default: FLATBUFFERS_ASSERT(false); return 1; - } -} - + default: FLATBUFFERS_ASSERT(false); return 1; + } + default: FLATBUFFERS_ASSERT(false); return 1; + } +} + inline int64_t LookupEnum(int64_t enum_val, const int64_t *values, - size_t num_values) { - if (!values) return enum_val; - for (size_t i = 0; i < num_values; i++) { + size_t num_values) { + if (!values) return enum_val; + for (size_t i = 0; i < num_values; i++) { if (enum_val == values[i]) return static_cast<int64_t>(i); - } - return -1; // Unknown enum value. -} - -template<typename T> const char *EnumName(T tval, const TypeTable *type_table) { - if (!type_table || !type_table->names) return nullptr; + } + return -1; // Unknown enum value. +} + +template<typename T> const char *EnumName(T tval, const TypeTable *type_table) { + if (!type_table || !type_table->names) return nullptr; auto i = LookupEnum(static_cast<int64_t>(tval), type_table->values, - type_table->num_elems); + type_table->num_elems); if (i >= 0 && i < static_cast<int64_t>(type_table->num_elems)) { - return type_table->names[i]; - } - return nullptr; -} - -void IterateObject(const uint8_t *obj, const TypeTable *type_table, - IterationVisitor *visitor); - -inline void IterateValue(ElementaryType type, const uint8_t *val, - const TypeTable *type_table, const uint8_t *prev_val, - soffset_t vector_index, IterationVisitor *visitor) { - switch (type) { - case ET_UTYPE: { + return type_table->names[i]; + } + return nullptr; +} + +void IterateObject(const uint8_t *obj, const TypeTable *type_table, + IterationVisitor *visitor); + +inline void IterateValue(ElementaryType type, const uint8_t *val, + const TypeTable *type_table, const uint8_t *prev_val, + soffset_t vector_index, IterationVisitor *visitor) { + switch (type) { + case ET_UTYPE: { auto tval = ReadScalar<uint8_t>(val); - visitor->UType(tval, EnumName(tval, type_table)); - break; - } - case ET_BOOL: { + visitor->UType(tval, EnumName(tval, type_table)); + break; + } + case ET_BOOL: { visitor->Bool(ReadScalar<uint8_t>(val) != 0); - break; - } - case ET_CHAR: { + break; + } + case ET_CHAR: { auto tval = ReadScalar<int8_t>(val); - visitor->Char(tval, EnumName(tval, type_table)); - break; - } - case ET_UCHAR: { + visitor->Char(tval, EnumName(tval, type_table)); + break; + } + case ET_UCHAR: { auto tval = ReadScalar<uint8_t>(val); - visitor->UChar(tval, EnumName(tval, type_table)); - break; - } - case ET_SHORT: { + visitor->UChar(tval, EnumName(tval, type_table)); + break; + } + case ET_SHORT: { auto tval = ReadScalar<int16_t>(val); - visitor->Short(tval, EnumName(tval, type_table)); - break; - } - case ET_USHORT: { + visitor->Short(tval, EnumName(tval, type_table)); + break; + } + case ET_USHORT: { auto tval = ReadScalar<uint16_t>(val); - visitor->UShort(tval, EnumName(tval, type_table)); - break; - } - case ET_INT: { + visitor->UShort(tval, EnumName(tval, type_table)); + break; + } + case ET_INT: { auto tval = ReadScalar<int32_t>(val); - visitor->Int(tval, EnumName(tval, type_table)); - break; - } - case ET_UINT: { + visitor->Int(tval, EnumName(tval, type_table)); + break; + } + case ET_UINT: { auto tval = ReadScalar<uint32_t>(val); - visitor->UInt(tval, EnumName(tval, type_table)); - break; - } - case ET_LONG: { + visitor->UInt(tval, EnumName(tval, type_table)); + break; + } + case ET_LONG: { visitor->Long(ReadScalar<int64_t>(val)); - break; - } - case ET_ULONG: { + break; + } + case ET_ULONG: { visitor->ULong(ReadScalar<uint64_t>(val)); - break; - } - case ET_FLOAT: { + break; + } + case ET_FLOAT: { visitor->Float(ReadScalar<float>(val)); - break; - } - case ET_DOUBLE: { + break; + } + case ET_DOUBLE: { visitor->Double(ReadScalar<double>(val)); - break; - } - case ET_STRING: { - val += ReadScalar<uoffset_t>(val); - visitor->String(reinterpret_cast<const String *>(val)); - break; - } - case ET_SEQUENCE: { - switch (type_table->st) { - case ST_TABLE: - val += ReadScalar<uoffset_t>(val); - IterateObject(val, type_table, visitor); - break; - case ST_STRUCT: IterateObject(val, type_table, visitor); break; - case ST_UNION: { - val += ReadScalar<uoffset_t>(val); - FLATBUFFERS_ASSERT(prev_val); - auto union_type = *prev_val; // Always a uint8_t. - if (vector_index >= 0) { - auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(prev_val); - union_type = type_vec->Get(static_cast<uoffset_t>(vector_index)); - } - auto type_code_idx = - LookupEnum(union_type, type_table->values, type_table->num_elems); - if (type_code_idx >= 0 && - type_code_idx < static_cast<int32_t>(type_table->num_elems)) { - auto type_code = type_table->type_codes[type_code_idx]; - switch (type_code.base_type) { - case ET_SEQUENCE: { - auto ref = type_table->type_refs[type_code.sequence_ref](); - IterateObject(val, ref, visitor); - break; - } - case ET_STRING: - visitor->String(reinterpret_cast<const String *>(val)); - break; - default: visitor->Unknown(val); - } - } else { - visitor->Unknown(val); - } - break; - } - case ST_ENUM: FLATBUFFERS_ASSERT(false); break; - } - break; - } - default: { - visitor->Unknown(val); - break; - } - } -} - -inline void IterateObject(const uint8_t *obj, const TypeTable *type_table, - IterationVisitor *visitor) { - visitor->StartSequence(); - const uint8_t *prev_val = nullptr; - size_t set_idx = 0; + break; + } + case ET_STRING: { + val += ReadScalar<uoffset_t>(val); + visitor->String(reinterpret_cast<const String *>(val)); + break; + } + case ET_SEQUENCE: { + switch (type_table->st) { + case ST_TABLE: + val += ReadScalar<uoffset_t>(val); + IterateObject(val, type_table, visitor); + break; + case ST_STRUCT: IterateObject(val, type_table, visitor); break; + case ST_UNION: { + val += ReadScalar<uoffset_t>(val); + FLATBUFFERS_ASSERT(prev_val); + auto union_type = *prev_val; // Always a uint8_t. + if (vector_index >= 0) { + auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(prev_val); + union_type = type_vec->Get(static_cast<uoffset_t>(vector_index)); + } + auto type_code_idx = + LookupEnum(union_type, type_table->values, type_table->num_elems); + if (type_code_idx >= 0 && + type_code_idx < static_cast<int32_t>(type_table->num_elems)) { + auto type_code = type_table->type_codes[type_code_idx]; + switch (type_code.base_type) { + case ET_SEQUENCE: { + auto ref = type_table->type_refs[type_code.sequence_ref](); + IterateObject(val, ref, visitor); + break; + } + case ET_STRING: + visitor->String(reinterpret_cast<const String *>(val)); + break; + default: visitor->Unknown(val); + } + } else { + visitor->Unknown(val); + } + break; + } + case ST_ENUM: FLATBUFFERS_ASSERT(false); break; + } + break; + } + default: { + visitor->Unknown(val); + break; + } + } +} + +inline void IterateObject(const uint8_t *obj, const TypeTable *type_table, + IterationVisitor *visitor) { + visitor->StartSequence(); + const uint8_t *prev_val = nullptr; + size_t set_idx = 0; size_t array_idx = 0; - for (size_t i = 0; i < type_table->num_elems; i++) { - auto type_code = type_table->type_codes[i]; - auto type = static_cast<ElementaryType>(type_code.base_type); + for (size_t i = 0; i < type_table->num_elems; i++) { + auto type_code = type_table->type_codes[i]; + auto type = static_cast<ElementaryType>(type_code.base_type); auto is_repeating = type_code.is_repeating != 0; - auto ref_idx = type_code.sequence_ref; - const TypeTable *ref = nullptr; - if (ref_idx >= 0) { ref = type_table->type_refs[ref_idx](); } - auto name = type_table->names ? type_table->names[i] : nullptr; - const uint8_t *val = nullptr; - if (type_table->st == ST_TABLE) { - val = reinterpret_cast<const Table *>(obj)->GetAddressOf( - FieldIndexToOffset(static_cast<voffset_t>(i))); - } else { - val = obj + type_table->values[i]; - } + auto ref_idx = type_code.sequence_ref; + const TypeTable *ref = nullptr; + if (ref_idx >= 0) { ref = type_table->type_refs[ref_idx](); } + auto name = type_table->names ? type_table->names[i] : nullptr; + const uint8_t *val = nullptr; + if (type_table->st == ST_TABLE) { + val = reinterpret_cast<const Table *>(obj)->GetAddressOf( + FieldIndexToOffset(static_cast<voffset_t>(i))); + } else { + val = obj + type_table->values[i]; + } visitor->Field(i, set_idx, type, is_repeating, ref, name, val); - if (val) { - set_idx++; + if (val) { + set_idx++; if (is_repeating) { auto elem_ptr = val; size_t size = 0; @@ -267,38 +267,38 @@ inline void IterateObject(const uint8_t *obj, const TypeTable *type_table, size = type_table->array_sizes[array_idx]; ++array_idx; } - visitor->StartVector(); + visitor->StartVector(); for (size_t j = 0; j < size; j++) { - visitor->Element(j, type, ref, elem_ptr); - IterateValue(type, elem_ptr, ref, prev_val, static_cast<soffset_t>(j), - visitor); - elem_ptr += InlineSize(type, ref); - } - visitor->EndVector(); - } else { - IterateValue(type, val, ref, prev_val, -1, visitor); - } - } - prev_val = val; - } - visitor->EndSequence(); -} - -inline void IterateFlatBuffer(const uint8_t *buffer, - const TypeTable *type_table, - IterationVisitor *callback) { - IterateObject(GetRoot<uint8_t>(buffer), type_table, callback); -} - -// Outputting a Flatbuffer to a string. Tries to conform as close to JSON / -// the output generated by idl_gen_text.cpp. - -struct ToStringVisitor : public IterationVisitor { - std::string s; - std::string d; - bool q; - std::string in; - size_t indent_level; + visitor->Element(j, type, ref, elem_ptr); + IterateValue(type, elem_ptr, ref, prev_val, static_cast<soffset_t>(j), + visitor); + elem_ptr += InlineSize(type, ref); + } + visitor->EndVector(); + } else { + IterateValue(type, val, ref, prev_val, -1, visitor); + } + } + prev_val = val; + } + visitor->EndSequence(); +} + +inline void IterateFlatBuffer(const uint8_t *buffer, + const TypeTable *type_table, + IterationVisitor *callback) { + IterateObject(GetRoot<uint8_t>(buffer), type_table, callback); +} + +// Outputting a Flatbuffer to a string. Tries to conform as close to JSON / +// the output generated by idl_gen_text.cpp. + +struct ToStringVisitor : public IterationVisitor { + std::string s; + std::string d; + bool q; + std::string in; + size_t indent_level; bool vector_delimited; ToStringVisitor(std::string delimiter, bool quotes, std::string indent, bool vdelimited = true) @@ -307,71 +307,71 @@ struct ToStringVisitor : public IterationVisitor { in(indent), indent_level(0), vector_delimited(vdelimited) {} - ToStringVisitor(std::string delimiter) + ToStringVisitor(std::string delimiter) : d(delimiter), q(false), in(""), indent_level(0), vector_delimited(true) {} - - void append_indent() { - for (size_t i = 0; i < indent_level; i++) { s += in; } - } - - void StartSequence() { - s += "{"; - s += d; - indent_level++; - } - void EndSequence() { - s += d; - indent_level--; - append_indent(); - s += "}"; - } - void Field(size_t /*field_idx*/, size_t set_idx, ElementaryType /*type*/, - bool /*is_vector*/, const TypeTable * /*type_table*/, - const char *name, const uint8_t *val) { - if (!val) return; - if (set_idx) { - s += ","; - s += d; - } - append_indent(); - if (name) { - if (q) s += "\""; - s += name; - if (q) s += "\""; - s += ": "; - } - } - template<typename T> void Named(T x, const char *name) { - if (name) { - if (q) s += "\""; - s += name; - if (q) s += "\""; - } else { - s += NumToString(x); - } - } - void UType(uint8_t x, const char *name) { Named(x, name); } - void Bool(bool x) { s += x ? "true" : "false"; } - void Char(int8_t x, const char *name) { Named(x, name); } - void UChar(uint8_t x, const char *name) { Named(x, name); } - void Short(int16_t x, const char *name) { Named(x, name); } - void UShort(uint16_t x, const char *name) { Named(x, name); } - void Int(int32_t x, const char *name) { Named(x, name); } - void UInt(uint32_t x, const char *name) { Named(x, name); } - void Long(int64_t x) { s += NumToString(x); } - void ULong(uint64_t x) { s += NumToString(x); } - void Float(float x) { s += NumToString(x); } - void Double(double x) { s += NumToString(x); } - void String(const struct String *str) { - EscapeString(str->c_str(), str->size(), &s, true, false); - } - void Unknown(const uint8_t *) { s += "(?)"; } - void StartVector() { - s += "["; + + void append_indent() { + for (size_t i = 0; i < indent_level; i++) { s += in; } + } + + void StartSequence() { + s += "{"; + s += d; + indent_level++; + } + void EndSequence() { + s += d; + indent_level--; + append_indent(); + s += "}"; + } + void Field(size_t /*field_idx*/, size_t set_idx, ElementaryType /*type*/, + bool /*is_vector*/, const TypeTable * /*type_table*/, + const char *name, const uint8_t *val) { + if (!val) return; + if (set_idx) { + s += ","; + s += d; + } + append_indent(); + if (name) { + if (q) s += "\""; + s += name; + if (q) s += "\""; + s += ": "; + } + } + template<typename T> void Named(T x, const char *name) { + if (name) { + if (q) s += "\""; + s += name; + if (q) s += "\""; + } else { + s += NumToString(x); + } + } + void UType(uint8_t x, const char *name) { Named(x, name); } + void Bool(bool x) { s += x ? "true" : "false"; } + void Char(int8_t x, const char *name) { Named(x, name); } + void UChar(uint8_t x, const char *name) { Named(x, name); } + void Short(int16_t x, const char *name) { Named(x, name); } + void UShort(uint16_t x, const char *name) { Named(x, name); } + void Int(int32_t x, const char *name) { Named(x, name); } + void UInt(uint32_t x, const char *name) { Named(x, name); } + void Long(int64_t x) { s += NumToString(x); } + void ULong(uint64_t x) { s += NumToString(x); } + void Float(float x) { s += NumToString(x); } + void Double(double x) { s += NumToString(x); } + void String(const struct String *str) { + EscapeString(str->c_str(), str->size(), &s, true, false); + } + void Unknown(const uint8_t *) { s += "(?)"; } + void StartVector() { + s += "["; if (vector_delimited) { s += d; indent_level++; @@ -379,8 +379,8 @@ struct ToStringVisitor : public IterationVisitor { } else { s += " "; } - } - void EndVector() { + } + void EndVector() { if (vector_delimited) { s += d; indent_level--; @@ -388,32 +388,32 @@ struct ToStringVisitor : public IterationVisitor { } else { s += " "; } - s += "]"; - } - void Element(size_t i, ElementaryType /*type*/, - const TypeTable * /*type_table*/, const uint8_t * /*val*/) { - if (i) { - s += ","; + s += "]"; + } + void Element(size_t i, ElementaryType /*type*/, + const TypeTable * /*type_table*/, const uint8_t * /*val*/) { + if (i) { + s += ","; if (vector_delimited) { s += d; append_indent(); } else { s += " "; } - } - } -}; - -inline std::string FlatBufferToString(const uint8_t *buffer, - const TypeTable *type_table, + } + } +}; + +inline std::string FlatBufferToString(const uint8_t *buffer, + const TypeTable *type_table, bool multi_line = false, bool vector_delimited = true) { ToStringVisitor tostring_visitor(multi_line ? "\n" : " ", false, "", vector_delimited); - IterateFlatBuffer(buffer, type_table, &tostring_visitor); - return tostring_visitor.s; -} - -} // namespace flatbuffers - -#endif // FLATBUFFERS_MINIREFLECT_H_ + IterateFlatBuffer(buffer, type_table, &tostring_visitor); + return tostring_visitor.s; +} + +} // namespace flatbuffers + +#endif // FLATBUFFERS_MINIREFLECT_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/reflection.h b/contrib/libs/flatbuffers/include/flatbuffers/reflection.h index f7c534f1cd..d268a3ffea 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/reflection.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/reflection.h @@ -30,19 +30,19 @@ namespace flatbuffers { // ------------------------- GETTERS ------------------------- -inline bool IsScalar(reflection::BaseType t) { - return t >= reflection::UType && t <= reflection::Double; -} -inline bool IsInteger(reflection::BaseType t) { - return t >= reflection::UType && t <= reflection::ULong; -} -inline bool IsFloat(reflection::BaseType t) { - return t == reflection::Float || t == reflection::Double; -} -inline bool IsLong(reflection::BaseType t) { - return t == reflection::Long || t == reflection::ULong; -} - +inline bool IsScalar(reflection::BaseType t) { + return t >= reflection::UType && t <= reflection::Double; +} +inline bool IsInteger(reflection::BaseType t) { + return t >= reflection::UType && t <= reflection::ULong; +} +inline bool IsFloat(reflection::BaseType t) { + return t == reflection::Float || t == reflection::Double; +} +inline bool IsLong(reflection::BaseType t) { + return t == reflection::Long || t == reflection::ULong; +} + // Size of a basic type, don't use with structs. inline size_t GetTypeSize(reflection::BaseType base_type) { // This needs to correspond to the BaseType enum. @@ -77,7 +77,7 @@ inline size_t GetTypeSize(reflection::BaseType base_type) { // Same as above, but now correctly returns the size of a struct if // the field (or vector element) is a struct. -inline size_t GetTypeSizeInline(reflection::BaseType base_type, int type_index, +inline size_t GetTypeSizeInline(reflection::BaseType base_type, int type_index, const reflection::Schema &schema) { if (base_type == reflection::Obj && schema.objects()->Get(type_index)->is_struct()) { @@ -95,30 +95,30 @@ inline const Table *GetAnyRoot(const uint8_t *flatbuf) { return GetRoot<Table>(flatbuf); } -// Get a field's default, if you know it's an integer, and its exact type. -template<typename T> T GetFieldDefaultI(const reflection::Field &field) { - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); - return static_cast<T>(field.default_integer()); -} - -// Get a field's default, if you know it's floating point and its exact type. -template<typename T> T GetFieldDefaultF(const reflection::Field &field) { - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); - return static_cast<T>(field.default_real()); -} - +// Get a field's default, if you know it's an integer, and its exact type. +template<typename T> T GetFieldDefaultI(const reflection::Field &field) { + FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); + return static_cast<T>(field.default_integer()); +} + +// Get a field's default, if you know it's floating point and its exact type. +template<typename T> T GetFieldDefaultF(const reflection::Field &field) { + FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); + return static_cast<T>(field.default_real()); +} + // Get a field, if you know it's an integer, and its exact type. -template<typename T> -T GetFieldI(const Table &table, const reflection::Field &field) { - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); +template<typename T> +T GetFieldI(const Table &table, const reflection::Field &field) { + FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); return table.GetField<T>(field.offset(), static_cast<T>(field.default_integer())); } // Get a field, if you know it's floating point and its exact type. -template<typename T> -T GetFieldF(const Table &table, const reflection::Field &field) { - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); +template<typename T> +T GetFieldF(const Table &table, const reflection::Field &field) { + FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); return table.GetField<T>(field.offset(), static_cast<T>(field.default_real())); } @@ -126,15 +126,15 @@ T GetFieldF(const Table &table, const reflection::Field &field) { // Get a field, if you know it's a string. inline const String *GetFieldS(const Table &table, const reflection::Field &field) { - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::String); + FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::String); return table.GetPointer<const String *>(field.offset()); } // Get a field, if you know it's a vector. -template<typename T> -Vector<T> *GetFieldV(const Table &table, const reflection::Field &field) { - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Vector && - sizeof(T) == GetTypeSize(field.type()->element())); +template<typename T> +Vector<T> *GetFieldV(const Table &table, const reflection::Field &field) { + FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Vector && + sizeof(T) == GetTypeSize(field.type()->element())); return table.GetPointer<Vector<T> *>(field.offset()); } @@ -147,28 +147,28 @@ inline VectorOfAny *GetFieldAnyV(const Table &table, } // Get a field, if you know it's a table. -inline Table *GetFieldT(const Table &table, const reflection::Field &field) { - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj || - field.type()->base_type() == reflection::Union); +inline Table *GetFieldT(const Table &table, const reflection::Field &field) { + FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj || + field.type()->base_type() == reflection::Union); return table.GetPointer<Table *>(field.offset()); } -// Get a field, if you know it's a struct. -inline const Struct *GetFieldStruct(const Table &table, - const reflection::Field &field) { - // TODO: This does NOT check if the field is a table or struct, but we'd need - // access to the schema to check the is_struct flag. - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj); - return table.GetStruct<const Struct *>(field.offset()); -} - -// Get a structure's field, if you know it's a struct. -inline const Struct *GetFieldStruct(const Struct &structure, - const reflection::Field &field) { - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj); - return structure.GetStruct<const Struct *>(field.offset()); -} - +// Get a field, if you know it's a struct. +inline const Struct *GetFieldStruct(const Table &table, + const reflection::Field &field) { + // TODO: This does NOT check if the field is a table or struct, but we'd need + // access to the schema to check the is_struct flag. + FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj); + return table.GetStruct<const Struct *>(field.offset()); +} + +// Get a structure's field, if you know it's a struct. +inline const Struct *GetFieldStruct(const Struct &structure, + const reflection::Field &field) { + FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj); + return structure.GetStruct<const Struct *>(field.offset()); +} + // Raw helper functions used below: get any value in memory as a 64bit int, a // double or a string. // All scalars get static_cast to an int64_t, strings use strtoull, every other @@ -180,7 +180,7 @@ double GetAnyValueF(reflection::BaseType type, const uint8_t *data); // All scalars converted using stringstream, strings as-is, and all other // data types provide some level of debug-pretty-printing. std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data, - const reflection::Schema *schema, int type_index); + const reflection::Schema *schema, int type_index); // Get any table field as a 64bit int, regardless of what type it is. inline int64_t GetAnyFieldI(const Table &table, @@ -191,7 +191,7 @@ inline int64_t GetAnyFieldI(const Table &table, } // Get any table field as a double, regardless of what type it is. -inline double GetAnyFieldF(const Table &table, const reflection::Field &field) { +inline double GetAnyFieldF(const Table &table, const reflection::Field &field) { auto field_ptr = table.GetAddressOf(field.offset()); return field_ptr ? GetAnyValueF(field.type()->base_type(), field_ptr) : field.default_real(); @@ -210,13 +210,13 @@ inline std::string GetAnyFieldS(const Table &table, } // Get any struct field as a 64bit int, regardless of what type it is. -inline int64_t GetAnyFieldI(const Struct &st, const reflection::Field &field) { +inline int64_t GetAnyFieldI(const Struct &st, const reflection::Field &field) { return GetAnyValueI(field.type()->base_type(), st.GetAddressOf(field.offset())); } // Get any struct field as a double, regardless of what type it is. -inline double GetAnyFieldF(const Struct &st, const reflection::Field &field) { +inline double GetAnyFieldF(const Struct &st, const reflection::Field &field) { return GetAnyValueF(field.type()->base_type(), st.GetAddressOf(field.offset())); } @@ -250,8 +250,8 @@ inline std::string GetAnyVectorElemS(const VectorOfAny *vec, // Get a vector element that's a table/string/vector from a generic vector. // Pass Table/String/VectorOfAny as template parameter. // Warning: does no typechecking. -template<typename T> -T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) { +template<typename T> +T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) { auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i; return reinterpret_cast<T *>(elem_ptr + ReadScalar<uoffset_t>(elem_ptr)); } @@ -261,40 +261,40 @@ T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) { // Get elem_size from GetTypeSizeInline(). // Note: little-endian data on all platforms, use EndianScalar() instead of // raw pointer access with scalars). -template<typename T> -T *GetAnyVectorElemAddressOf(const VectorOfAny *vec, size_t i, - size_t elem_size) { +template<typename T> +T *GetAnyVectorElemAddressOf(const VectorOfAny *vec, size_t i, + size_t elem_size) { return reinterpret_cast<T *>(vec->Data() + elem_size * i); } // Similarly, for elements of tables. -template<typename T> -T *GetAnyFieldAddressOf(const Table &table, const reflection::Field &field) { +template<typename T> +T *GetAnyFieldAddressOf(const Table &table, const reflection::Field &field) { return reinterpret_cast<T *>(table.GetAddressOf(field.offset())); } // Similarly, for elements of structs. -template<typename T> -T *GetAnyFieldAddressOf(const Struct &st, const reflection::Field &field) { +template<typename T> +T *GetAnyFieldAddressOf(const Struct &st, const reflection::Field &field) { return reinterpret_cast<T *>(st.GetAddressOf(field.offset())); } // ------------------------- SETTERS ------------------------- // Set any scalar field, if you know its exact type. -template<typename T> -bool SetField(Table *table, const reflection::Field &field, T val) { - reflection::BaseType type = field.type()->base_type(); - if (!IsScalar(type)) { return false; } - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(type)); - T def; - if (IsInteger(type)) { - def = GetFieldDefaultI<T>(field); - } else { - FLATBUFFERS_ASSERT(IsFloat(type)); - def = GetFieldDefaultF<T>(field); - } - return table->SetField(field.offset(), val, def); +template<typename T> +bool SetField(Table *table, const reflection::Field &field, T val) { + reflection::BaseType type = field.type()->base_type(); + if (!IsScalar(type)) { return false; } + FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(type)); + T def; + if (IsInteger(type)) { + def = GetFieldDefaultI<T>(field); + } else { + FLATBUFFERS_ASSERT(IsFloat(type)); + def = GetFieldDefaultF<T>(field); + } + return table->SetField(field.offset(), val, def); } // Raw helper functions used below: set any value in memory as a 64bit int, a @@ -309,7 +309,7 @@ void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val); inline bool SetAnyFieldI(Table *table, const reflection::Field &field, int64_t val) { auto field_ptr = table->GetAddressOf(field.offset()); - if (!field_ptr) return val == GetFieldDefaultI<int64_t>(field); + if (!field_ptr) return val == GetFieldDefaultI<int64_t>(field); SetAnyValueI(field.type()->base_type(), field_ptr, val); return true; } @@ -318,14 +318,14 @@ inline bool SetAnyFieldI(Table *table, const reflection::Field &field, inline bool SetAnyFieldF(Table *table, const reflection::Field &field, double val) { auto field_ptr = table->GetAddressOf(field.offset()); - if (!field_ptr) return val == GetFieldDefaultF<double>(field); + if (!field_ptr) return val == GetFieldDefaultF<double>(field); SetAnyValueF(field.type()->base_type(), field_ptr, val); return true; } // Set any table field as a string, regardless of what type it is. inline bool SetAnyFieldS(Table *table, const reflection::Field &field, - const char *val) { + const char *val) { auto field_ptr = table->GetAddressOf(field.offset()); if (!field_ptr) return false; SetAnyValueS(field.type()->base_type(), field_ptr, val); @@ -378,29 +378,29 @@ inline void SetAnyVectorElemS(VectorOfAny *vec, reflection::BaseType elem_type, template<typename T, typename U> class pointer_inside_vector { public: pointer_inside_vector(T *ptr, std::vector<U> &vec) - : offset_(reinterpret_cast<uint8_t *>(ptr) - - reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec))), - vec_(vec) {} + : offset_(reinterpret_cast<uint8_t *>(ptr) - + reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec))), + vec_(vec) {} T *operator*() const { return reinterpret_cast<T *>( - reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec_)) + offset_); + reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec_)) + offset_); } - T *operator->() const { return operator*(); } - + T *operator->() const { return operator*(); } + private: size_t offset_; std::vector<U> &vec_; }; // Helper to create the above easily without specifying template args. -template<typename T, typename U> -pointer_inside_vector<T, U> piv(T *ptr, std::vector<U> &vec) { +template<typename T, typename U> +pointer_inside_vector<T, U> piv(T *ptr, std::vector<U> &vec) { return pointer_inside_vector<T, U>(ptr, vec); } -inline const char *UnionTypeFieldSuffix() { return "_type"; } - +inline const char *UnionTypeFieldSuffix() { return "_type"; } + // Helper to figure out the actual table type a union refers to. inline const reflection::Object &GetUnionType( const reflection::Schema &schema, const reflection::Object &parent, @@ -408,8 +408,8 @@ inline const reflection::Object &GetUnionType( auto enumdef = schema.enums()->Get(unionfield.type()->index()); // TODO: this is clumsy and slow, but no other way to find it? auto type_field = parent.fields()->LookupByKey( - (unionfield.name()->str() + UnionTypeFieldSuffix()).c_str()); - FLATBUFFERS_ASSERT(type_field); + (unionfield.name()->str() + UnionTypeFieldSuffix()).c_str()); + FLATBUFFERS_ASSERT(type_field); auto union_type = GetFieldI<uint8_t>(table, *type_field); auto enumval = enumdef->values()->LookupByKey(union_type); return *enumval->object(); @@ -434,18 +434,18 @@ uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize, uoffset_t elem_size, std::vector<uint8_t> *flatbuf, const reflection::Object *root_table = nullptr); -template<typename T> +template<typename T> void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val, const Vector<T> *vec, std::vector<uint8_t> *flatbuf, const reflection::Object *root_table = nullptr) { auto delta_elem = static_cast<int>(newsize) - static_cast<int>(vec->size()); - auto newelems = ResizeAnyVector( - schema, newsize, reinterpret_cast<const VectorOfAny *>(vec), vec->size(), - static_cast<uoffset_t>(sizeof(T)), flatbuf, root_table); + auto newelems = ResizeAnyVector( + schema, newsize, reinterpret_cast<const VectorOfAny *>(vec), vec->size(), + static_cast<uoffset_t>(sizeof(T)), flatbuf, root_table); // Set new elements to "val". for (int i = 0; i < delta_elem; i++) { auto loc = newelems + i * sizeof(T); - auto is_scalar = flatbuffers::is_scalar<T>::value; + auto is_scalar = flatbuffers::is_scalar<T>::value; if (is_scalar) { WriteScalar(loc, val); } else { // struct @@ -467,8 +467,8 @@ const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf, inline bool SetFieldT(Table *table, const reflection::Field &field, const uint8_t *val) { - FLATBUFFERS_ASSERT(sizeof(uoffset_t) == - GetTypeSize(field.type()->base_type())); + FLATBUFFERS_ASSERT(sizeof(uoffset_t) == + GetTypeSize(field.type()->base_type())); return table->SetPointer(field.offset(), val); } @@ -480,23 +480,23 @@ inline bool SetFieldT(Table *table, const reflection::Field &field, // above resizing functionality has introduced garbage in a buffer you want // to remove. // Note: this does not deal with DAGs correctly. If the table passed forms a -// DAG, the copy will be a tree instead (with duplicates). Strings can be -// shared however, by passing true for use_string_pooling. +// DAG, the copy will be a tree instead (with duplicates). Strings can be +// shared however, by passing true for use_string_pooling. Offset<const Table *> CopyTable(FlatBufferBuilder &fbb, const reflection::Schema &schema, const reflection::Object &objectdef, - const Table &table, - bool use_string_pooling = false); - -// Verifies the provided flatbuffer using reflection. -// root should point to the root type for this flatbuffer. -// buf should point to the start of flatbuffer data. -// length specifies the size of the flatbuffer data. -bool Verify(const reflection::Schema &schema, const reflection::Object &root, + const Table &table, + bool use_string_pooling = false); + +// Verifies the provided flatbuffer using reflection. +// root should point to the root type for this flatbuffer. +// buf should point to the start of flatbuffer data. +// length specifies the size of the flatbuffer data. +bool Verify(const reflection::Schema &schema, const reflection::Object &root, const uint8_t *buf, size_t length, uoffset_t max_depth = 64, uoffset_t max_tables = 1000000); - + } // namespace flatbuffers #endif // FLATBUFFERS_REFLECTION_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h b/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h index a95f7b055f..93dc4b88b7 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h @@ -1,6 +1,6 @@ // automatically generated by the FlatBuffers compiler, do not modify - + #ifndef FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_ #define FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_ @@ -10,28 +10,28 @@ namespace reflection { struct Type; struct TypeBuilder; - -struct KeyValue; + +struct KeyValue; struct KeyValueBuilder; - + struct EnumVal; struct EnumValBuilder; - + struct Enum; struct EnumBuilder; - + struct Field; struct FieldBuilder; - + struct Object; struct ObjectBuilder; - -struct RPCCall; + +struct RPCCall; struct RPCCallBuilder; - -struct Service; + +struct Service; struct ServiceBuilder; - + struct Schema; struct SchemaBuilder; @@ -58,61 +58,61 @@ enum BaseType { }; inline const BaseType (&EnumValuesBaseType())[19] { - static const BaseType values[] = { - None, - UType, - Bool, - Byte, - UByte, - Short, - UShort, - Int, - UInt, - Long, - ULong, - Float, - Double, - String, - Vector, - Obj, + static const BaseType values[] = { + None, + UType, + Bool, + Byte, + UByte, + Short, + UShort, + Int, + UInt, + Long, + ULong, + Float, + Double, + String, + Vector, + Obj, Union, Array, MaxBaseType - }; - return values; -} - -inline const char * const *EnumNamesBaseType() { + }; + return values; +} + +inline const char * const *EnumNamesBaseType() { static const char * const names[20] = { - "None", - "UType", - "Bool", - "Byte", - "UByte", - "Short", - "UShort", - "Int", - "UInt", - "Long", - "ULong", - "Float", - "Double", - "String", - "Vector", - "Obj", - "Union", + "None", + "UType", + "Bool", + "Byte", + "UByte", + "Short", + "UShort", + "Int", + "UInt", + "Long", + "ULong", + "Float", + "Double", + "String", + "Vector", + "Obj", + "Union", "Array", "MaxBaseType", - nullptr - }; + nullptr + }; return names; } -inline const char *EnumNameBaseType(BaseType e) { +inline const char *EnumNameBaseType(BaseType e) { if (flatbuffers::IsOutRange(e, None, MaxBaseType)) return ""; const size_t index = static_cast<size_t>(e); - return EnumNamesBaseType()[index]; -} + return EnumNamesBaseType()[index]; +} enum AdvancedFeatures { AdvancedArrayFeatures = 1ULL, @@ -155,28 +155,28 @@ inline const char *EnumNameAdvancedFeatures(AdvancedFeatures e) { struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef TypeBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_BASE_TYPE = 4, - VT_ELEMENT = 6, + VT_BASE_TYPE = 4, + VT_ELEMENT = 6, VT_INDEX = 8, VT_FIXED_LENGTH = 10 - }; + }; reflection::BaseType base_type() const { return static_cast<reflection::BaseType>(GetField<int8_t>(VT_BASE_TYPE, 0)); - } + } reflection::BaseType element() const { return static_cast<reflection::BaseType>(GetField<int8_t>(VT_ELEMENT, 0)); - } - int32_t index() const { - return GetField<int32_t>(VT_INDEX, -1); - } + } + int32_t index() const { + return GetField<int32_t>(VT_INDEX, -1); + } uint16_t fixed_length() const { return GetField<uint16_t>(VT_FIXED_LENGTH, 0); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField<int8_t>(verifier, VT_BASE_TYPE) && - VerifyField<int8_t>(verifier, VT_ELEMENT) && - VerifyField<int32_t>(verifier, VT_INDEX) && + VerifyField<int8_t>(verifier, VT_BASE_TYPE) && + VerifyField<int8_t>(verifier, VT_ELEMENT) && + VerifyField<int32_t>(verifier, VT_INDEX) && VerifyField<uint16_t>(verifier, VT_FIXED_LENGTH) && verifier.EndTable(); } @@ -187,30 +187,30 @@ struct TypeBuilder { flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; void add_base_type(reflection::BaseType base_type) { - fbb_.AddElement<int8_t>(Type::VT_BASE_TYPE, static_cast<int8_t>(base_type), 0); - } + fbb_.AddElement<int8_t>(Type::VT_BASE_TYPE, static_cast<int8_t>(base_type), 0); + } void add_element(reflection::BaseType element) { - fbb_.AddElement<int8_t>(Type::VT_ELEMENT, static_cast<int8_t>(element), 0); - } - void add_index(int32_t index) { - fbb_.AddElement<int32_t>(Type::VT_INDEX, index, -1); - } + fbb_.AddElement<int8_t>(Type::VT_ELEMENT, static_cast<int8_t>(element), 0); + } + void add_index(int32_t index) { + fbb_.AddElement<int32_t>(Type::VT_INDEX, index, -1); + } void add_fixed_length(uint16_t fixed_length) { fbb_.AddElement<uint16_t>(Type::VT_FIXED_LENGTH, fixed_length, 0); } - explicit TypeBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } + explicit TypeBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } flatbuffers::Offset<Type> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<Type>(end); + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<Type>(end); return o; } }; -inline flatbuffers::Offset<Type> CreateType( - flatbuffers::FlatBufferBuilder &_fbb, +inline flatbuffers::Offset<Type> CreateType( + flatbuffers::FlatBufferBuilder &_fbb, reflection::BaseType base_type = reflection::None, reflection::BaseType element = reflection::None, int32_t index = -1, @@ -223,120 +223,120 @@ inline flatbuffers::Offset<Type> CreateType( return builder_.Finish(); } -struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { +struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef KeyValueBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_KEY = 4, - VT_VALUE = 6 - }; - const flatbuffers::String *key() const { - return GetPointer<const flatbuffers::String *>(VT_KEY); - } - bool KeyCompareLessThan(const KeyValue *o) const { - return *key() < *o->key(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(key()->c_str(), val); - } - const flatbuffers::String *value() const { - return GetPointer<const flatbuffers::String *>(VT_VALUE); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_KEY) && - verifier.VerifyString(key()) && - VerifyOffset(verifier, VT_VALUE) && - verifier.VerifyString(value()) && - verifier.EndTable(); - } -}; - -struct KeyValueBuilder { + VT_KEY = 4, + VT_VALUE = 6 + }; + const flatbuffers::String *key() const { + return GetPointer<const flatbuffers::String *>(VT_KEY); + } + bool KeyCompareLessThan(const KeyValue *o) const { + return *key() < *o->key(); + } + int KeyCompareWithValue(const char *val) const { + return strcmp(key()->c_str(), val); + } + const flatbuffers::String *value() const { + return GetPointer<const flatbuffers::String *>(VT_VALUE); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffsetRequired(verifier, VT_KEY) && + verifier.VerifyString(key()) && + VerifyOffset(verifier, VT_VALUE) && + verifier.VerifyString(value()) && + verifier.EndTable(); + } +}; + +struct KeyValueBuilder { typedef KeyValue Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_key(flatbuffers::Offset<flatbuffers::String> key) { - fbb_.AddOffset(KeyValue::VT_KEY, key); - } - void add_value(flatbuffers::Offset<flatbuffers::String> value) { - fbb_.AddOffset(KeyValue::VT_VALUE, value); - } - explicit KeyValueBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset<KeyValue> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<KeyValue>(end); - fbb_.Required(o, KeyValue::VT_KEY); - return o; - } -}; - -inline flatbuffers::Offset<KeyValue> CreateKeyValue( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> key = 0, - flatbuffers::Offset<flatbuffers::String> value = 0) { - KeyValueBuilder builder_(_fbb); - builder_.add_value(value); - builder_.add_key(key); - return builder_.Finish(); -} - -inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *key = nullptr, - const char *value = nullptr) { + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_key(flatbuffers::Offset<flatbuffers::String> key) { + fbb_.AddOffset(KeyValue::VT_KEY, key); + } + void add_value(flatbuffers::Offset<flatbuffers::String> value) { + fbb_.AddOffset(KeyValue::VT_VALUE, value); + } + explicit KeyValueBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + flatbuffers::Offset<KeyValue> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<KeyValue>(end); + fbb_.Required(o, KeyValue::VT_KEY); + return o; + } +}; + +inline flatbuffers::Offset<KeyValue> CreateKeyValue( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<flatbuffers::String> key = 0, + flatbuffers::Offset<flatbuffers::String> value = 0) { + KeyValueBuilder builder_(_fbb); + builder_.add_value(value); + builder_.add_key(key); + return builder_.Finish(); +} + +inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const char *key = nullptr, + const char *value = nullptr) { auto key__ = key ? _fbb.CreateString(key) : 0; auto value__ = value ? _fbb.CreateString(value) : 0; - return reflection::CreateKeyValue( - _fbb, + return reflection::CreateKeyValue( + _fbb, key__, value__); -} - +} + struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef EnumValBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_VALUE = 6, - VT_OBJECT = 8, - VT_UNION_TYPE = 10, - VT_DOCUMENTATION = 12 - }; - const flatbuffers::String *name() const { - return GetPointer<const flatbuffers::String *>(VT_NAME); - } - int64_t value() const { - return GetField<int64_t>(VT_VALUE, 0); - } - bool KeyCompareLessThan(const EnumVal *o) const { - return value() < o->value(); - } - int KeyCompareWithValue(int64_t val) const { - return static_cast<int>(value() > val) - static_cast<int>(value() < val); - } + VT_NAME = 4, + VT_VALUE = 6, + VT_OBJECT = 8, + VT_UNION_TYPE = 10, + VT_DOCUMENTATION = 12 + }; + const flatbuffers::String *name() const { + return GetPointer<const flatbuffers::String *>(VT_NAME); + } + int64_t value() const { + return GetField<int64_t>(VT_VALUE, 0); + } + bool KeyCompareLessThan(const EnumVal *o) const { + return value() < o->value(); + } + int KeyCompareWithValue(int64_t val) const { + return static_cast<int>(value() > val) - static_cast<int>(value() < val); + } const reflection::Object *object() const { return GetPointer<const reflection::Object *>(VT_OBJECT); - } + } const reflection::Type *union_type() const { return GetPointer<const reflection::Type *>(VT_UNION_TYPE); - } - const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); - } + } + const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { + return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyField<int64_t>(verifier, VT_VALUE) && - VerifyOffset(verifier, VT_OBJECT) && + VerifyOffsetRequired(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyField<int64_t>(verifier, VT_VALUE) && + VerifyOffset(verifier, VT_OBJECT) && verifier.VerifyTable(object()) && - VerifyOffset(verifier, VT_UNION_TYPE) && - verifier.VerifyTable(union_type()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && + VerifyOffset(verifier, VT_UNION_TYPE) && + verifier.VerifyTable(union_type()) && + VerifyOffset(verifier, VT_DOCUMENTATION) && + verifier.VerifyVector(documentation()) && + verifier.VerifyVectorOfStrings(documentation()) && verifier.EndTable(); } }; @@ -345,117 +345,117 @@ struct EnumValBuilder { typedef EnumVal Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset<flatbuffers::String> name) { - fbb_.AddOffset(EnumVal::VT_NAME, name); - } - void add_value(int64_t value) { - fbb_.AddElement<int64_t>(EnumVal::VT_VALUE, value, 0); - } + void add_name(flatbuffers::Offset<flatbuffers::String> name) { + fbb_.AddOffset(EnumVal::VT_NAME, name); + } + void add_value(int64_t value) { + fbb_.AddElement<int64_t>(EnumVal::VT_VALUE, value, 0); + } void add_object(flatbuffers::Offset<reflection::Object> object) { - fbb_.AddOffset(EnumVal::VT_OBJECT, object); - } + fbb_.AddOffset(EnumVal::VT_OBJECT, object); + } void add_union_type(flatbuffers::Offset<reflection::Type> union_type) { - fbb_.AddOffset(EnumVal::VT_UNION_TYPE, union_type); - } - void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { - fbb_.AddOffset(EnumVal::VT_DOCUMENTATION, documentation); - } - explicit EnumValBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } + fbb_.AddOffset(EnumVal::VT_UNION_TYPE, union_type); + } + void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { + fbb_.AddOffset(EnumVal::VT_DOCUMENTATION, documentation); + } + explicit EnumValBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } flatbuffers::Offset<EnumVal> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<EnumVal>(end); - fbb_.Required(o, EnumVal::VT_NAME); + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<EnumVal>(end); + fbb_.Required(o, EnumVal::VT_NAME); return o; } }; -inline flatbuffers::Offset<EnumVal> CreateEnumVal( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> name = 0, - int64_t value = 0, +inline flatbuffers::Offset<EnumVal> CreateEnumVal( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<flatbuffers::String> name = 0, + int64_t value = 0, flatbuffers::Offset<reflection::Object> object = 0, flatbuffers::Offset<reflection::Type> union_type = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { EnumValBuilder builder_(_fbb); builder_.add_value(value); - builder_.add_documentation(documentation); - builder_.add_union_type(union_type); + builder_.add_documentation(documentation); + builder_.add_union_type(union_type); builder_.add_object(object); builder_.add_name(name); return builder_.Finish(); } -inline flatbuffers::Offset<EnumVal> CreateEnumValDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - int64_t value = 0, +inline flatbuffers::Offset<EnumVal> CreateEnumValDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, + int64_t value = 0, flatbuffers::Offset<reflection::Object> object = 0, flatbuffers::Offset<reflection::Type> union_type = 0, - const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { + const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { auto name__ = name ? _fbb.CreateString(name) : 0; auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0; - return reflection::CreateEnumVal( - _fbb, + return reflection::CreateEnumVal( + _fbb, name__, - value, - object, - union_type, + value, + object, + union_type, documentation__); -} - +} + struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef EnumBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_VALUES = 6, - VT_IS_UNION = 8, - VT_UNDERLYING_TYPE = 10, - VT_ATTRIBUTES = 12, - VT_DOCUMENTATION = 14 - }; - const flatbuffers::String *name() const { - return GetPointer<const flatbuffers::String *>(VT_NAME); - } - bool KeyCompareLessThan(const Enum *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } + VT_NAME = 4, + VT_VALUES = 6, + VT_IS_UNION = 8, + VT_UNDERLYING_TYPE = 10, + VT_ATTRIBUTES = 12, + VT_DOCUMENTATION = 14 + }; + const flatbuffers::String *name() const { + return GetPointer<const flatbuffers::String *>(VT_NAME); + } + bool KeyCompareLessThan(const Enum *o) const { + return *name() < *o->name(); + } + int KeyCompareWithValue(const char *val) const { + return strcmp(name()->c_str(), val); + } const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *values() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *>(VT_VALUES); - } - bool is_union() const { - return GetField<uint8_t>(VT_IS_UNION, 0) != 0; - } + } + bool is_union() const { + return GetField<uint8_t>(VT_IS_UNION, 0) != 0; + } const reflection::Type *underlying_type() const { return GetPointer<const reflection::Type *>(VT_UNDERLYING_TYPE); - } + } const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); - } + } + const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { + return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffsetRequired(verifier, VT_VALUES) && - verifier.VerifyVector(values()) && + VerifyOffsetRequired(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyOffsetRequired(verifier, VT_VALUES) && + verifier.VerifyVector(values()) && verifier.VerifyVectorOfTables(values()) && - VerifyField<uint8_t>(verifier, VT_IS_UNION) && - VerifyOffsetRequired(verifier, VT_UNDERLYING_TYPE) && + VerifyField<uint8_t>(verifier, VT_IS_UNION) && + VerifyOffsetRequired(verifier, VT_UNDERLYING_TYPE) && verifier.VerifyTable(underlying_type()) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && + VerifyOffset(verifier, VT_ATTRIBUTES) && + verifier.VerifyVector(attributes()) && + verifier.VerifyVectorOfTables(attributes()) && + VerifyOffset(verifier, VT_DOCUMENTATION) && + verifier.VerifyVector(documentation()) && + verifier.VerifyVectorOfStrings(documentation()) && verifier.EndTable(); } }; @@ -464,49 +464,49 @@ struct EnumBuilder { typedef Enum Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset<flatbuffers::String> name) { - fbb_.AddOffset(Enum::VT_NAME, name); - } + void add_name(flatbuffers::Offset<flatbuffers::String> name) { + fbb_.AddOffset(Enum::VT_NAME, name); + } void add_values(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values) { - fbb_.AddOffset(Enum::VT_VALUES, values); - } - void add_is_union(bool is_union) { - fbb_.AddElement<uint8_t>(Enum::VT_IS_UNION, static_cast<uint8_t>(is_union), 0); - } + fbb_.AddOffset(Enum::VT_VALUES, values); + } + void add_is_union(bool is_union) { + fbb_.AddElement<uint8_t>(Enum::VT_IS_UNION, static_cast<uint8_t>(is_union), 0); + } void add_underlying_type(flatbuffers::Offset<reflection::Type> underlying_type) { - fbb_.AddOffset(Enum::VT_UNDERLYING_TYPE, underlying_type); - } + fbb_.AddOffset(Enum::VT_UNDERLYING_TYPE, underlying_type); + } void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) { - fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { - fbb_.AddOffset(Enum::VT_DOCUMENTATION, documentation); - } - explicit EnumBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } + fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes); + } + void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { + fbb_.AddOffset(Enum::VT_DOCUMENTATION, documentation); + } + explicit EnumBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } flatbuffers::Offset<Enum> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<Enum>(end); - fbb_.Required(o, Enum::VT_NAME); - fbb_.Required(o, Enum::VT_VALUES); - fbb_.Required(o, Enum::VT_UNDERLYING_TYPE); + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<Enum>(end); + fbb_.Required(o, Enum::VT_NAME); + fbb_.Required(o, Enum::VT_VALUES); + fbb_.Required(o, Enum::VT_UNDERLYING_TYPE); return o; } }; -inline flatbuffers::Offset<Enum> CreateEnum( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> name = 0, +inline flatbuffers::Offset<Enum> CreateEnum( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<flatbuffers::String> name = 0, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values = 0, - bool is_union = false, + bool is_union = false, flatbuffers::Offset<reflection::Type> underlying_type = 0, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { EnumBuilder builder_(_fbb); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); + builder_.add_documentation(documentation); + builder_.add_attributes(attributes); builder_.add_underlying_type(underlying_type); builder_.add_values(values); builder_.add_name(name); @@ -514,105 +514,105 @@ inline flatbuffers::Offset<Enum> CreateEnum( return builder_.Finish(); } -inline flatbuffers::Offset<Enum> CreateEnumDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, +inline flatbuffers::Offset<Enum> CreateEnumDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, std::vector<flatbuffers::Offset<reflection::EnumVal>> *values = nullptr, - bool is_union = false, + bool is_union = false, flatbuffers::Offset<reflection::Type> underlying_type = 0, std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr, - const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { + const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { auto name__ = name ? _fbb.CreateString(name) : 0; auto values__ = values ? _fbb.CreateVectorOfSortedTables<reflection::EnumVal>(values) : 0; auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0; auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0; - return reflection::CreateEnum( - _fbb, + return reflection::CreateEnum( + _fbb, name__, values__, - is_union, - underlying_type, + is_union, + underlying_type, attributes__, documentation__); -} - +} + struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef FieldBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_TYPE = 6, - VT_ID = 8, - VT_OFFSET = 10, - VT_DEFAULT_INTEGER = 12, - VT_DEFAULT_REAL = 14, - VT_DEPRECATED = 16, - VT_REQUIRED = 18, - VT_KEY = 20, - VT_ATTRIBUTES = 22, + VT_NAME = 4, + VT_TYPE = 6, + VT_ID = 8, + VT_OFFSET = 10, + VT_DEFAULT_INTEGER = 12, + VT_DEFAULT_REAL = 14, + VT_DEPRECATED = 16, + VT_REQUIRED = 18, + VT_KEY = 20, + VT_ATTRIBUTES = 22, VT_DOCUMENTATION = 24, VT_OPTIONAL = 26 - }; - const flatbuffers::String *name() const { - return GetPointer<const flatbuffers::String *>(VT_NAME); - } - bool KeyCompareLessThan(const Field *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } + }; + const flatbuffers::String *name() const { + return GetPointer<const flatbuffers::String *>(VT_NAME); + } + bool KeyCompareLessThan(const Field *o) const { + return *name() < *o->name(); + } + int KeyCompareWithValue(const char *val) const { + return strcmp(name()->c_str(), val); + } const reflection::Type *type() const { return GetPointer<const reflection::Type *>(VT_TYPE); - } - uint16_t id() const { - return GetField<uint16_t>(VT_ID, 0); - } - uint16_t offset() const { - return GetField<uint16_t>(VT_OFFSET, 0); - } - int64_t default_integer() const { - return GetField<int64_t>(VT_DEFAULT_INTEGER, 0); - } - double default_real() const { - return GetField<double>(VT_DEFAULT_REAL, 0.0); - } - bool deprecated() const { - return GetField<uint8_t>(VT_DEPRECATED, 0) != 0; - } - bool required() const { - return GetField<uint8_t>(VT_REQUIRED, 0) != 0; - } - bool key() const { - return GetField<uint8_t>(VT_KEY, 0) != 0; - } + } + uint16_t id() const { + return GetField<uint16_t>(VT_ID, 0); + } + uint16_t offset() const { + return GetField<uint16_t>(VT_OFFSET, 0); + } + int64_t default_integer() const { + return GetField<int64_t>(VT_DEFAULT_INTEGER, 0); + } + double default_real() const { + return GetField<double>(VT_DEFAULT_REAL, 0.0); + } + bool deprecated() const { + return GetField<uint8_t>(VT_DEPRECATED, 0) != 0; + } + bool required() const { + return GetField<uint8_t>(VT_REQUIRED, 0) != 0; + } + bool key() const { + return GetField<uint8_t>(VT_KEY, 0) != 0; + } const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); - } + } + const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { + return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); + } bool optional() const { return GetField<uint8_t>(VT_OPTIONAL, 0) != 0; } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffsetRequired(verifier, VT_TYPE) && + VerifyOffsetRequired(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyOffsetRequired(verifier, VT_TYPE) && verifier.VerifyTable(type()) && - VerifyField<uint16_t>(verifier, VT_ID) && - VerifyField<uint16_t>(verifier, VT_OFFSET) && - VerifyField<int64_t>(verifier, VT_DEFAULT_INTEGER) && - VerifyField<double>(verifier, VT_DEFAULT_REAL) && - VerifyField<uint8_t>(verifier, VT_DEPRECATED) && - VerifyField<uint8_t>(verifier, VT_REQUIRED) && - VerifyField<uint8_t>(verifier, VT_KEY) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && + VerifyField<uint16_t>(verifier, VT_ID) && + VerifyField<uint16_t>(verifier, VT_OFFSET) && + VerifyField<int64_t>(verifier, VT_DEFAULT_INTEGER) && + VerifyField<double>(verifier, VT_DEFAULT_REAL) && + VerifyField<uint8_t>(verifier, VT_DEPRECATED) && + VerifyField<uint8_t>(verifier, VT_REQUIRED) && + VerifyField<uint8_t>(verifier, VT_KEY) && + VerifyOffset(verifier, VT_ATTRIBUTES) && + verifier.VerifyVector(attributes()) && + verifier.VerifyVectorOfTables(attributes()) && + VerifyOffset(verifier, VT_DOCUMENTATION) && + verifier.VerifyVector(documentation()) && + verifier.VerifyVectorOfStrings(documentation()) && VerifyField<uint8_t>(verifier, VT_OPTIONAL) && verifier.EndTable(); } @@ -622,74 +622,74 @@ struct FieldBuilder { typedef Field Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset<flatbuffers::String> name) { - fbb_.AddOffset(Field::VT_NAME, name); - } + void add_name(flatbuffers::Offset<flatbuffers::String> name) { + fbb_.AddOffset(Field::VT_NAME, name); + } void add_type(flatbuffers::Offset<reflection::Type> type) { - fbb_.AddOffset(Field::VT_TYPE, type); - } - void add_id(uint16_t id) { - fbb_.AddElement<uint16_t>(Field::VT_ID, id, 0); - } - void add_offset(uint16_t offset) { - fbb_.AddElement<uint16_t>(Field::VT_OFFSET, offset, 0); - } - void add_default_integer(int64_t default_integer) { - fbb_.AddElement<int64_t>(Field::VT_DEFAULT_INTEGER, default_integer, 0); - } - void add_default_real(double default_real) { - fbb_.AddElement<double>(Field::VT_DEFAULT_REAL, default_real, 0.0); - } - void add_deprecated(bool deprecated) { - fbb_.AddElement<uint8_t>(Field::VT_DEPRECATED, static_cast<uint8_t>(deprecated), 0); - } - void add_required(bool required) { - fbb_.AddElement<uint8_t>(Field::VT_REQUIRED, static_cast<uint8_t>(required), 0); - } - void add_key(bool key) { - fbb_.AddElement<uint8_t>(Field::VT_KEY, static_cast<uint8_t>(key), 0); - } + fbb_.AddOffset(Field::VT_TYPE, type); + } + void add_id(uint16_t id) { + fbb_.AddElement<uint16_t>(Field::VT_ID, id, 0); + } + void add_offset(uint16_t offset) { + fbb_.AddElement<uint16_t>(Field::VT_OFFSET, offset, 0); + } + void add_default_integer(int64_t default_integer) { + fbb_.AddElement<int64_t>(Field::VT_DEFAULT_INTEGER, default_integer, 0); + } + void add_default_real(double default_real) { + fbb_.AddElement<double>(Field::VT_DEFAULT_REAL, default_real, 0.0); + } + void add_deprecated(bool deprecated) { + fbb_.AddElement<uint8_t>(Field::VT_DEPRECATED, static_cast<uint8_t>(deprecated), 0); + } + void add_required(bool required) { + fbb_.AddElement<uint8_t>(Field::VT_REQUIRED, static_cast<uint8_t>(required), 0); + } + void add_key(bool key) { + fbb_.AddElement<uint8_t>(Field::VT_KEY, static_cast<uint8_t>(key), 0); + } void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) { - fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { - fbb_.AddOffset(Field::VT_DOCUMENTATION, documentation); - } + fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes); + } + void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { + fbb_.AddOffset(Field::VT_DOCUMENTATION, documentation); + } void add_optional(bool optional) { fbb_.AddElement<uint8_t>(Field::VT_OPTIONAL, static_cast<uint8_t>(optional), 0); } - explicit FieldBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } + explicit FieldBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } flatbuffers::Offset<Field> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<Field>(end); - fbb_.Required(o, Field::VT_NAME); - fbb_.Required(o, Field::VT_TYPE); + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<Field>(end); + fbb_.Required(o, Field::VT_NAME); + fbb_.Required(o, Field::VT_TYPE); return o; } }; -inline flatbuffers::Offset<Field> CreateField( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> name = 0, +inline flatbuffers::Offset<Field> CreateField( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<flatbuffers::String> name = 0, flatbuffers::Offset<reflection::Type> type = 0, - uint16_t id = 0, - uint16_t offset = 0, - int64_t default_integer = 0, - double default_real = 0.0, - bool deprecated = false, - bool required = false, - bool key = false, + uint16_t id = 0, + uint16_t offset = 0, + int64_t default_integer = 0, + double default_real = 0.0, + bool deprecated = false, + bool required = false, + bool key = false, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0, bool optional = false) { FieldBuilder builder_(_fbb); builder_.add_default_real(default_real); builder_.add_default_integer(default_integer); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); + builder_.add_documentation(documentation); + builder_.add_attributes(attributes); builder_.add_type(type); builder_.add_name(name); builder_.add_offset(offset); @@ -701,93 +701,93 @@ inline flatbuffers::Offset<Field> CreateField( return builder_.Finish(); } -inline flatbuffers::Offset<Field> CreateFieldDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, +inline flatbuffers::Offset<Field> CreateFieldDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, flatbuffers::Offset<reflection::Type> type = 0, - uint16_t id = 0, - uint16_t offset = 0, - int64_t default_integer = 0, - double default_real = 0.0, - bool deprecated = false, - bool required = false, - bool key = false, + uint16_t id = 0, + uint16_t offset = 0, + int64_t default_integer = 0, + double default_real = 0.0, + bool deprecated = false, + bool required = false, + bool key = false, std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr, const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr, bool optional = false) { auto name__ = name ? _fbb.CreateString(name) : 0; auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0; auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0; - return reflection::CreateField( - _fbb, + return reflection::CreateField( + _fbb, name__, - type, - id, - offset, - default_integer, - default_real, - deprecated, - required, - key, + type, + id, + offset, + default_integer, + default_real, + deprecated, + required, + key, attributes__, documentation__, optional); -} - +} + struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef ObjectBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_FIELDS = 6, - VT_IS_STRUCT = 8, - VT_MINALIGN = 10, - VT_BYTESIZE = 12, - VT_ATTRIBUTES = 14, - VT_DOCUMENTATION = 16 - }; - const flatbuffers::String *name() const { - return GetPointer<const flatbuffers::String *>(VT_NAME); - } - bool KeyCompareLessThan(const Object *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } + VT_NAME = 4, + VT_FIELDS = 6, + VT_IS_STRUCT = 8, + VT_MINALIGN = 10, + VT_BYTESIZE = 12, + VT_ATTRIBUTES = 14, + VT_DOCUMENTATION = 16 + }; + const flatbuffers::String *name() const { + return GetPointer<const flatbuffers::String *>(VT_NAME); + } + bool KeyCompareLessThan(const Object *o) const { + return *name() < *o->name(); + } + int KeyCompareWithValue(const char *val) const { + return strcmp(name()->c_str(), val); + } const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *fields() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *>(VT_FIELDS); - } - bool is_struct() const { - return GetField<uint8_t>(VT_IS_STRUCT, 0) != 0; - } - int32_t minalign() const { - return GetField<int32_t>(VT_MINALIGN, 0); - } - int32_t bytesize() const { - return GetField<int32_t>(VT_BYTESIZE, 0); - } + } + bool is_struct() const { + return GetField<uint8_t>(VT_IS_STRUCT, 0) != 0; + } + int32_t minalign() const { + return GetField<int32_t>(VT_MINALIGN, 0); + } + int32_t bytesize() const { + return GetField<int32_t>(VT_BYTESIZE, 0); + } const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); - } + } + const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { + return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffsetRequired(verifier, VT_FIELDS) && - verifier.VerifyVector(fields()) && + VerifyOffsetRequired(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyOffsetRequired(verifier, VT_FIELDS) && + verifier.VerifyVector(fields()) && verifier.VerifyVectorOfTables(fields()) && - VerifyField<uint8_t>(verifier, VT_IS_STRUCT) && - VerifyField<int32_t>(verifier, VT_MINALIGN) && - VerifyField<int32_t>(verifier, VT_BYTESIZE) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && + VerifyField<uint8_t>(verifier, VT_IS_STRUCT) && + VerifyField<int32_t>(verifier, VT_MINALIGN) && + VerifyField<int32_t>(verifier, VT_BYTESIZE) && + VerifyOffset(verifier, VT_ATTRIBUTES) && + verifier.VerifyVector(attributes()) && + verifier.VerifyVectorOfTables(attributes()) && + VerifyOffset(verifier, VT_DOCUMENTATION) && + verifier.VerifyVector(documentation()) && + verifier.VerifyVectorOfStrings(documentation()) && verifier.EndTable(); } }; @@ -796,52 +796,52 @@ struct ObjectBuilder { typedef Object Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset<flatbuffers::String> name) { - fbb_.AddOffset(Object::VT_NAME, name); - } + void add_name(flatbuffers::Offset<flatbuffers::String> name) { + fbb_.AddOffset(Object::VT_NAME, name); + } void add_fields(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields) { - fbb_.AddOffset(Object::VT_FIELDS, fields); - } - void add_is_struct(bool is_struct) { - fbb_.AddElement<uint8_t>(Object::VT_IS_STRUCT, static_cast<uint8_t>(is_struct), 0); - } - void add_minalign(int32_t minalign) { - fbb_.AddElement<int32_t>(Object::VT_MINALIGN, minalign, 0); - } - void add_bytesize(int32_t bytesize) { - fbb_.AddElement<int32_t>(Object::VT_BYTESIZE, bytesize, 0); - } + fbb_.AddOffset(Object::VT_FIELDS, fields); + } + void add_is_struct(bool is_struct) { + fbb_.AddElement<uint8_t>(Object::VT_IS_STRUCT, static_cast<uint8_t>(is_struct), 0); + } + void add_minalign(int32_t minalign) { + fbb_.AddElement<int32_t>(Object::VT_MINALIGN, minalign, 0); + } + void add_bytesize(int32_t bytesize) { + fbb_.AddElement<int32_t>(Object::VT_BYTESIZE, bytesize, 0); + } void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) { - fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { - fbb_.AddOffset(Object::VT_DOCUMENTATION, documentation); - } - explicit ObjectBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } + fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes); + } + void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { + fbb_.AddOffset(Object::VT_DOCUMENTATION, documentation); + } + explicit ObjectBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } flatbuffers::Offset<Object> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<Object>(end); - fbb_.Required(o, Object::VT_NAME); - fbb_.Required(o, Object::VT_FIELDS); + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<Object>(end); + fbb_.Required(o, Object::VT_NAME); + fbb_.Required(o, Object::VT_FIELDS); return o; } }; -inline flatbuffers::Offset<Object> CreateObject( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> name = 0, +inline flatbuffers::Offset<Object> CreateObject( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<flatbuffers::String> name = 0, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields = 0, - bool is_struct = false, - int32_t minalign = 0, - int32_t bytesize = 0, + bool is_struct = false, + int32_t minalign = 0, + int32_t bytesize = 0, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { ObjectBuilder builder_(_fbb); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); + builder_.add_documentation(documentation); + builder_.add_attributes(attributes); builder_.add_bytesize(bytesize); builder_.add_minalign(minalign); builder_.add_fields(fields); @@ -850,298 +850,298 @@ inline flatbuffers::Offset<Object> CreateObject( return builder_.Finish(); } -inline flatbuffers::Offset<Object> CreateObjectDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, +inline flatbuffers::Offset<Object> CreateObjectDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, std::vector<flatbuffers::Offset<reflection::Field>> *fields = nullptr, - bool is_struct = false, - int32_t minalign = 0, - int32_t bytesize = 0, + bool is_struct = false, + int32_t minalign = 0, + int32_t bytesize = 0, std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr, - const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { + const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { auto name__ = name ? _fbb.CreateString(name) : 0; auto fields__ = fields ? _fbb.CreateVectorOfSortedTables<reflection::Field>(fields) : 0; auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0; auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0; - return reflection::CreateObject( - _fbb, + return reflection::CreateObject( + _fbb, name__, fields__, - is_struct, - minalign, - bytesize, + is_struct, + minalign, + bytesize, attributes__, documentation__); -} - -struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { +} + +struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef RPCCallBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_REQUEST = 6, - VT_RESPONSE = 8, - VT_ATTRIBUTES = 10, - VT_DOCUMENTATION = 12 - }; - const flatbuffers::String *name() const { - return GetPointer<const flatbuffers::String *>(VT_NAME); - } - bool KeyCompareLessThan(const RPCCall *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } + VT_NAME = 4, + VT_REQUEST = 6, + VT_RESPONSE = 8, + VT_ATTRIBUTES = 10, + VT_DOCUMENTATION = 12 + }; + const flatbuffers::String *name() const { + return GetPointer<const flatbuffers::String *>(VT_NAME); + } + bool KeyCompareLessThan(const RPCCall *o) const { + return *name() < *o->name(); + } + int KeyCompareWithValue(const char *val) const { + return strcmp(name()->c_str(), val); + } const reflection::Object *request() const { return GetPointer<const reflection::Object *>(VT_REQUEST); - } + } const reflection::Object *response() const { return GetPointer<const reflection::Object *>(VT_RESPONSE); - } + } const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffsetRequired(verifier, VT_REQUEST) && - verifier.VerifyTable(request()) && - VerifyOffsetRequired(verifier, VT_RESPONSE) && - verifier.VerifyTable(response()) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - verifier.EndTable(); - } -}; - -struct RPCCallBuilder { + } + const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { + return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffsetRequired(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyOffsetRequired(verifier, VT_REQUEST) && + verifier.VerifyTable(request()) && + VerifyOffsetRequired(verifier, VT_RESPONSE) && + verifier.VerifyTable(response()) && + VerifyOffset(verifier, VT_ATTRIBUTES) && + verifier.VerifyVector(attributes()) && + verifier.VerifyVectorOfTables(attributes()) && + VerifyOffset(verifier, VT_DOCUMENTATION) && + verifier.VerifyVector(documentation()) && + verifier.VerifyVectorOfStrings(documentation()) && + verifier.EndTable(); + } +}; + +struct RPCCallBuilder { typedef RPCCall Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset<flatbuffers::String> name) { - fbb_.AddOffset(RPCCall::VT_NAME, name); - } + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_name(flatbuffers::Offset<flatbuffers::String> name) { + fbb_.AddOffset(RPCCall::VT_NAME, name); + } void add_request(flatbuffers::Offset<reflection::Object> request) { - fbb_.AddOffset(RPCCall::VT_REQUEST, request); - } + fbb_.AddOffset(RPCCall::VT_REQUEST, request); + } void add_response(flatbuffers::Offset<reflection::Object> response) { - fbb_.AddOffset(RPCCall::VT_RESPONSE, response); - } + fbb_.AddOffset(RPCCall::VT_RESPONSE, response); + } void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) { - fbb_.AddOffset(RPCCall::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { - fbb_.AddOffset(RPCCall::VT_DOCUMENTATION, documentation); - } - explicit RPCCallBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset<RPCCall> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<RPCCall>(end); - fbb_.Required(o, RPCCall::VT_NAME); - fbb_.Required(o, RPCCall::VT_REQUEST); - fbb_.Required(o, RPCCall::VT_RESPONSE); - return o; - } -}; - -inline flatbuffers::Offset<RPCCall> CreateRPCCall( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> name = 0, + fbb_.AddOffset(RPCCall::VT_ATTRIBUTES, attributes); + } + void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { + fbb_.AddOffset(RPCCall::VT_DOCUMENTATION, documentation); + } + explicit RPCCallBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + flatbuffers::Offset<RPCCall> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<RPCCall>(end); + fbb_.Required(o, RPCCall::VT_NAME); + fbb_.Required(o, RPCCall::VT_REQUEST); + fbb_.Required(o, RPCCall::VT_RESPONSE); + return o; + } +}; + +inline flatbuffers::Offset<RPCCall> CreateRPCCall( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<flatbuffers::String> name = 0, flatbuffers::Offset<reflection::Object> request = 0, flatbuffers::Offset<reflection::Object> response = 0, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { - RPCCallBuilder builder_(_fbb); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); - builder_.add_response(response); - builder_.add_request(request); - builder_.add_name(name); - return builder_.Finish(); -} - -inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { + RPCCallBuilder builder_(_fbb); + builder_.add_documentation(documentation); + builder_.add_attributes(attributes); + builder_.add_response(response); + builder_.add_request(request); + builder_.add_name(name); + return builder_.Finish(); +} + +inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, flatbuffers::Offset<reflection::Object> request = 0, flatbuffers::Offset<reflection::Object> response = 0, std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr, - const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { + const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { auto name__ = name ? _fbb.CreateString(name) : 0; auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0; auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0; - return reflection::CreateRPCCall( - _fbb, + return reflection::CreateRPCCall( + _fbb, name__, - request, - response, + request, + response, attributes__, documentation__); -} - -struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { +} + +struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef ServiceBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_CALLS = 6, - VT_ATTRIBUTES = 8, - VT_DOCUMENTATION = 10 - }; - const flatbuffers::String *name() const { - return GetPointer<const flatbuffers::String *>(VT_NAME); - } - bool KeyCompareLessThan(const Service *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } + VT_NAME = 4, + VT_CALLS = 6, + VT_ATTRIBUTES = 8, + VT_DOCUMENTATION = 10 + }; + const flatbuffers::String *name() const { + return GetPointer<const flatbuffers::String *>(VT_NAME); + } + bool KeyCompareLessThan(const Service *o) const { + return *name() < *o->name(); + } + int KeyCompareWithValue(const char *val) const { + return strcmp(name()->c_str(), val); + } const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *calls() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *>(VT_CALLS); - } + } const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { - return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffset(verifier, VT_CALLS) && - verifier.VerifyVector(calls()) && - verifier.VerifyVectorOfTables(calls()) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - verifier.EndTable(); - } -}; - -struct ServiceBuilder { + } + const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const { + return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffsetRequired(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyOffset(verifier, VT_CALLS) && + verifier.VerifyVector(calls()) && + verifier.VerifyVectorOfTables(calls()) && + VerifyOffset(verifier, VT_ATTRIBUTES) && + verifier.VerifyVector(attributes()) && + verifier.VerifyVectorOfTables(attributes()) && + VerifyOffset(verifier, VT_DOCUMENTATION) && + verifier.VerifyVector(documentation()) && + verifier.VerifyVectorOfStrings(documentation()) && + verifier.EndTable(); + } +}; + +struct ServiceBuilder { typedef Service Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset<flatbuffers::String> name) { - fbb_.AddOffset(Service::VT_NAME, name); - } + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_name(flatbuffers::Offset<flatbuffers::String> name) { + fbb_.AddOffset(Service::VT_NAME, name); + } void add_calls(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls) { - fbb_.AddOffset(Service::VT_CALLS, calls); - } + fbb_.AddOffset(Service::VT_CALLS, calls); + } void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) { - fbb_.AddOffset(Service::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { - fbb_.AddOffset(Service::VT_DOCUMENTATION, documentation); - } - explicit ServiceBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset<Service> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<Service>(end); - fbb_.Required(o, Service::VT_NAME); - return o; - } -}; - -inline flatbuffers::Offset<Service> CreateService( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset<flatbuffers::String> name = 0, + fbb_.AddOffset(Service::VT_ATTRIBUTES, attributes); + } + void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) { + fbb_.AddOffset(Service::VT_DOCUMENTATION, documentation); + } + explicit ServiceBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + flatbuffers::Offset<Service> Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<Service>(end); + fbb_.Required(o, Service::VT_NAME); + return o; + } +}; + +inline flatbuffers::Offset<Service> CreateService( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset<flatbuffers::String> name = 0, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls = 0, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0, - flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { - ServiceBuilder builder_(_fbb); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); - builder_.add_calls(calls); - builder_.add_name(name); - return builder_.Finish(); -} - -inline flatbuffers::Offset<Service> CreateServiceDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, + flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) { + ServiceBuilder builder_(_fbb); + builder_.add_documentation(documentation); + builder_.add_attributes(attributes); + builder_.add_calls(calls); + builder_.add_name(name); + return builder_.Finish(); +} + +inline flatbuffers::Offset<Service> CreateServiceDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, std::vector<flatbuffers::Offset<reflection::RPCCall>> *calls = nullptr, std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr, - const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { + const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) { auto name__ = name ? _fbb.CreateString(name) : 0; auto calls__ = calls ? _fbb.CreateVectorOfSortedTables<reflection::RPCCall>(calls) : 0; auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0; auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0; - return reflection::CreateService( - _fbb, + return reflection::CreateService( + _fbb, name__, calls__, attributes__, documentation__); -} - +} + struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { typedef SchemaBuilder Builder; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_OBJECTS = 4, - VT_ENUMS = 6, - VT_FILE_IDENT = 8, - VT_FILE_EXT = 10, - VT_ROOT_TABLE = 12, + VT_OBJECTS = 4, + VT_ENUMS = 6, + VT_FILE_IDENT = 8, + VT_FILE_EXT = 10, + VT_ROOT_TABLE = 12, VT_SERVICES = 14, VT_ADVANCED_FEATURES = 16 - }; + }; const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *objects() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *>(VT_OBJECTS); - } + } const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *enums() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *>(VT_ENUMS); - } - const flatbuffers::String *file_ident() const { - return GetPointer<const flatbuffers::String *>(VT_FILE_IDENT); - } - const flatbuffers::String *file_ext() const { - return GetPointer<const flatbuffers::String *>(VT_FILE_EXT); - } + } + const flatbuffers::String *file_ident() const { + return GetPointer<const flatbuffers::String *>(VT_FILE_IDENT); + } + const flatbuffers::String *file_ext() const { + return GetPointer<const flatbuffers::String *>(VT_FILE_EXT); + } const reflection::Object *root_table() const { return GetPointer<const reflection::Object *>(VT_ROOT_TABLE); - } + } const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *services() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *>(VT_SERVICES); - } + } reflection::AdvancedFeatures advanced_features() const { return static_cast<reflection::AdvancedFeatures>(GetField<uint64_t>(VT_ADVANCED_FEATURES, 0)); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_OBJECTS) && - verifier.VerifyVector(objects()) && + VerifyOffsetRequired(verifier, VT_OBJECTS) && + verifier.VerifyVector(objects()) && verifier.VerifyVectorOfTables(objects()) && - VerifyOffsetRequired(verifier, VT_ENUMS) && - verifier.VerifyVector(enums()) && + VerifyOffsetRequired(verifier, VT_ENUMS) && + verifier.VerifyVector(enums()) && verifier.VerifyVectorOfTables(enums()) && - VerifyOffset(verifier, VT_FILE_IDENT) && - verifier.VerifyString(file_ident()) && - VerifyOffset(verifier, VT_FILE_EXT) && - verifier.VerifyString(file_ext()) && - VerifyOffset(verifier, VT_ROOT_TABLE) && + VerifyOffset(verifier, VT_FILE_IDENT) && + verifier.VerifyString(file_ident()) && + VerifyOffset(verifier, VT_FILE_EXT) && + verifier.VerifyString(file_ext()) && + VerifyOffset(verifier, VT_ROOT_TABLE) && verifier.VerifyTable(root_table()) && - VerifyOffset(verifier, VT_SERVICES) && - verifier.VerifyVector(services()) && - verifier.VerifyVectorOfTables(services()) && + VerifyOffset(verifier, VT_SERVICES) && + verifier.VerifyVector(services()) && + verifier.VerifyVectorOfTables(services()) && VerifyField<uint64_t>(verifier, VT_ADVANCED_FEATURES) && verifier.EndTable(); } @@ -1152,51 +1152,51 @@ struct SchemaBuilder { flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; void add_objects(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects) { - fbb_.AddOffset(Schema::VT_OBJECTS, objects); - } + fbb_.AddOffset(Schema::VT_OBJECTS, objects); + } void add_enums(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums) { - fbb_.AddOffset(Schema::VT_ENUMS, enums); - } - void add_file_ident(flatbuffers::Offset<flatbuffers::String> file_ident) { - fbb_.AddOffset(Schema::VT_FILE_IDENT, file_ident); - } - void add_file_ext(flatbuffers::Offset<flatbuffers::String> file_ext) { - fbb_.AddOffset(Schema::VT_FILE_EXT, file_ext); - } + fbb_.AddOffset(Schema::VT_ENUMS, enums); + } + void add_file_ident(flatbuffers::Offset<flatbuffers::String> file_ident) { + fbb_.AddOffset(Schema::VT_FILE_IDENT, file_ident); + } + void add_file_ext(flatbuffers::Offset<flatbuffers::String> file_ext) { + fbb_.AddOffset(Schema::VT_FILE_EXT, file_ext); + } void add_root_table(flatbuffers::Offset<reflection::Object> root_table) { - fbb_.AddOffset(Schema::VT_ROOT_TABLE, root_table); - } + fbb_.AddOffset(Schema::VT_ROOT_TABLE, root_table); + } void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services) { - fbb_.AddOffset(Schema::VT_SERVICES, services); - } + fbb_.AddOffset(Schema::VT_SERVICES, services); + } void add_advanced_features(reflection::AdvancedFeatures advanced_features) { fbb_.AddElement<uint64_t>(Schema::VT_ADVANCED_FEATURES, static_cast<uint64_t>(advanced_features), 0); } - explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } + explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } flatbuffers::Offset<Schema> Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset<Schema>(end); - fbb_.Required(o, Schema::VT_OBJECTS); - fbb_.Required(o, Schema::VT_ENUMS); + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset<Schema>(end); + fbb_.Required(o, Schema::VT_OBJECTS); + fbb_.Required(o, Schema::VT_ENUMS); return o; } }; -inline flatbuffers::Offset<Schema> CreateSchema( - flatbuffers::FlatBufferBuilder &_fbb, +inline flatbuffers::Offset<Schema> CreateSchema( + flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects = 0, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums = 0, - flatbuffers::Offset<flatbuffers::String> file_ident = 0, - flatbuffers::Offset<flatbuffers::String> file_ext = 0, + flatbuffers::Offset<flatbuffers::String> file_ident = 0, + flatbuffers::Offset<flatbuffers::String> file_ext = 0, flatbuffers::Offset<reflection::Object> root_table = 0, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services = 0, reflection::AdvancedFeatures advanced_features = static_cast<reflection::AdvancedFeatures>(0)) { SchemaBuilder builder_(_fbb); builder_.add_advanced_features(advanced_features); - builder_.add_services(services); + builder_.add_services(services); builder_.add_root_table(root_table); builder_.add_file_ext(file_ext); builder_.add_file_ident(file_ident); @@ -1205,12 +1205,12 @@ inline flatbuffers::Offset<Schema> CreateSchema( return builder_.Finish(); } -inline flatbuffers::Offset<Schema> CreateSchemaDirect( - flatbuffers::FlatBufferBuilder &_fbb, +inline flatbuffers::Offset<Schema> CreateSchemaDirect( + flatbuffers::FlatBufferBuilder &_fbb, std::vector<flatbuffers::Offset<reflection::Object>> *objects = nullptr, std::vector<flatbuffers::Offset<reflection::Enum>> *enums = nullptr, - const char *file_ident = nullptr, - const char *file_ext = nullptr, + const char *file_ident = nullptr, + const char *file_ext = nullptr, flatbuffers::Offset<reflection::Object> root_table = 0, std::vector<flatbuffers::Offset<reflection::Service>> *services = nullptr, reflection::AdvancedFeatures advanced_features = static_cast<reflection::AdvancedFeatures>(0)) { @@ -1219,60 +1219,60 @@ inline flatbuffers::Offset<Schema> CreateSchemaDirect( auto file_ident__ = file_ident ? _fbb.CreateString(file_ident) : 0; auto file_ext__ = file_ext ? _fbb.CreateString(file_ext) : 0; auto services__ = services ? _fbb.CreateVectorOfSortedTables<reflection::Service>(services) : 0; - return reflection::CreateSchema( - _fbb, + return reflection::CreateSchema( + _fbb, objects__, enums__, file_ident__, file_ext__, - root_table, + root_table, services__, advanced_features); -} - -inline const reflection::Schema *GetSchema(const void *buf) { - return flatbuffers::GetRoot<reflection::Schema>(buf); -} - -inline const reflection::Schema *GetSizePrefixedSchema(const void *buf) { - return flatbuffers::GetSizePrefixedRoot<reflection::Schema>(buf); -} - -inline const char *SchemaIdentifier() { - return "BFBS"; -} - -inline bool SchemaBufferHasIdentifier(const void *buf) { - return flatbuffers::BufferHasIdentifier( - buf, SchemaIdentifier()); -} - -inline bool VerifySchemaBuffer( - flatbuffers::Verifier &verifier) { - return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier()); -} - -inline bool VerifySizePrefixedSchemaBuffer( - flatbuffers::Verifier &verifier) { - return verifier.VerifySizePrefixedBuffer<reflection::Schema>(SchemaIdentifier()); -} - -inline const char *SchemaExtension() { - return "bfbs"; -} - -inline void FinishSchemaBuffer( - flatbuffers::FlatBufferBuilder &fbb, - flatbuffers::Offset<reflection::Schema> root) { - fbb.Finish(root, SchemaIdentifier()); -} - -inline void FinishSizePrefixedSchemaBuffer( - flatbuffers::FlatBufferBuilder &fbb, - flatbuffers::Offset<reflection::Schema> root) { - fbb.FinishSizePrefixed(root, SchemaIdentifier()); -} - +} + +inline const reflection::Schema *GetSchema(const void *buf) { + return flatbuffers::GetRoot<reflection::Schema>(buf); +} + +inline const reflection::Schema *GetSizePrefixedSchema(const void *buf) { + return flatbuffers::GetSizePrefixedRoot<reflection::Schema>(buf); +} + +inline const char *SchemaIdentifier() { + return "BFBS"; +} + +inline bool SchemaBufferHasIdentifier(const void *buf) { + return flatbuffers::BufferHasIdentifier( + buf, SchemaIdentifier()); +} + +inline bool VerifySchemaBuffer( + flatbuffers::Verifier &verifier) { + return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier()); +} + +inline bool VerifySizePrefixedSchemaBuffer( + flatbuffers::Verifier &verifier) { + return verifier.VerifySizePrefixedBuffer<reflection::Schema>(SchemaIdentifier()); +} + +inline const char *SchemaExtension() { + return "bfbs"; +} + +inline void FinishSchemaBuffer( + flatbuffers::FlatBufferBuilder &fbb, + flatbuffers::Offset<reflection::Schema> root) { + fbb.Finish(root, SchemaIdentifier()); +} + +inline void FinishSizePrefixedSchemaBuffer( + flatbuffers::FlatBufferBuilder &fbb, + flatbuffers::Offset<reflection::Schema> root) { + fbb.FinishSizePrefixed(root, SchemaIdentifier()); +} + } // namespace reflection #endif // FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/registry.h b/contrib/libs/flatbuffers/include/flatbuffers/registry.h index a313d257f0..30a0016dcb 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/registry.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/registry.h @@ -1,127 +1,127 @@ -/* - * 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_REGISTRY_H_ -#define FLATBUFFERS_REGISTRY_H_ - +/* + * 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_REGISTRY_H_ +#define FLATBUFFERS_REGISTRY_H_ + #include "idl.h" - -namespace flatbuffers { - -// Convenience class to easily parse or generate text for arbitrary FlatBuffers. -// Simply pre-populate it with all schema filenames that may be in use, and -// This class will look them up using the file_identifier declared in the -// schema. -class Registry { - public: - // Call this for all schemas that may be in use. The identifier has - // a function in the generated code, e.g. MonsterIdentifier(). - void Register(const char *file_identifier, const char *schema_path) { - Schema schema; - schema.path_ = schema_path; - schemas_[file_identifier] = schema; - } - - // Generate text from an arbitrary FlatBuffer by looking up its - // file_identifier in the registry. - bool FlatBufferToText(const uint8_t *flatbuf, size_t len, std::string *dest) { - // Get the identifier out of the buffer. - // If the buffer is truncated, exit. - if (len < sizeof(uoffset_t) + FlatBufferBuilder::kFileIdentifierLength) { - lasterror_ = "buffer truncated"; - return false; - } - std::string ident( - reinterpret_cast<const char *>(flatbuf) + sizeof(uoffset_t), - FlatBufferBuilder::kFileIdentifierLength); - // Load and parse the schema. - Parser parser; - if (!LoadSchema(ident, &parser)) return false; - // Now we're ready to generate text. - if (!GenerateText(parser, flatbuf, dest)) { - lasterror_ = "unable to generate text for FlatBuffer binary"; - return false; - } - return true; - } - - // Converts a binary buffer to text using one of the schemas in the registry, - // use the file_identifier to indicate which. - // If DetachedBuffer::data() is null then parsing failed. - DetachedBuffer TextToFlatBuffer(const char *text, - const char *file_identifier) { - // Load and parse the schema. - Parser parser; - if (!LoadSchema(file_identifier, &parser)) return DetachedBuffer(); - // Parse the text. - if (!parser.Parse(text)) { - lasterror_ = parser.error_; - return DetachedBuffer(); - } - // We have a valid FlatBuffer. Detach it from the builder and return. + +namespace flatbuffers { + +// Convenience class to easily parse or generate text for arbitrary FlatBuffers. +// Simply pre-populate it with all schema filenames that may be in use, and +// This class will look them up using the file_identifier declared in the +// schema. +class Registry { + public: + // Call this for all schemas that may be in use. The identifier has + // a function in the generated code, e.g. MonsterIdentifier(). + void Register(const char *file_identifier, const char *schema_path) { + Schema schema; + schema.path_ = schema_path; + schemas_[file_identifier] = schema; + } + + // Generate text from an arbitrary FlatBuffer by looking up its + // file_identifier in the registry. + bool FlatBufferToText(const uint8_t *flatbuf, size_t len, std::string *dest) { + // Get the identifier out of the buffer. + // If the buffer is truncated, exit. + if (len < sizeof(uoffset_t) + FlatBufferBuilder::kFileIdentifierLength) { + lasterror_ = "buffer truncated"; + return false; + } + std::string ident( + reinterpret_cast<const char *>(flatbuf) + sizeof(uoffset_t), + FlatBufferBuilder::kFileIdentifierLength); + // Load and parse the schema. + Parser parser; + if (!LoadSchema(ident, &parser)) return false; + // Now we're ready to generate text. + if (!GenerateText(parser, flatbuf, dest)) { + lasterror_ = "unable to generate text for FlatBuffer binary"; + return false; + } + return true; + } + + // Converts a binary buffer to text using one of the schemas in the registry, + // use the file_identifier to indicate which. + // If DetachedBuffer::data() is null then parsing failed. + DetachedBuffer TextToFlatBuffer(const char *text, + const char *file_identifier) { + // Load and parse the schema. + Parser parser; + if (!LoadSchema(file_identifier, &parser)) return DetachedBuffer(); + // Parse the text. + if (!parser.Parse(text)) { + lasterror_ = parser.error_; + return DetachedBuffer(); + } + // We have a valid FlatBuffer. Detach it from the builder and return. return parser.builder_.Release(); - } - - // Modify any parsing / output options used by the other functions. - void SetOptions(const IDLOptions &opts) { opts_ = opts; } - - // If schemas used contain include statements, call this function for every - // directory the parser should search them for. - void AddIncludeDirectory(const char *path) { include_paths_.push_back(path); } - - // Returns a human readable error if any of the above functions fail. - const std::string &GetLastError() { return lasterror_; } - - private: - bool LoadSchema(const std::string &ident, Parser *parser) { - // Find the schema, if not, exit. - auto it = schemas_.find(ident); - if (it == schemas_.end()) { - // Don't attach the identifier, since it may not be human readable. - lasterror_ = "identifier for this buffer not in the registry"; - return false; - } - auto &schema = it->second; - // Load the schema from disk. If not, exit. - std::string schematext; - if (!LoadFile(schema.path_.c_str(), false, &schematext)) { - lasterror_ = "could not load schema: " + schema.path_; - return false; - } - // Parse schema. - parser->opts = opts_; - if (!parser->Parse(schematext.c_str(), vector_data(include_paths_), - schema.path_.c_str())) { - lasterror_ = parser->error_; - return false; - } - return true; - } - - struct Schema { - std::string path_; - // TODO(wvo) optionally cache schema file or parsed schema here. - }; - - std::string lasterror_; - IDLOptions opts_; - std::vector<const char *> include_paths_; - std::map<std::string, Schema> schemas_; -}; - -} // namespace flatbuffers - -#endif // FLATBUFFERS_REGISTRY_H_ + } + + // Modify any parsing / output options used by the other functions. + void SetOptions(const IDLOptions &opts) { opts_ = opts; } + + // If schemas used contain include statements, call this function for every + // directory the parser should search them for. + void AddIncludeDirectory(const char *path) { include_paths_.push_back(path); } + + // Returns a human readable error if any of the above functions fail. + const std::string &GetLastError() { return lasterror_; } + + private: + bool LoadSchema(const std::string &ident, Parser *parser) { + // Find the schema, if not, exit. + auto it = schemas_.find(ident); + if (it == schemas_.end()) { + // Don't attach the identifier, since it may not be human readable. + lasterror_ = "identifier for this buffer not in the registry"; + return false; + } + auto &schema = it->second; + // Load the schema from disk. If not, exit. + std::string schematext; + if (!LoadFile(schema.path_.c_str(), false, &schematext)) { + lasterror_ = "could not load schema: " + schema.path_; + return false; + } + // Parse schema. + parser->opts = opts_; + if (!parser->Parse(schematext.c_str(), vector_data(include_paths_), + schema.path_.c_str())) { + lasterror_ = parser->error_; + return false; + } + return true; + } + + struct Schema { + std::string path_; + // TODO(wvo) optionally cache schema file or parsed schema here. + }; + + std::string lasterror_; + IDLOptions opts_; + std::vector<const char *> include_paths_; + std::map<std::string, Schema> schemas_; +}; + +} // namespace flatbuffers + +#endif // FLATBUFFERS_REGISTRY_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/stl_emulation.h b/contrib/libs/flatbuffers/include/flatbuffers/stl_emulation.h index d84aecea8e..e8e1e59487 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/stl_emulation.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/stl_emulation.h @@ -1,39 +1,39 @@ -/* - * 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 +/* + * 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 "base.h" - -#include <string> -#include <type_traits> -#include <vector> -#include <memory> -#include <limits> - -#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 <cctype> -#endif // defined(FLATBUFFERS_CPP98_STL) - + +#include <string> +#include <type_traits> +#include <vector> +#include <memory> +#include <limits> + +#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 <cctype> +#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) \ @@ -62,52 +62,52 @@ #include <array> #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 <typename T> inline T *vector_data(std::vector<T> &vector) { - // In some debug environments, operator[] does bounds checking, so &vector[0] - // can't be used. - return vector.empty() ? nullptr : &vector[0]; -} - -template <typename T> inline const T *vector_data( - const std::vector<T> &vector) { - return vector.empty() ? nullptr : &vector[0]; -} - -template <typename T, typename V> -inline void vector_emplace_back(std::vector<T> *vector, V &&data) { - #if defined(FLATBUFFERS_CPP98_STL) - vector->push_back(data); - #else - vector->emplace_back(std::forward<V>(data)); - #endif // defined(FLATBUFFERS_CPP98_STL) -} - -#ifndef FLATBUFFERS_CPP98_STL - #if defined(FLATBUFFERS_TEMPLATES_ALIASES) - template <typename T> - using numeric_limits = std::numeric_limits<T>; - #else - template <typename T> class numeric_limits : - public std::numeric_limits<T> {}; - #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) -#else - template <typename T> class numeric_limits : + +// 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 <typename T> inline T *vector_data(std::vector<T> &vector) { + // In some debug environments, operator[] does bounds checking, so &vector[0] + // can't be used. + return vector.empty() ? nullptr : &vector[0]; +} + +template <typename T> inline const T *vector_data( + const std::vector<T> &vector) { + return vector.empty() ? nullptr : &vector[0]; +} + +template <typename T, typename V> +inline void vector_emplace_back(std::vector<T> *vector, V &&data) { + #if defined(FLATBUFFERS_CPP98_STL) + vector->push_back(data); + #else + vector->emplace_back(std::forward<V>(data)); + #endif // defined(FLATBUFFERS_CPP98_STL) +} + +#ifndef FLATBUFFERS_CPP98_STL + #if defined(FLATBUFFERS_TEMPLATES_ALIASES) + template <typename T> + using numeric_limits = std::numeric_limits<T>; + #else + template <typename T> class numeric_limits : + public std::numeric_limits<T> {}; + #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) +#else + template <typename T> class numeric_limits : public std::numeric_limits<T> { public: // Android NDK fix. @@ -115,7 +115,7 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) { return std::numeric_limits<T>::min(); } }; - + template <> class numeric_limits<float> : public std::numeric_limits<float> { public: @@ -128,36 +128,36 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) { static double lowest() { return -DBL_MAX; } }; - template <> class numeric_limits<unsigned long long> { - public: - static unsigned long long min() { return 0ULL; } - static unsigned long long max() { return ~0ULL; } + template <> class numeric_limits<unsigned long long> { + public: + static unsigned long long min() { return 0ULL; } + static unsigned long long max() { return ~0ULL; } static unsigned long long lowest() { return numeric_limits<unsigned long long>::min(); } - }; - - template <> class numeric_limits<long long> { - public: - static long long min() { - return static_cast<long long>(1ULL << ((sizeof(long long) << 3) - 1)); - } - static long long max() { - return static_cast<long long>( - (1ULL << ((sizeof(long long) << 3) - 1)) - 1); - } + }; + + template <> class numeric_limits<long long> { + public: + static long long min() { + return static_cast<long long>(1ULL << ((sizeof(long long) << 3) - 1)); + } + static long long max() { + return static_cast<long long>( + (1ULL << ((sizeof(long long) << 3) - 1)) - 1); + } static long long lowest() { return numeric_limits<long long>::min(); } - }; -#endif // FLATBUFFERS_CPP98_STL - -#if defined(FLATBUFFERS_TEMPLATES_ALIASES) - #ifndef FLATBUFFERS_CPP98_STL - template <typename T> using is_scalar = std::is_scalar<T>; - template <typename T, typename U> using is_same = std::is_same<T,U>; - template <typename T> using is_floating_point = std::is_floating_point<T>; - template <typename T> using is_unsigned = std::is_unsigned<T>; + }; +#endif // FLATBUFFERS_CPP98_STL + +#if defined(FLATBUFFERS_TEMPLATES_ALIASES) + #ifndef FLATBUFFERS_CPP98_STL + template <typename T> using is_scalar = std::is_scalar<T>; + template <typename T, typename U> using is_same = std::is_same<T,U>; + template <typename T> using is_floating_point = std::is_floating_point<T>; + template <typename T> using is_unsigned = std::is_unsigned<T>; template <typename T> using is_enum = std::is_enum<T>; template <typename T> using make_unsigned = std::make_unsigned<T>; template<bool B, class T, class F> @@ -166,13 +166,13 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) { using integral_constant = std::integral_constant<T, v>; template <bool B> using bool_constant = integral_constant<bool, B>; - #else - // Map C++ TR1 templates defined by stlport. - template <typename T> using is_scalar = std::tr1::is_scalar<T>; - template <typename T, typename U> using is_same = std::tr1::is_same<T,U>; - template <typename T> using is_floating_point = - std::tr1::is_floating_point<T>; - template <typename T> using is_unsigned = std::tr1::is_unsigned<T>; + #else + // Map C++ TR1 templates defined by stlport. + template <typename T> using is_scalar = std::tr1::is_scalar<T>; + template <typename T, typename U> using is_same = std::tr1::is_same<T,U>; + template <typename T> using is_floating_point = + std::tr1::is_floating_point<T>; + template <typename T> using is_unsigned = std::tr1::is_unsigned<T>; template <typename T> using is_enum = std::tr1::is_enum<T>; // Android NDK doesn't have std::make_unsigned or std::tr1::make_unsigned. template<typename T> struct make_unsigned { @@ -191,14 +191,14 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) { using integral_constant = std::tr1::integral_constant<T, v>; template <bool B> using bool_constant = integral_constant<bool, B>; - #endif // !FLATBUFFERS_CPP98_STL -#else - // MSVC 2010 doesn't support C++11 aliases. - template <typename T> struct is_scalar : public std::is_scalar<T> {}; - template <typename T, typename U> struct is_same : public std::is_same<T,U> {}; - template <typename T> struct is_floating_point : - public std::is_floating_point<T> {}; - template <typename T> struct is_unsigned : public std::is_unsigned<T> {}; + #endif // !FLATBUFFERS_CPP98_STL +#else + // MSVC 2010 doesn't support C++11 aliases. + template <typename T> struct is_scalar : public std::is_scalar<T> {}; + template <typename T, typename U> struct is_same : public std::is_same<T,U> {}; + template <typename T> struct is_floating_point : + public std::is_floating_point<T> {}; + template <typename T> struct is_unsigned : public std::is_unsigned<T> {}; template <typename T> struct is_enum : public std::is_enum<T> {}; template <typename T> struct make_unsigned : public std::make_unsigned<T> {}; template<bool B, class T, class F> @@ -207,108 +207,108 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) { struct integral_constant : public std::integral_constant<T, v> {}; template <bool B> struct bool_constant : public integral_constant<bool, B> {}; -#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) - -#ifndef FLATBUFFERS_CPP98_STL - #if defined(FLATBUFFERS_TEMPLATES_ALIASES) - template <class T> using unique_ptr = std::unique_ptr<T>; - #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 +#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) + +#ifndef FLATBUFFERS_CPP98_STL + #if defined(FLATBUFFERS_TEMPLATES_ALIASES) + template <class T> using unique_ptr = std::unique_ptr<T>; + #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 T> class unique_ptr : public std::unique_ptr<T> { - public: - unique_ptr() {} - explicit unique_ptr(T* p) : std::unique_ptr<T>(p) {} - unique_ptr(std::unique_ptr<T>&& u) { *this = std::move(u); } - unique_ptr(unique_ptr&& u) { *this = std::move(u); } - unique_ptr& operator=(std::unique_ptr<T>&& u) { - std::unique_ptr<T>::reset(u.release()); - return *this; - } - unique_ptr& operator=(unique_ptr&& u) { - std::unique_ptr<T>::reset(u.release()); - return *this; - } - unique_ptr& operator=(T* p) { - return std::unique_ptr<T>::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 T> 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<unique_ptr*>(&u)->release()); - } - ~unique_ptr() { reset(); } - - unique_ptr& operator=(const unique_ptr& u) { - reset(const_cast<unique_ptr*>(&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 <class T> bool operator==(const unique_ptr<T>& x, - const unique_ptr<T>& y) { - return x.get() == y.get(); - } - - template <class T, class D> bool operator==(const unique_ptr<T>& x, - const D* y) { - return static_cast<D*>(x.get()) == y; - } - - template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) { - return reinterpret_cast<intptr_t>(x.get()) == y; - } + // for C++98 STL implementations. + template <class T> class unique_ptr : public std::unique_ptr<T> { + public: + unique_ptr() {} + explicit unique_ptr(T* p) : std::unique_ptr<T>(p) {} + unique_ptr(std::unique_ptr<T>&& u) { *this = std::move(u); } + unique_ptr(unique_ptr&& u) { *this = std::move(u); } + unique_ptr& operator=(std::unique_ptr<T>&& u) { + std::unique_ptr<T>::reset(u.release()); + return *this; + } + unique_ptr& operator=(unique_ptr&& u) { + std::unique_ptr<T>::reset(u.release()); + return *this; + } + unique_ptr& operator=(T* p) { + return std::unique_ptr<T>::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 T> 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<unique_ptr*>(&u)->release()); + } + ~unique_ptr() { reset(); } + + unique_ptr& operator=(const unique_ptr& u) { + reset(const_cast<unique_ptr*>(&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 <class T> bool operator==(const unique_ptr<T>& x, + const unique_ptr<T>& y) { + return x.get() == y.get(); + } + + template <class T, class D> bool operator==(const unique_ptr<T>& x, + const D* y) { + return static_cast<D*>(x.get()) == y; + } + + template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) { + return reinterpret_cast<intptr_t>(x.get()) == y; + } template <class T> bool operator!=(const unique_ptr<T>& x, decltype(nullptr)) { return !!x; @@ -326,8 +326,8 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) { return !x; } -#endif // !FLATBUFFERS_CPP98_STL - +#endif // !FLATBUFFERS_CPP98_STL + #ifdef FLATBUFFERS_USE_STD_OPTIONAL template<class T> using Optional = std::optional<T>; @@ -668,6 +668,6 @@ class span FLATBUFFERS_FINAL_CLASS { #endif // defined(FLATBUFFERS_USE_STD_SPAN) -} // namespace flatbuffers - -#endif // FLATBUFFERS_STL_EMULATION_H_ +} // namespace flatbuffers + +#endif // FLATBUFFERS_STL_EMULATION_H_ diff --git a/contrib/libs/flatbuffers/include/flatbuffers/util.h b/contrib/libs/flatbuffers/include/flatbuffers/util.h index 0501a6df66..4493c561c2 100644 --- a/contrib/libs/flatbuffers/include/flatbuffers/util.h +++ b/contrib/libs/flatbuffers/include/flatbuffers/util.h @@ -22,11 +22,11 @@ #include "base.h" #include "stl_emulation.h" -#ifndef FLATBUFFERS_PREFER_PRINTF -# include <sstream> +#ifndef FLATBUFFERS_PREFER_PRINTF +# include <sstream> #else // FLATBUFFERS_PREFER_PRINTF -# include <float.h> -# include <stdio.h> +# include <float.h> +# include <stdio.h> #endif // FLATBUFFERS_PREFER_PRINTF #include <iomanip> @@ -86,54 +86,54 @@ inline char CharToLower(char c) { // @end-locale-independent functions for ASCII character set -#ifdef FLATBUFFERS_PREFER_PRINTF -template<typename T> size_t IntToDigitCount(T t) { - size_t digit_count = 0; - // Count the sign for negative numbers - if (t < 0) digit_count++; - // Count a single 0 left of the dot for fractional numbers - if (-1 < t && t < 1) digit_count++; - // Count digits until fractional part - T eps = std::numeric_limits<float>::epsilon(); - while (t <= (-1 + eps) || (1 - eps) <= t) { - t /= 10; - digit_count++; - } - return digit_count; -} - -template<typename T> size_t NumToStringWidth(T t, int precision = 0) { - size_t string_width = IntToDigitCount(t); - // Count the dot for floating point numbers - if (precision) string_width += (precision + 1); - return string_width; -} - +#ifdef FLATBUFFERS_PREFER_PRINTF +template<typename T> size_t IntToDigitCount(T t) { + size_t digit_count = 0; + // Count the sign for negative numbers + if (t < 0) digit_count++; + // Count a single 0 left of the dot for fractional numbers + if (-1 < t && t < 1) digit_count++; + // Count digits until fractional part + T eps = std::numeric_limits<float>::epsilon(); + while (t <= (-1 + eps) || (1 - eps) <= t) { + t /= 10; + digit_count++; + } + return digit_count; +} + +template<typename T> size_t NumToStringWidth(T t, int precision = 0) { + size_t string_width = IntToDigitCount(t); + // Count the dot for floating point numbers + if (precision) string_width += (precision + 1); + return string_width; +} + template<typename T> std::string NumToStringImplWrapper(T t, const char *fmt, int precision = 0) { - size_t string_width = NumToStringWidth(t, precision); - std::string s(string_width, 0x00); - // Allow snprintf to use std::string trailing null to detect buffer overflow + size_t string_width = NumToStringWidth(t, precision); + std::string s(string_width, 0x00); + // Allow snprintf to use std::string trailing null to detect buffer overflow snprintf(const_cast<char *>(s.data()), (s.size() + 1), fmt, string_width, t); - return s; -} + return s; +} #endif // FLATBUFFERS_PREFER_PRINTF - + // Convert an integer or floating point value to a string. // In contrast to std::stringstream, "char" values are // converted to a string of digits, and we don't use scientific notation. template<typename T> std::string NumToString(T t) { - // clang-format off - - #ifndef FLATBUFFERS_PREFER_PRINTF - std::stringstream ss; - ss << t; - return ss.str(); - #else // FLATBUFFERS_PREFER_PRINTF - auto v = static_cast<long long>(t); - return NumToStringImplWrapper(v, "%.*lld"); - #endif // FLATBUFFERS_PREFER_PRINTF - // clang-format on + // clang-format off + + #ifndef FLATBUFFERS_PREFER_PRINTF + std::stringstream ss; + ss << t; + return ss.str(); + #else // FLATBUFFERS_PREFER_PRINTF + auto v = static_cast<long long>(t); + return NumToStringImplWrapper(v, "%.*lld"); + #endif // FLATBUFFERS_PREFER_PRINTF + // clang-format on } // Avoid char types used as character data. template<> inline std::string NumToString<signed char>(signed char t) { @@ -145,54 +145,54 @@ template<> inline std::string NumToString<unsigned char>(unsigned char t) { template<> inline std::string NumToString<char>(char t) { return NumToString(static_cast<int>(t)); } -#if defined(FLATBUFFERS_CPP98_STL) -template<> inline std::string NumToString<long long>(long long t) { - char buf[21]; // (log((1 << 63) - 1) / log(10)) + 2 - snprintf(buf, sizeof(buf), "%lld", t); - return std::string(buf); -} - -template<> -inline std::string NumToString<unsigned long long>(unsigned long long t) { - char buf[22]; // (log((1 << 63) - 1) / log(10)) + 1 - snprintf(buf, sizeof(buf), "%llu", t); - return std::string(buf); -} -#endif // defined(FLATBUFFERS_CPP98_STL) - +#if defined(FLATBUFFERS_CPP98_STL) +template<> inline std::string NumToString<long long>(long long t) { + char buf[21]; // (log((1 << 63) - 1) / log(10)) + 2 + snprintf(buf, sizeof(buf), "%lld", t); + return std::string(buf); +} + +template<> +inline std::string NumToString<unsigned long long>(unsigned long long t) { + char buf[22]; // (log((1 << 63) - 1) / log(10)) + 1 + snprintf(buf, sizeof(buf), "%llu", t); + return std::string(buf); +} +#endif // defined(FLATBUFFERS_CPP98_STL) + // Special versions for floats/doubles. -template<typename T> std::string FloatToString(T t, int precision) { - // clang-format off - - #ifndef FLATBUFFERS_PREFER_PRINTF - // to_string() prints different numbers of digits for floats depending on - // platform and isn't available on Android, so we use stringstream - std::stringstream ss; - // Use std::fixed to suppress scientific notation. - ss << std::fixed; - // Default precision is 6, we want that to be higher for doubles. - ss << std::setprecision(precision); - ss << t; - auto s = ss.str(); - #else // FLATBUFFERS_PREFER_PRINTF - auto v = static_cast<double>(t); - auto s = NumToStringImplWrapper(v, "%0.*f", precision); - #endif // FLATBUFFERS_PREFER_PRINTF - // clang-format on +template<typename T> std::string FloatToString(T t, int precision) { + // clang-format off + + #ifndef FLATBUFFERS_PREFER_PRINTF + // to_string() prints different numbers of digits for floats depending on + // platform and isn't available on Android, so we use stringstream + std::stringstream ss; + // Use std::fixed to suppress scientific notation. + ss << std::fixed; + // Default precision is 6, we want that to be higher for doubles. + ss << std::setprecision(precision); + ss << t; + auto s = ss.str(); + #else // FLATBUFFERS_PREFER_PRINTF + auto v = static_cast<double>(t); + auto s = NumToStringImplWrapper(v, "%0.*f", precision); + #endif // FLATBUFFERS_PREFER_PRINTF + // clang-format on // Sadly, std::fixed turns "1" into "1.00000", so here we undo that. auto p = s.find_last_not_of('0'); if (p != std::string::npos) { - // Strip trailing zeroes. If it is a whole number, keep one zero. - s.resize(p + (s[p] == '.' ? 2 : 1)); + // Strip trailing zeroes. If it is a whole number, keep one zero. + s.resize(p + (s[p] == '.' ? 2 : 1)); } return s; } - -template<> inline std::string NumToString<double>(double t) { - return FloatToString(t, 12); -} + +template<> inline std::string NumToString<double>(double t) { + return FloatToString(t, 12); +} template<> inline std::string NumToString<float>(float t) { - return FloatToString(t, 6); + return FloatToString(t, 6); } // Convert an integer value to a hexadecimal string. @@ -200,17 +200,17 @@ template<> inline std::string NumToString<float>(float t) { // For example, IntToStringHex(0x23, 8) returns the string "00000023". inline std::string IntToStringHex(int i, int xdigits) { FLATBUFFERS_ASSERT(i >= 0); - // clang-format off - - #ifndef FLATBUFFERS_PREFER_PRINTF - std::stringstream ss; - ss << std::setw(xdigits) << std::setfill('0') << std::hex << std::uppercase - << i; - return ss.str(); - #else // FLATBUFFERS_PREFER_PRINTF - return NumToStringImplWrapper(i, "%.*X", xdigits); - #endif // FLATBUFFERS_PREFER_PRINTF - // clang-format on + // clang-format off + + #ifndef FLATBUFFERS_PREFER_PRINTF + std::stringstream ss; + ss << std::setw(xdigits) << std::setfill('0') << std::hex << std::uppercase + << i; + return ss.str(); + #else // FLATBUFFERS_PREFER_PRINTF + return NumToStringImplWrapper(i, "%.*X", xdigits); + #endif // FLATBUFFERS_PREFER_PRINTF + // clang-format on } // clang-format off @@ -405,26 +405,26 @@ inline uint64_t StringToUInt(const char *s, int base = 10) { return StringToIntegerImpl(&val, s, base) ? val : 0; } -typedef bool (*LoadFileFunction)(const char *filename, bool binary, - std::string *dest); -typedef bool (*FileExistsFunction)(const char *filename); - -LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function); - -FileExistsFunction SetFileExistsFunction( - FileExistsFunction file_exists_function); - +typedef bool (*LoadFileFunction)(const char *filename, bool binary, + std::string *dest); +typedef bool (*FileExistsFunction)(const char *filename); + +LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function); + +FileExistsFunction SetFileExistsFunction( + FileExistsFunction file_exists_function); + // Check if file "name" exists. -bool FileExists(const char *name); +bool FileExists(const char *name); + +// Check if "name" exists and it is also a directory. +bool DirExists(const char *name); -// Check if "name" exists and it is also a directory. -bool DirExists(const char *name); - // Load file "name" into "buf" returning true if successful // false otherwise. If "binary" is false data is read // using ifstream's text mode, otherwise data is read with // no transcoding. -bool LoadFile(const char *name, bool binary, std::string *buf); +bool LoadFile(const char *name, bool binary, std::string *buf); // Save data "buf" of length "len" bytes into a file // "name" returning true if successful, false otherwise. @@ -441,14 +441,14 @@ inline bool SaveFile(const char *name, const std::string &buf, bool binary) { return SaveFile(name, buf.c_str(), buf.size(), binary); } -// Functionality for minimalistic portable path handling. +// Functionality for minimalistic portable path handling. -// The functions below behave correctly regardless of whether posix ('/') or -// Windows ('/' or '\\') separators are used. - -// Any new separators inserted are always posix. +// The functions below behave correctly regardless of whether posix ('/') or +// Windows ('/' or '\\') separators are used. + +// Any new separators inserted are always posix. FLATBUFFERS_CONSTEXPR char kPathSeparator = '/'; - + // Returns the path with the extension, if any, removed. std::string StripExtension(const std::string &filepath); @@ -466,9 +466,9 @@ std::string StripFileName(const std::string &filepath); std::string ConCatPathFileName(const std::string &path, const std::string &filename); -// Replaces any '\\' separators with '/' +// Replaces any '\\' separators with '/' std::string PosixPath(const char *path); - + // This function ensure a directory exists, by recursively // creating dirs for any parts of the path that don't exist yet. void EnsureDirExists(const std::string &filepath); @@ -482,7 +482,7 @@ std::string AbsolutePath(const std::string &filepath); // Convert a unicode code point into a UTF-8 representation by appending it // to a string. Returns the number of bytes generated. inline int ToUTF8(uint32_t ucc, std::string *out) { - FLATBUFFERS_ASSERT(!(ucc & 0x80000000)); // Top bit can't be set. + FLATBUFFERS_ASSERT(!(ucc & 0x80000000)); // Top bit can't be set. // 6 possible encodings: http://en.wikipedia.org/wiki/UTF-8 for (int i = 0; i < 6; i++) { // Max bits this encoding can represent. @@ -492,7 +492,7 @@ inline int ToUTF8(uint32_t ucc, std::string *out) { uint32_t remain_bits = i * 6; // Store first byte: (*out) += static_cast<char>((0xFE << (max_bits - remain_bits)) | - (ucc >> remain_bits)); + (ucc >> remain_bits)); // Store remaining bytes: for (int j = i - 1; j >= 0; j--) { (*out) += static_cast<char>(((ucc >> (j * 6)) & 0x3F) | 0x80); @@ -500,7 +500,7 @@ inline int ToUTF8(uint32_t ucc, std::string *out) { return i + 1; // Return the number of bytes added. } } - FLATBUFFERS_ASSERT(0); // Impossible to arrive here. + FLATBUFFERS_ASSERT(0); // Impossible to arrive here. return -1; } @@ -522,8 +522,8 @@ inline int FromUTF8(const char **in) { if ((static_cast<unsigned char>(**in) << len) & 0x80) return -1; // Bit after leading 1's must be 0. if (!len) return *(*in)++; - // UTF-8 encoded values with a length are between 2 and 4 bytes. - if (len < 2 || len > 4) { return -1; } + // UTF-8 encoded values with a length are between 2 and 4 bytes. + if (len < 2 || len > 4) { return -1; } // Grab initial bits of the code. int ucc = *(*in)++ & ((1 << (7 - len)) - 1); for (int i = 0; i < len - 1; i++) { @@ -531,28 +531,28 @@ inline int FromUTF8(const char **in) { ucc <<= 6; ucc |= *(*in)++ & 0x3F; // Grab 6 more bits of the code. } - // UTF-8 cannot encode values between 0xD800 and 0xDFFF (reserved for - // UTF-16 surrogate pairs). - if (ucc >= 0xD800 && ucc <= 0xDFFF) { return -1; } - // UTF-8 must represent code points in their shortest possible encoding. - switch (len) { - case 2: - // Two bytes of UTF-8 can represent code points from U+0080 to U+07FF. - if (ucc < 0x0080 || ucc > 0x07FF) { return -1; } - break; - case 3: - // Three bytes of UTF-8 can represent code points from U+0800 to U+FFFF. - if (ucc < 0x0800 || ucc > 0xFFFF) { return -1; } - break; - case 4: - // Four bytes of UTF-8 can represent code points from U+10000 to U+10FFFF. - if (ucc < 0x10000 || ucc > 0x10FFFF) { return -1; } - break; - } + // UTF-8 cannot encode values between 0xD800 and 0xDFFF (reserved for + // UTF-16 surrogate pairs). + if (ucc >= 0xD800 && ucc <= 0xDFFF) { return -1; } + // UTF-8 must represent code points in their shortest possible encoding. + switch (len) { + case 2: + // Two bytes of UTF-8 can represent code points from U+0080 to U+07FF. + if (ucc < 0x0080 || ucc > 0x07FF) { return -1; } + break; + case 3: + // Three bytes of UTF-8 can represent code points from U+0800 to U+FFFF. + if (ucc < 0x0800 || ucc > 0xFFFF) { return -1; } + break; + case 4: + // Four bytes of UTF-8 can represent code points from U+10000 to U+10FFFF. + if (ucc < 0x10000 || ucc > 0x10FFFF) { return -1; } + break; + } return ucc; } -#ifndef FLATBUFFERS_PREFER_PRINTF +#ifndef FLATBUFFERS_PREFER_PRINTF // Wraps a string to a maximum length, inserting new lines where necessary. Any // existing whitespace will be collapsed down to a single space. A prefix or // suffix can be provided, which will be inserted before or after a wrapped @@ -581,76 +581,76 @@ inline std::string WordWrap(const std::string in, size_t max_length, } #endif // !FLATBUFFERS_PREFER_PRINTF -inline bool EscapeString(const char *s, size_t length, std::string *_text, - bool allow_non_utf8, bool natural_utf8) { - std::string &text = *_text; - text += "\""; - for (uoffset_t i = 0; i < length; i++) { - char c = s[i]; - switch (c) { - case '\n': text += "\\n"; break; - case '\t': text += "\\t"; break; - case '\r': text += "\\r"; break; - case '\b': text += "\\b"; break; - case '\f': text += "\\f"; break; - case '\"': text += "\\\""; break; - case '\\': text += "\\\\"; break; - default: - if (c >= ' ' && c <= '~') { - text += c; - } else { - // Not printable ASCII data. Let's see if it's valid UTF-8 first: - const char *utf8 = s + i; - int ucc = FromUTF8(&utf8); - if (ucc < 0) { - if (allow_non_utf8) { - text += "\\x"; - text += IntToStringHex(static_cast<uint8_t>(c), 2); - } else { - // There are two cases here: - // - // 1) We reached here by parsing an IDL file. In that case, - // we previously checked for non-UTF-8, so we shouldn't reach - // here. - // - // 2) We reached here by someone calling GenerateText() - // on a previously-serialized flatbuffer. The data might have - // non-UTF-8 Strings, or might be corrupt. - // - // In both cases, we have to give up and inform the caller - // they have no JSON. - return false; - } - } else { - if (natural_utf8) { - // utf8 points to past all utf-8 bytes parsed - text.append(s + i, static_cast<size_t>(utf8 - s - i)); - } else if (ucc <= 0xFFFF) { - // Parses as Unicode within JSON's \uXXXX range, so use that. - text += "\\u"; - text += IntToStringHex(ucc, 4); - } else if (ucc <= 0x10FFFF) { - // Encode Unicode SMP values to a surrogate pair using two \u - // escapes. - uint32_t base = ucc - 0x10000; - auto high_surrogate = (base >> 10) + 0xD800; - auto low_surrogate = (base & 0x03FF) + 0xDC00; - text += "\\u"; - text += IntToStringHex(high_surrogate, 4); - text += "\\u"; - text += IntToStringHex(low_surrogate, 4); - } - // Skip past characters recognized. - i = static_cast<uoffset_t>(utf8 - s - 1); - } - } - break; - } - } - text += "\""; - return true; -} - +inline bool EscapeString(const char *s, size_t length, std::string *_text, + bool allow_non_utf8, bool natural_utf8) { + std::string &text = *_text; + text += "\""; + for (uoffset_t i = 0; i < length; i++) { + char c = s[i]; + switch (c) { + case '\n': text += "\\n"; break; + case '\t': text += "\\t"; break; + case '\r': text += "\\r"; break; + case '\b': text += "\\b"; break; + case '\f': text += "\\f"; break; + case '\"': text += "\\\""; break; + case '\\': text += "\\\\"; break; + default: + if (c >= ' ' && c <= '~') { + text += c; + } else { + // Not printable ASCII data. Let's see if it's valid UTF-8 first: + const char *utf8 = s + i; + int ucc = FromUTF8(&utf8); + if (ucc < 0) { + if (allow_non_utf8) { + text += "\\x"; + text += IntToStringHex(static_cast<uint8_t>(c), 2); + } else { + // There are two cases here: + // + // 1) We reached here by parsing an IDL file. In that case, + // we previously checked for non-UTF-8, so we shouldn't reach + // here. + // + // 2) We reached here by someone calling GenerateText() + // on a previously-serialized flatbuffer. The data might have + // non-UTF-8 Strings, or might be corrupt. + // + // In both cases, we have to give up and inform the caller + // they have no JSON. + return false; + } + } else { + if (natural_utf8) { + // utf8 points to past all utf-8 bytes parsed + text.append(s + i, static_cast<size_t>(utf8 - s - i)); + } else if (ucc <= 0xFFFF) { + // Parses as Unicode within JSON's \uXXXX range, so use that. + text += "\\u"; + text += IntToStringHex(ucc, 4); + } else if (ucc <= 0x10FFFF) { + // Encode Unicode SMP values to a surrogate pair using two \u + // escapes. + uint32_t base = ucc - 0x10000; + auto high_surrogate = (base >> 10) + 0xD800; + auto low_surrogate = (base & 0x03FF) + 0xDC00; + text += "\\u"; + text += IntToStringHex(high_surrogate, 4); + text += "\\u"; + text += IntToStringHex(low_surrogate, 4); + } + // Skip past characters recognized. + i = static_cast<uoffset_t>(utf8 - s - 1); + } + } + break; + } + } + text += "\""; + return true; +} + inline std::string BufferToHexText(const void *buffer, size_t buffer_size, size_t max_length, const std::string &wrapped_line_prefix, |