Update flatbuffers to v22.9.29 (#26)

* update flatbuffers files

How:
- Copied files in from the latest release (v22.9.29) of flatbuffers

Why:
- The files in place blocked compilation within Alpine Linux

Links:
- https://github.com/felt/tippecanoe/issues/24
- https://github.com/google/flatbuffers/releases/tag/v22.9.29

* update flatgeobuf generate files

How
- Created `feature_generated.h` & `header_generated.h` using the `src/fbs` files from the latest release (3.23.1) of flatgeobuf
    - Downloaded the `flatc` binary from the v22.9.29 release of flatbuffers
    - Copied `flatc` into the flatgeobuf repository
    - Created a new directory named `out` to collect the generated files
    - `./flatc --cpp -o out -I include src/fbs/feature.fbs`
    - `./flatc --cpp -o out -I include src/fbs/header.fbs`
    - Moved the generate files from `out` into this repository's `flatgeobuf` directory

Why
- This is a required step in the process of updating flatbuffers files

Links
- https://github.com/flatgeobuf/flatgeobuf/releases/tag/3.23.1
- https://github.com/google/flatbuffers/releases/tag/v22.9.29
- https://github.com/felt/tippecanoe/issues/24#issuecomment-1286476550
This commit is contained in:
James Chevalier
2022-11-03 14:24:02 -07:00
committed by GitHub
parent 5b03b18f31
commit c2214631f2
12 changed files with 436 additions and 291 deletions
+28 -16
View File
@@ -138,9 +138,9 @@
#endif #endif
#endif // !defined(FLATBUFFERS_LITTLEENDIAN) #endif // !defined(FLATBUFFERS_LITTLEENDIAN)
#define FLATBUFFERS_VERSION_MAJOR 2 #define FLATBUFFERS_VERSION_MAJOR 22
#define FLATBUFFERS_VERSION_MINOR 0 #define FLATBUFFERS_VERSION_MINOR 9
#define FLATBUFFERS_VERSION_REVISION 5 #define FLATBUFFERS_VERSION_REVISION 29
#define FLATBUFFERS_STRING_EXPAND(X) #X #define FLATBUFFERS_STRING_EXPAND(X) #X
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X) #define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
namespace flatbuffers { namespace flatbuffers {
@@ -260,9 +260,12 @@ namespace flatbuffers {
#endif // !FLATBUFFERS_HAS_NEW_STRTOD #endif // !FLATBUFFERS_HAS_NEW_STRTOD
#ifndef FLATBUFFERS_LOCALE_INDEPENDENT #ifndef FLATBUFFERS_LOCALE_INDEPENDENT
// Enable locale independent functions {strtof_l, strtod_l,strtoll_l, strtoull_l}. // Enable locale independent functions {strtof_l, strtod_l,strtoll_l,
#if ((defined(_MSC_VER) && _MSC_VER >= 1800) || \ // strtoull_l}.
(defined(_XOPEN_VERSION) && (_XOPEN_VERSION>=700)) && (!defined(__ANDROID_API__) || (defined(__ANDROID_API__) && (__ANDROID_API__>=21)))) #if (defined(_MSC_VER) && _MSC_VER >= 1800) || \
(defined(__ANDROID_API__) && __ANDROID_API__>= 21) || \
(defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 700)) && \
(!defined(__Fuchsia__) && !defined(__ANDROID_API__))
#define FLATBUFFERS_LOCALE_INDEPENDENT 1 #define FLATBUFFERS_LOCALE_INDEPENDENT 1
#else #else
#define FLATBUFFERS_LOCALE_INDEPENDENT 0 #define FLATBUFFERS_LOCALE_INDEPENDENT 0
@@ -270,14 +273,14 @@ namespace flatbuffers {
#endif // !FLATBUFFERS_LOCALE_INDEPENDENT #endif // !FLATBUFFERS_LOCALE_INDEPENDENT
// Suppress Undefined Behavior Sanitizer (recoverable only). Usage: // Suppress Undefined Behavior Sanitizer (recoverable only). Usage:
// - __supress_ubsan__("undefined") // - __suppress_ubsan__("undefined")
// - __supress_ubsan__("signed-integer-overflow") // - __suppress_ubsan__("signed-integer-overflow")
#if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7)) #if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7))
#define __supress_ubsan__(type) __attribute__((no_sanitize(type))) #define __suppress_ubsan__(type) __attribute__((no_sanitize(type)))
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409) #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)
#define __supress_ubsan__(type) __attribute__((no_sanitize_undefined)) #define __suppress_ubsan__(type) __attribute__((no_sanitize_undefined))
#else #else
#define __supress_ubsan__(type) #define __suppress_ubsan__(type)
#endif #endif
// This is constexpr function used for checking compile-time constants. // This is constexpr function used for checking compile-time constants.
@@ -328,8 +331,17 @@ typedef uintmax_t largest_scalar_t;
// In 32bits, this evaluates to 2GB - 1 // In 32bits, this evaluates to 2GB - 1
#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1) #define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1)
// The minimum size buffer that can be a valid flatbuffer.
// Includes the offset to the root table (uoffset_t), the offset to the vtable
// of the root table (soffset_t), the size of the vtable (uint16_t), and the
// size of the referring table (uint16_t).
#define FLATBUFFERS_MIN_BUFFER_SIZE sizeof(uoffset_t) + sizeof(soffset_t) + \
sizeof(uint16_t) + sizeof(uint16_t)
// We support aligning the contents of buffers up to this size. // We support aligning the contents of buffers up to this size.
#define FLATBUFFERS_MAX_ALIGNMENT 16 #ifndef FLATBUFFERS_MAX_ALIGNMENT
#define FLATBUFFERS_MAX_ALIGNMENT 32
#endif
/// @brief The length of a FlatBuffer file header. /// @brief The length of a FlatBuffer file header.
static const size_t kFileIdentifierLength = 4; static const size_t kFileIdentifierLength = 4;
@@ -401,7 +413,7 @@ template<typename T> T EndianScalar(T t) {
template<typename T> template<typename T>
// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. // UBSAN: C++ aliasing type rules, see std::bit_cast<> for details.
__supress_ubsan__("alignment") __suppress_ubsan__("alignment")
T ReadScalar(const void *p) { T ReadScalar(const void *p) {
return EndianScalar(*reinterpret_cast<const T *>(p)); return EndianScalar(*reinterpret_cast<const T *>(p));
} }
@@ -415,13 +427,13 @@ T ReadScalar(const void *p) {
template<typename T> template<typename T>
// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. // UBSAN: C++ aliasing type rules, see std::bit_cast<> for details.
__supress_ubsan__("alignment") __suppress_ubsan__("alignment")
void WriteScalar(void *p, T t) { 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> struct Offset;
template<typename T> __supress_ubsan__("alignment") void WriteScalar(void *p, Offset<T> t) { template<typename T> __suppress_ubsan__("alignment") void WriteScalar(void *p, Offset<T> t) {
*reinterpret_cast<uoffset_t *>(p) = EndianScalar(t.o); *reinterpret_cast<uoffset_t *>(p) = EndianScalar(t.o);
} }
@@ -432,7 +444,7 @@ template<typename T> __supress_ubsan__("alignment") void WriteScalar(void *p, Of
// Computes how many bytes you'd have to pad to be able to write an // 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 // "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in
// memory). // memory).
__supress_ubsan__("unsigned-integer-overflow") __suppress_ubsan__("unsigned-integer-overflow")
inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) { inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
return ((~buf_size) + 1) & (scalar_size - 1); return ((~buf_size) + 1) & (scalar_size - 1);
} }
+1 -1
View File
@@ -95,7 +95,7 @@ template<typename T> struct IndirectHelper<const T *> {
} }
}; };
/// @brief Get a pointer to the the file_identifier section of the buffer. /// @brief Get a pointer to the file_identifier section of the buffer.
/// @return Returns a const char pointer to the start of the file_identifier /// @return Returns a const char pointer to the start of the file_identifier
/// characters in the buffer. The returned char * has length /// characters in the buffer. The returned char * has length
/// 'flatbuffers::FlatBufferBuilder::kFileIdentifierLength'. /// 'flatbuffers::FlatBufferBuilder::kFileIdentifierLength'.
+73 -36
View File
@@ -18,6 +18,7 @@
#define FLATBUFFERS_FLATBUFFER_BUILDER_H_ #define FLATBUFFERS_FLATBUFFER_BUILDER_H_
#include <functional> #include <functional>
#include <initializer_list>
#include "flatbuffers/allocator.h" #include "flatbuffers/allocator.h"
#include "flatbuffers/array.h" #include "flatbuffers/array.h"
@@ -42,14 +43,15 @@ inline voffset_t FieldIndexToOffset(voffset_t field_id) {
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> template<typename T, typename Alloc = std::allocator<T>>
const T *data(const std::vector<T, Alloc> &v) { const T *data(const std::vector<T, Alloc> &v) {
// Eventually the returned pointer gets passed down to memcpy, so // Eventually the returned pointer gets passed down to memcpy, so
// we need it to be non-null to avoid undefined behavior. // we need it to be non-null to avoid undefined behavior.
static uint8_t t; static uint8_t t;
return v.empty() ? reinterpret_cast<const T *>(&t) : &v.front(); 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 = std::allocator<T>>
T *data(std::vector<T, Alloc> &v) {
// Eventually the returned pointer gets passed down to memcpy, so // Eventually the returned pointer gets passed down to memcpy, so
// we need it to be non-null to avoid undefined behavior. // we need it to be non-null to avoid undefined behavior.
static uint8_t t; static uint8_t t;
@@ -285,9 +287,7 @@ class FlatBufferBuilder {
FieldLoc fl = { off, field }; FieldLoc fl = { off, field };
buf_.scratch_push_small(fl); buf_.scratch_push_small(fl);
num_field_loc++; num_field_loc++;
if (field > max_voffset_) { if (field > max_voffset_) { max_voffset_ = field; }
max_voffset_ = field;
}
} }
// Like PushElement, but additionally tracks the field this represents. // Like PushElement, but additionally tracks the field this represents.
@@ -358,7 +358,7 @@ class FlatBufferBuilder {
// If you get this assert, a corresponding StartTable wasn't called. // 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. // Write the vtable offset, which is the start of any Table.
// We fill it's value later. // We fill its value later.
auto vtableoffsetloc = PushElement<soffset_t>(0); auto vtableoffsetloc = PushElement<soffset_t>(0);
// Write a vtable, which consists entirely of voffset_t elements. // Write a vtable, which consists entirely of voffset_t elements.
// It starts with the number of offsets, followed by a type id, followed // It starts with the number of offsets, followed by a type id, followed
@@ -443,12 +443,13 @@ class FlatBufferBuilder {
// Aligns such that when "len" bytes are written, an object can be written // Aligns such that when "len" bytes are written, an object can be written
// after it with "alignment" without padding. // after it with "alignment" without padding.
void PreAlign(size_t len, size_t alignment) { void PreAlign(size_t len, size_t alignment) {
if (len == 0) return;
TrackMinAlign(alignment); TrackMinAlign(alignment);
buf_.fill(PaddingBytes(GetSize() + len, alignment)); buf_.fill(PaddingBytes(GetSize() + len, alignment));
} }
template<typename T> void PreAlign(size_t len) { template<typename T> void PreAlign(size_t len) {
AssertScalarT<T>(); AssertScalarT<T>();
PreAlign(len, sizeof(T)); PreAlign(len, AlignOf<T>());
} }
/// @endcond /// @endcond
@@ -578,7 +579,7 @@ class FlatBufferBuilder {
/// @param[in] str A const pointer to a `String` struct to add to the buffer. /// @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 /// @return Returns the offset in the buffer where the string starts
Offset<String> CreateSharedString(const String *str) { Offset<String> CreateSharedString(const String *str) {
return CreateSharedString(str->c_str(), str->size()); return str ? CreateSharedString(str->c_str(), str->size()) : 0;
} }
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
@@ -588,11 +589,15 @@ class FlatBufferBuilder {
return PushElement(static_cast<uoffset_t>(len)); return PushElement(static_cast<uoffset_t>(len));
} }
void StartVector(size_t len, size_t elemsize) { void StartVector(size_t len, size_t elemsize, size_t alignment) {
NotNested(); NotNested();
nested = true; nested = true;
PreAlign<uoffset_t>(len * elemsize); PreAlign<uoffset_t>(len * elemsize);
PreAlign(len * elemsize, elemsize); // Just in case elemsize > uoffset_t. PreAlign(len * elemsize, alignment); // Just in case elemsize > uoffset_t.
}
template<typename T> void StartVector(size_t len) {
return StartVector(len, sizeof(T), AlignOf<T>());
} }
// Call this right before StartVector/CreateVector if you want to force the // Call this right before StartVector/CreateVector if you want to force the
@@ -601,12 +606,14 @@ class FlatBufferBuilder {
// This is useful when storing a nested_flatbuffer in a vector of bytes, // This is useful when storing a nested_flatbuffer in a vector of bytes,
// or when storing SIMD floats, etc. // or when storing SIMD floats, etc.
void ForceVectorAlignment(size_t len, size_t elemsize, size_t alignment) { void ForceVectorAlignment(size_t len, size_t elemsize, size_t alignment) {
if (len == 0) return;
FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment)); FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment));
PreAlign(len * elemsize, alignment); PreAlign(len * elemsize, alignment);
} }
// Similar to ForceVectorAlignment but for String fields. // Similar to ForceVectorAlignment but for String fields.
void ForceStringAlignment(size_t len, size_t alignment) { void ForceStringAlignment(size_t len, size_t alignment) {
if (len == 0) return;
FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment)); FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment));
PreAlign((len + 1) * sizeof(char), alignment); PreAlign((len + 1) * sizeof(char), alignment);
} }
@@ -624,7 +631,7 @@ class FlatBufferBuilder {
// If this assert hits, you're specifying a template argument that is // If this assert hits, you're specifying a template argument that is
// causing the wrong overload to be selected, remove it. // causing the wrong overload to be selected, remove it.
AssertScalarT<T>(); AssertScalarT<T>();
StartVector(len, sizeof(T)); StartVector<T>(len);
if (len == 0) { return Offset<Vector<T>>(EndVector(len)); } if (len == 0) { return Offset<Vector<T>>(EndVector(len)); }
// clang-format off // clang-format off
#if FLATBUFFERS_LITTLEENDIAN #if FLATBUFFERS_LITTLEENDIAN
@@ -642,9 +649,30 @@ class FlatBufferBuilder {
return Offset<Vector<T>>(EndVector(len)); return Offset<Vector<T>>(EndVector(len));
} }
/// @brief Serialize an array like object into a FlatBuffer `vector`.
/// @tparam T The data type of the array elements.
/// @tparam C The type of the array.
/// @param[in] array A reference to an array like object of type `T` 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, class C> Offset<Vector<T>> CreateVector(const C &array) {
return CreateVector(array.data(), array.size());
}
/// @brief Serialize an initializer list into a FlatBuffer `vector`.
/// @tparam T The data type of the initializer list elements.
/// @param[in] v The value of the initializer list.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
template<typename T>
Offset<Vector<T>> CreateVector(std::initializer_list<T> v) {
return CreateVector(v.begin(), v.size());
}
template<typename T> template<typename T>
Offset<Vector<Offset<T>>> CreateVector(const Offset<T> *v, size_t len) { Offset<Vector<Offset<T>>> CreateVector(const Offset<T> *v, size_t len) {
StartVector(len, sizeof(Offset<T>)); StartVector<Offset<T>>(len);
for (auto i = len; i > 0;) { PushElement(v[--i]); } for (auto i = len; i > 0;) { PushElement(v[--i]); }
return Offset<Vector<Offset<T>>>(EndVector(len)); return Offset<Vector<Offset<T>>>(EndVector(len));
} }
@@ -655,7 +683,7 @@ class FlatBufferBuilder {
/// buffer as a `vector`. /// buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
template<typename T, typename Alloc> template<typename T, typename Alloc = std::allocator<T>>
Offset<Vector<T>> CreateVector(const std::vector<T, Alloc> &v) { Offset<Vector<T>> CreateVector(const std::vector<T, Alloc> &v) {
return CreateVector(data(v), v.size()); return CreateVector(data(v), v.size());
} }
@@ -664,7 +692,7 @@ class FlatBufferBuilder {
// an array. Instead, read elements manually. // an array. Instead, read elements manually.
// Background: https://isocpp.org/blog/2012/11/on-vectorbool // Background: https://isocpp.org/blog/2012/11/on-vectorbool
Offset<Vector<uint8_t>> CreateVector(const std::vector<bool> &v) { Offset<Vector<uint8_t>> CreateVector(const std::vector<bool> &v) {
StartVector(v.size(), sizeof(uint8_t)); StartVector<uint8_t>(v.size());
for (auto i = v.size(); i > 0;) { for (auto i = v.size(); i > 0;) {
PushElement(static_cast<uint8_t>(v[--i])); PushElement(static_cast<uint8_t>(v[--i]));
} }
@@ -706,21 +734,24 @@ class FlatBufferBuilder {
return CreateVector(elems); return CreateVector(elems);
} }
/// @brief Serialize a `std::vector<std::string>` into a FlatBuffer `vector`. /// @brief Serialize a `std::vector<StringType>` into a FlatBuffer `vector`.
/// whereas StringType is any type that is accepted by the CreateString()
/// overloads.
/// This is a convenience function for a common case. /// This is a convenience function for a common case.
/// @param v A const reference to the `std::vector` to serialize into the /// @param v A const reference to the `std::vector` to serialize into the
/// buffer as a `vector`. /// buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
template<typename Alloc> template<typename StringType = std::string,
typename Alloc = std::allocator<StringType>>
Offset<Vector<Offset<String>>> CreateVectorOfStrings( Offset<Vector<Offset<String>>> CreateVectorOfStrings(
const std::vector<std::string, Alloc> &v) { const std::vector<StringType, Alloc> &v) {
return CreateVectorOfStrings(v.cbegin(), v.cend()); return CreateVectorOfStrings(v.cbegin(), v.cend());
} }
/// @brief Serialize a collection of Strings into a FlatBuffer `vector`. /// @brief Serialize a collection of Strings into a FlatBuffer `vector`.
/// This is a convenience function for a common case. /// This is a convenience function for a common case.
/// @param begin The begining iterator of the collection /// @param begin The beginning iterator of the collection
/// @param end The ending iterator of the collection /// @param end The ending iterator of the collection
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
@@ -730,12 +761,12 @@ class FlatBufferBuilder {
auto scratch_buffer_usage = size * sizeof(Offset<String>); auto scratch_buffer_usage = size * sizeof(Offset<String>);
// If there is not enough space to store the offsets, there definitely won't // If there is not enough space to store the offsets, there definitely won't
// be enough space to store all the strings. So ensuring space for the // be enough space to store all the strings. So ensuring space for the
// scratch region is OK, for it it fails, it would have failed later. // scratch region is OK, for if it fails, it would have failed later.
buf_.ensure_space(scratch_buffer_usage); buf_.ensure_space(scratch_buffer_usage);
for (auto it = begin; it != end; ++it) { for (auto it = begin; it != end; ++it) {
buf_.scratch_push_small(CreateString(*it)); buf_.scratch_push_small(CreateString(*it));
} }
StartVector(size, sizeof(Offset<String>)); StartVector<Offset<String>>(size);
for (auto i = 1; i <= size; i++) { for (auto i = 1; i <= size; i++) {
// Note we re-evaluate the buf location each iteration to account for any // Note we re-evaluate the buf location each iteration to account for any
// underlying buffer resizing that may occur. // underlying buffer resizing that may occur.
@@ -755,7 +786,7 @@ class FlatBufferBuilder {
/// where the vector is stored. /// where the vector is stored.
template<typename T> template<typename T>
Offset<Vector<const T *>> CreateVectorOfStructs(const T *v, size_t len) { Offset<Vector<const T *>> CreateVectorOfStructs(const T *v, size_t len) {
StartVector(len * sizeof(T) / AlignOf<T>(), AlignOf<T>()); StartVector(len * sizeof(T) / AlignOf<T>(), sizeof(T), AlignOf<T>());
if (len > 0) { if (len > 0) {
PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len); PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len);
} }
@@ -841,7 +872,7 @@ class FlatBufferBuilder {
/// serialize into the buffer as a `vector`. /// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
template<typename T, typename Alloc> template<typename T, typename Alloc = std::allocator<T>>
Offset<Vector<const T *>> CreateVectorOfStructs( Offset<Vector<const T *>> CreateVectorOfStructs(
const std::vector<T, Alloc> &v) { const std::vector<T, Alloc> &v) {
return CreateVectorOfStructs(data(v), v.size()); return CreateVectorOfStructs(data(v), v.size());
@@ -857,7 +888,7 @@ class FlatBufferBuilder {
/// to the FlatBuffer struct. /// to the FlatBuffer struct.
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
template<typename T, typename S, typename Alloc> template<typename T, typename S, typename Alloc = std::allocator<T>>
Offset<Vector<const T *>> CreateVectorOfNativeStructs( Offset<Vector<const T *>> CreateVectorOfNativeStructs(
const std::vector<S, Alloc> &v, T (*const pack_func)(const S &)) { const std::vector<S, Alloc> &v, T (*const pack_func)(const S &)) {
return CreateVectorOfNativeStructs<T, S>(data(v), v.size(), pack_func); return CreateVectorOfNativeStructs<T, S>(data(v), v.size(), pack_func);
@@ -871,7 +902,7 @@ class FlatBufferBuilder {
/// serialize into the buffer as a `vector`. /// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
template<typename T, typename S, typename Alloc> template<typename T, typename S, typename Alloc = std::allocator<S>>
Offset<Vector<const T *>> CreateVectorOfNativeStructs( Offset<Vector<const T *>> CreateVectorOfNativeStructs(
const std::vector<S, Alloc> &v) { const std::vector<S, Alloc> &v) {
return CreateVectorOfNativeStructs<T, S>(data(v), v.size()); return CreateVectorOfNativeStructs<T, S>(data(v), v.size());
@@ -892,7 +923,7 @@ class FlatBufferBuilder {
/// serialize into the buffer as a `vector`. /// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
template<typename T, typename Alloc> template<typename T, typename Alloc = std::allocator<T>>
Offset<Vector<const T *>> CreateVectorOfSortedStructs( Offset<Vector<const T *>> CreateVectorOfSortedStructs(
std::vector<T, Alloc> *v) { std::vector<T, Alloc> *v) {
return CreateVectorOfSortedStructs(data(*v), v->size()); return CreateVectorOfSortedStructs(data(*v), v->size());
@@ -906,7 +937,7 @@ class FlatBufferBuilder {
/// serialize into the buffer as a `vector`. /// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
template<typename T, typename S, typename Alloc> template<typename T, typename S, typename Alloc = std::allocator<T>>
Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs( Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(
std::vector<S, Alloc> *v) { std::vector<S, Alloc> *v) {
return CreateVectorOfSortedNativeStructs<T, S>(data(*v), v->size()); return CreateVectorOfSortedNativeStructs<T, S>(data(*v), v->size());
@@ -922,7 +953,7 @@ class FlatBufferBuilder {
/// where the vector is stored. /// where the vector is stored.
template<typename T> template<typename T>
Offset<Vector<const T *>> CreateVectorOfSortedStructs(T *v, size_t len) { Offset<Vector<const T *>> CreateVectorOfSortedStructs(T *v, size_t len) {
std::sort(v, v + len, StructKeyComparator<T>()); std::stable_sort(v, v + len, StructKeyComparator<T>());
return CreateVectorOfStructs(v, len); return CreateVectorOfStructs(v, len);
} }
@@ -941,7 +972,7 @@ class FlatBufferBuilder {
extern T Pack(const S &); extern T Pack(const S &);
auto structs = StartVectorOfStructs<T>(len); auto structs = StartVectorOfStructs<T>(len);
for (size_t i = 0; i < len; i++) { structs[i] = Pack(v[i]); } for (size_t i = 0; i < len; i++) { structs[i] = Pack(v[i]); }
std::sort(structs, structs + len, StructKeyComparator<T>()); std::stable_sort(structs, structs + len, StructKeyComparator<T>());
return EndVectorOfStructs<T>(len); return EndVectorOfStructs<T>(len);
} }
@@ -973,7 +1004,7 @@ class FlatBufferBuilder {
template<typename T> template<typename T>
Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(Offset<T> *v, Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(Offset<T> *v,
size_t len) { size_t len) {
std::sort(v, v + len, TableKeyComparator<T>(buf_)); std::stable_sort(v, v + len, TableKeyComparator<T>(buf_));
return CreateVector(v, len); return CreateVector(v, len);
} }
@@ -984,7 +1015,7 @@ class FlatBufferBuilder {
/// offsets to store in the buffer in sorted order. /// offsets to store in the buffer in sorted order.
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
template<typename T, typename Alloc> template<typename T, typename Alloc = std::allocator<T>>
Offset<Vector<Offset<T>>> CreateVectorOfSortedTables( Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(
std::vector<Offset<T>, Alloc> *v) { std::vector<Offset<T>, Alloc> *v) {
return CreateVectorOfSortedTables(data(*v), v->size()); return CreateVectorOfSortedTables(data(*v), v->size());
@@ -998,9 +1029,9 @@ class FlatBufferBuilder {
/// written to at a later time to serialize the data into a `vector` /// written to at a later time to serialize the data into a `vector`
/// in the buffer. /// in the buffer.
uoffset_t CreateUninitializedVector(size_t len, size_t elemsize, uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
uint8_t **buf) { size_t alignment, uint8_t **buf) {
NotNested(); NotNested();
StartVector(len, elemsize); StartVector(len, elemsize, alignment);
buf_.make_space(len * elemsize); buf_.make_space(len * elemsize);
auto vec_start = GetSize(); auto vec_start = GetSize();
auto vec_end = EndVector(len); auto vec_end = EndVector(len);
@@ -1008,6 +1039,12 @@ class FlatBufferBuilder {
return vec_end; return vec_end;
} }
FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]])
uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
uint8_t **buf) {
return CreateUninitializedVector(len, elemsize, elemsize, buf);
}
/// @brief Specialized version of `CreateVector` for non-copying use cases. /// @brief Specialized version of `CreateVector` for non-copying use cases.
/// Write the data any time later to the returned buffer pointer `buf`. /// Write the data any time later to the returned buffer pointer `buf`.
/// @tparam T The data type of the data that will be stored in the buffer /// @tparam T The data type of the data that will be stored in the buffer
@@ -1019,14 +1056,14 @@ class FlatBufferBuilder {
template<typename T> template<typename T>
Offset<Vector<T>> CreateUninitializedVector(size_t len, T **buf) { Offset<Vector<T>> CreateUninitializedVector(size_t len, T **buf) {
AssertScalarT<T>(); AssertScalarT<T>();
return CreateUninitializedVector(len, sizeof(T), return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
reinterpret_cast<uint8_t **>(buf)); reinterpret_cast<uint8_t **>(buf));
} }
template<typename T> template<typename T>
Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len, Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
T **buf) { T **buf) {
return CreateUninitializedVector(len, sizeof(T), return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
reinterpret_cast<uint8_t **>(buf)); reinterpret_cast<uint8_t **>(buf));
} }
@@ -1037,7 +1074,7 @@ class FlatBufferBuilder {
Offset<Vector<T>> CreateVectorScalarCast(const U *v, size_t len) { Offset<Vector<T>> CreateVectorScalarCast(const U *v, size_t len) {
AssertScalarT<T>(); AssertScalarT<T>();
AssertScalarT<U>(); AssertScalarT<U>();
StartVector(len, sizeof(T)); StartVector<T>(len);
for (auto i = len; i > 0;) { PushElement(static_cast<T>(v[--i])); } for (auto i = len; i > 0;) { PushElement(static_cast<T>(v[--i])); }
return Offset<Vector<T>>(EndVector(len)); return Offset<Vector<T>>(EndVector(len));
} }
@@ -1146,7 +1183,7 @@ class FlatBufferBuilder {
// Allocates space for a vector of structures. // Allocates space for a vector of structures.
// Must be completed with EndVectorOfStructs(). // Must be completed with EndVectorOfStructs().
template<typename T> T *StartVectorOfStructs(size_t vector_size) { template<typename T> T *StartVectorOfStructs(size_t vector_size) {
StartVector(vector_size * sizeof(T) / AlignOf<T>(), AlignOf<T>()); StartVector(vector_size * sizeof(T) / AlignOf<T>(), sizeof(T), AlignOf<T>());
return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T))); return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
} }
+5 -19
View File
@@ -226,27 +226,13 @@ struct TypeTable {
}; };
// String which identifies the current version of FlatBuffers. // String which identifies the current version of FlatBuffers.
// flatbuffer_version_string is used by Google developers to identify which inline const char *flatbuffers_version_string() {
// applications uploaded to Google Play are using this library. This allows return "FlatBuffers " FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
// the development team at Google to determine the popularity of the library. FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
// How it works: Applications that are uploaded to the Google Play Store are FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
// scanned for this version string. We track which applications are using it }
// to measure popularity. You are free to remove it (of course) but we would
// appreciate if you left it in.
// Weak linkage is culled by VS & doesn't work on cygwin.
// clang-format off // clang-format off
#if !defined(_WIN32) && !defined(__CYGWIN__)
extern volatile __attribute__((weak)) const char *flatbuffer_version_string;
volatile __attribute__((weak)) const char *flatbuffer_version_string =
"FlatBuffers "
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
#endif // !defined(_WIN32) && !defined(__CYGWIN__)
#define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\ #define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\
inline E operator | (E lhs, E rhs){\ inline E operator | (E lhs, E rhs){\
return E(T(lhs) | T(rhs));\ return E(T(lhs) | T(rhs));\
+45 -44
View File
@@ -26,22 +26,27 @@
#include <memory> #include <memory>
#include <limits> #include <limits>
// Detect C++17 compatible compiler. #ifndef FLATBUFFERS_USE_STD_OPTIONAL
// __cplusplus >= 201703L - a compiler has support of 'static inline' variables. // Detect C++17 compatible compiler.
#if defined(FLATBUFFERS_USE_STD_OPTIONAL) \ // __cplusplus >= 201703L - a compiler has support of 'static inline' variables.
|| (defined(__cplusplus) && __cplusplus >= 201703L) \ #if (defined(__cplusplus) && __cplusplus >= 201703L) \
|| (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L)) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
#define FLATBUFFERS_USE_STD_OPTIONAL 1
#else
#define FLATBUFFERS_USE_STD_OPTIONAL 0
#endif // (defined(__cplusplus) && __cplusplus >= 201703L) ...
#endif // FLATBUFFERS_USE_STD_OPTIONAL
#if FLATBUFFERS_USE_STD_OPTIONAL
#include <optional> #include <optional>
#ifndef FLATBUFFERS_USE_STD_OPTIONAL #endif
#define FLATBUFFERS_USE_STD_OPTIONAL
#endif
#endif // defined(FLATBUFFERS_USE_STD_OPTIONAL) ...
// The __cpp_lib_span is the predefined feature macro. // The __cpp_lib_span is the predefined feature macro.
#if defined(FLATBUFFERS_USE_STD_SPAN) #if defined(FLATBUFFERS_USE_STD_SPAN)
#include <span> #include <span>
#elif defined(__cpp_lib_span) && defined(__has_include) #elif defined(__cpp_lib_span) && defined(__has_include)
#if __has_include(<span>) #if __has_include(<span>)
#include <array>
#include <span> #include <span>
#define FLATBUFFERS_USE_STD_SPAN #define FLATBUFFERS_USE_STD_SPAN
#endif #endif
@@ -128,7 +133,7 @@ namespace flatbuffers {
}; };
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
#ifdef FLATBUFFERS_USE_STD_OPTIONAL #if FLATBUFFERS_USE_STD_OPTIONAL
template<class T> template<class T>
using Optional = std::optional<T>; using Optional = std::optional<T>;
using nullopt_t = std::nullopt_t; using nullopt_t = std::nullopt_t;
@@ -284,13 +289,13 @@ FLATBUFFERS_CONSTEXPR std::size_t dynamic_extent = static_cast<std::size_t>(-1);
namespace internal { namespace internal {
// This is SFINAE helper class for checking of a common condition: // This is SFINAE helper class for checking of a common condition:
// > This overload only participates in overload resolution // > This overload only participates in overload resolution
// > Check whether a pointer to an array of U can be converted // > Check whether a pointer to an array of From can be converted
// > to a pointer to an array of E. // > to a pointer to an array of To.
// This helper is used for checking of 'U -> const U'. // This helper is used for checking of 'From -> const From'.
template<class E, std::size_t Extent, class U, std::size_t N> template<class To, std::size_t Extent, class From, std::size_t N>
struct is_span_convertable { struct is_span_convertible {
using type = using type =
typename std::conditional<std::is_convertible<U (*)[], E (*)[]>::value typename std::conditional<std::is_convertible<From (*)[], To (*)[]>::value
&& (Extent == dynamic_extent || N == Extent), && (Extent == dynamic_extent || N == Extent),
int, void>::type; int, void>::type;
}; };
@@ -362,13 +367,9 @@ class span FLATBUFFERS_FINAL_CLASS {
#if !defined(FLATBUFFERS_SPAN_MINIMAL) #if !defined(FLATBUFFERS_SPAN_MINIMAL)
using Iterator = internal::SpanIterator<T>; using Iterator = internal::SpanIterator<T>;
using ConstIterator = internal::SpanIterator<const T>;
Iterator begin() const { return Iterator(data()); } Iterator begin() const { return Iterator(data()); }
Iterator end() const { return Iterator(data() + size()); } Iterator end() const { return Iterator(data() + size()); }
ConstIterator cbegin() const { return ConstIterator(data()); }
ConstIterator cend() const { return ConstIterator(data() + size()); }
#endif #endif
// Returns a reference to the idx-th element of the sequence. // Returns a reference to the idx-th element of the sequence.
@@ -414,7 +415,7 @@ class span FLATBUFFERS_FINAL_CLASS {
// extent == 0 || extent == flatbuffers::dynamic_extent. // extent == 0 || extent == flatbuffers::dynamic_extent.
// A dummy template argument N is need dependency for SFINAE. // A dummy template argument N is need dependency for SFINAE.
template<std::size_t N = 0, template<std::size_t N = 0,
typename internal::is_span_convertable<element_type, Extent, element_type, (N - N)>::type = 0> typename internal::is_span_convertible<element_type, Extent, element_type, (N - N)>::type = 0>
FLATBUFFERS_CONSTEXPR_CPP11 span() FLATBUFFERS_NOEXCEPT : data_(nullptr), FLATBUFFERS_CONSTEXPR_CPP11 span() FLATBUFFERS_NOEXCEPT : data_(nullptr),
count_(0) { count_(0) {
static_assert(extent == 0 || extent == dynamic_extent, "invalid span"); static_assert(extent == 0 || extent == dynamic_extent, "invalid span");
@@ -427,12 +428,12 @@ class span FLATBUFFERS_FINAL_CLASS {
// std::remove_pointer_t<decltype(std::data(arr))>(*)[] // std::remove_pointer_t<decltype(std::data(arr))>(*)[]
// is convertible to element_type (*)[]. // is convertible to element_type (*)[].
template<std::size_t N, template<std::size_t N,
typename internal::is_span_convertable<element_type, Extent, element_type, N>::type = 0> typename internal::is_span_convertible<element_type, Extent, element_type, N>::type = 0>
FLATBUFFERS_CONSTEXPR_CPP11 span(element_type (&arr)[N]) FLATBUFFERS_NOEXCEPT FLATBUFFERS_CONSTEXPR_CPP11 span(element_type (&arr)[N]) FLATBUFFERS_NOEXCEPT
: data_(arr), count_(N) {} : data_(arr), count_(N) {}
template<class U, std::size_t N, template<class U, std::size_t N,
typename internal::is_span_convertable<element_type, Extent, U, N>::type = 0> typename internal::is_span_convertible<element_type, Extent, U, N>::type = 0>
FLATBUFFERS_CONSTEXPR_CPP11 span(std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT FLATBUFFERS_CONSTEXPR_CPP11 span(std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT
: data_(arr.data()), count_(N) {} : data_(arr.data()), count_(N) {}
@@ -442,7 +443,7 @@ class span FLATBUFFERS_FINAL_CLASS {
// : data_(arr.data()), count_(N) {} // : data_(arr.data()), count_(N) {}
template<class U, std::size_t N, template<class U, std::size_t N,
typename internal::is_span_convertable<element_type, Extent, U, N>::type = 0> typename internal::is_span_convertible<element_type, Extent, U, N>::type = 0>
FLATBUFFERS_CONSTEXPR_CPP11 span(const std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT FLATBUFFERS_CONSTEXPR_CPP11 span(const std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT
: data_(arr.data()), count_(N) {} : data_(arr.data()), count_(N) {}
@@ -452,7 +453,7 @@ class span FLATBUFFERS_FINAL_CLASS {
// if extent == std::dynamic_extent || N == extent is true and U (*)[] // if extent == std::dynamic_extent || N == extent is true and U (*)[]
// is convertible to element_type (*)[]. // is convertible to element_type (*)[].
template<class U, std::size_t N, template<class U, std::size_t N,
typename internal::is_span_convertable<element_type, Extent, U, N>::type = 0> typename internal::is_span_convertible<element_type, Extent, U, N>::type = 0>
FLATBUFFERS_CONSTEXPR_CPP11 span(const flatbuffers::span<U, N> &s) FLATBUFFERS_NOEXCEPT FLATBUFFERS_CONSTEXPR_CPP11 span(const flatbuffers::span<U, N> &s) FLATBUFFERS_NOEXCEPT
: span(s.data(), s.size()) { : span(s.data(), s.size()) {
} }
@@ -462,45 +463,45 @@ class span FLATBUFFERS_FINAL_CLASS {
private: private:
// This is a naive implementation with 'count_' member even if (Extent != dynamic_extent). // This is a naive implementation with 'count_' member even if (Extent != dynamic_extent).
pointer const data_; pointer const data_;
const size_type count_; size_type count_;
}; };
#endif // defined(FLATBUFFERS_USE_STD_SPAN) #endif // defined(FLATBUFFERS_USE_STD_SPAN)
#if !defined(FLATBUFFERS_SPAN_MINIMAL) #if !defined(FLATBUFFERS_SPAN_MINIMAL)
template<class U, std::size_t N> template<class ElementType, std::size_t Extent>
FLATBUFFERS_CONSTEXPR_CPP11 FLATBUFFERS_CONSTEXPR_CPP11
flatbuffers::span<U, N> make_span(U(&arr)[N]) FLATBUFFERS_NOEXCEPT { flatbuffers::span<ElementType, Extent> make_span(ElementType(&arr)[Extent]) FLATBUFFERS_NOEXCEPT {
return span<U, N>(arr); return span<ElementType, Extent>(arr);
} }
template<class U, std::size_t N> template<class ElementType, std::size_t Extent>
FLATBUFFERS_CONSTEXPR_CPP11 FLATBUFFERS_CONSTEXPR_CPP11
flatbuffers::span<const U, N> make_span(const U(&arr)[N]) FLATBUFFERS_NOEXCEPT { flatbuffers::span<const ElementType, Extent> make_span(const ElementType(&arr)[Extent]) FLATBUFFERS_NOEXCEPT {
return span<const U, N>(arr); return span<const ElementType, Extent>(arr);
} }
template<class U, std::size_t N> template<class ElementType, std::size_t Extent>
FLATBUFFERS_CONSTEXPR_CPP11 FLATBUFFERS_CONSTEXPR_CPP11
flatbuffers::span<U, N> make_span(std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT { flatbuffers::span<ElementType, Extent> make_span(std::array<ElementType, Extent> &arr) FLATBUFFERS_NOEXCEPT {
return span<U, N>(arr); return span<ElementType, Extent>(arr);
} }
template<class U, std::size_t N> template<class ElementType, std::size_t Extent>
FLATBUFFERS_CONSTEXPR_CPP11 FLATBUFFERS_CONSTEXPR_CPP11
flatbuffers::span<const U, N> make_span(const std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT { flatbuffers::span<const ElementType, Extent> make_span(const std::array<ElementType, Extent> &arr) FLATBUFFERS_NOEXCEPT {
return span<const U, N>(arr); return span<const ElementType, Extent>(arr);
} }
template<class U, std::size_t N> template<class ElementType, std::size_t Extent>
FLATBUFFERS_CONSTEXPR_CPP11 FLATBUFFERS_CONSTEXPR_CPP11
flatbuffers::span<U, dynamic_extent> make_span(U *first, std::size_t count) FLATBUFFERS_NOEXCEPT { flatbuffers::span<ElementType, dynamic_extent> make_span(ElementType *first, std::size_t count) FLATBUFFERS_NOEXCEPT {
return span<U, dynamic_extent>(first, count); return span<ElementType, dynamic_extent>(first, count);
} }
template<class U, std::size_t N> template<class ElementType, std::size_t Extent>
FLATBUFFERS_CONSTEXPR_CPP11 FLATBUFFERS_CONSTEXPR_CPP11
flatbuffers::span<const U, dynamic_extent> make_span(const U *first, std::size_t count) FLATBUFFERS_NOEXCEPT { flatbuffers::span<const ElementType, dynamic_extent> make_span(const ElementType *first, std::size_t count) FLATBUFFERS_NOEXCEPT {
return span<const U, dynamic_extent>(first, count); return span<const ElementType, dynamic_extent>(first, count);
} }
#endif // !defined(FLATBUFFERS_SPAN_MINIMAL) #endif // !defined(FLATBUFFERS_SPAN_MINIMAL)
+6 -4
View File
@@ -112,20 +112,22 @@ class Table {
// Verify a particular field. // Verify a particular field.
template<typename T> template<typename T>
bool VerifyField(const Verifier &verifier, voffset_t field) const { bool VerifyField(const Verifier &verifier, voffset_t field,
size_t align) const {
// Calling GetOptionalFieldOffset should be safe now thanks to // Calling GetOptionalFieldOffset should be safe now thanks to
// VerifyTable(). // VerifyTable().
auto field_offset = GetOptionalFieldOffset(field); auto field_offset = GetOptionalFieldOffset(field);
// Check the actual field. // Check the actual field.
return !field_offset || verifier.Verify<T>(data_, field_offset); return !field_offset || verifier.VerifyField<T>(data_, field_offset, align);
} }
// VerifyField for required fields. // VerifyField for required fields.
template<typename T> template<typename T>
bool VerifyFieldRequired(const Verifier &verifier, voffset_t field) const { bool VerifyFieldRequired(const Verifier &verifier, voffset_t field,
size_t align) const {
auto field_offset = GetOptionalFieldOffset(field); auto field_offset = GetOptionalFieldOffset(field);
return verifier.Check(field_offset != 0) && return verifier.Check(field_offset != 0) &&
verifier.Verify<T>(data_, field_offset); verifier.VerifyField<T>(data_, field_offset, align);
} }
// Versions for offsets. // Versions for offsets.
+32 -5
View File
@@ -17,19 +17,20 @@
#ifndef FLATBUFFERS_UTIL_H_ #ifndef FLATBUFFERS_UTIL_H_
#define FLATBUFFERS_UTIL_H_ #define FLATBUFFERS_UTIL_H_
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include "flatbuffers/base.h" #include "flatbuffers/base.h"
#include "flatbuffers/stl_emulation.h" #include "flatbuffers/stl_emulation.h"
#ifndef FLATBUFFERS_PREFER_PRINTF #ifndef FLATBUFFERS_PREFER_PRINTF
# include <iomanip>
# include <sstream> # include <sstream>
#else // FLATBUFFERS_PREFER_PRINTF #else // FLATBUFFERS_PREFER_PRINTF
# include <float.h> # include <float.h>
# include <stdio.h> # include <stdio.h>
#endif // FLATBUFFERS_PREFER_PRINTF #endif // FLATBUFFERS_PREFER_PRINTF
#include <iomanip>
#include <string> #include <string>
namespace flatbuffers { namespace flatbuffers {
@@ -94,7 +95,7 @@ template<typename T> size_t IntToDigitCount(T t) {
// Count a single 0 left of the dot for fractional numbers // Count a single 0 left of the dot for fractional numbers
if (-1 < t && t < 1) digit_count++; if (-1 < t && t < 1) digit_count++;
// Count digits until fractional part // Count digits until fractional part
T eps = std::numeric_limits<float>::epsilon(); T eps = std::numeric_limits<T>::epsilon();
while (t <= (-1 + eps) || (1 - eps) <= t) { while (t <= (-1 + eps) || (1 - eps) <= t) {
t /= 10; t /= 10;
digit_count++; digit_count++;
@@ -254,7 +255,7 @@ inline void strtoval_impl(double *val, const char *str, char **endptr) {
} }
// UBSAN: double to float is safe if numeric_limits<float>::is_iec559 is true. // UBSAN: double to float is safe if numeric_limits<float>::is_iec559 is true.
__supress_ubsan__("float-cast-overflow") __suppress_ubsan__("float-cast-overflow")
inline void strtoval_impl(float *val, const char *str, char **endptr) { inline void strtoval_impl(float *val, const char *str, char **endptr) {
*val = __strtof_impl(str, endptr); *val = __strtof_impl(str, endptr);
} }
@@ -447,6 +448,9 @@ std::string StripPath(const std::string &filepath);
// Strip the last component of the path + separator. // Strip the last component of the path + separator.
std::string StripFileName(const std::string &filepath); std::string StripFileName(const std::string &filepath);
std::string StripPrefix(const std::string &filepath,
const std::string &prefix_to_remove);
// Concatenates a path with a filename, regardless of whether the path // Concatenates a path with a filename, regardless of whether the path
// ends in a separator or not. // ends in a separator or not.
std::string ConCatPathFileName(const std::string &path, std::string ConCatPathFileName(const std::string &path,
@@ -681,8 +685,31 @@ bool SetGlobalTestLocale(const char *locale_name,
bool ReadEnvironmentVariable(const char *var_name, bool ReadEnvironmentVariable(const char *var_name,
std::string *_value = nullptr); std::string *_value = nullptr);
// MSVC specific: Send all assert reports to STDOUT to prevent CI hangs. enum class Case {
void SetupDefaultCRTReportMode(); kUnknown = 0,
// TheQuickBrownFox
kUpperCamel = 1,
// theQuickBrownFox
kLowerCamel = 2,
// the_quick_brown_fox
kSnake = 3,
// THE_QUICK_BROWN_FOX
kScreamingSnake = 4,
// THEQUICKBROWNFOX
kAllUpper = 5,
// thequickbrownfox
kAllLower = 6,
// the-quick-brown-fox
kDasher = 7,
// THEQuiCKBr_ownFox (or whatever you want, we won't change it)
kKeep = 8,
// the_quick_brown_fox123 (as opposed to the_quick_brown_fox_123)
kSnake2 = 9,
};
// Convert the `input` string of case `input_case` to the specified `output_case`.
std::string ConvertCase(const std::string &input, Case output_case,
Case input_case = Case::kSnake);
} // namespace flatbuffers } // namespace flatbuffers
+19
View File
@@ -19,6 +19,7 @@
#include "flatbuffers/base.h" #include "flatbuffers/base.h"
#include "flatbuffers/buffer.h" #include "flatbuffers/buffer.h"
#include "flatbuffers/stl_emulation.h"
namespace flatbuffers { namespace flatbuffers {
@@ -326,6 +327,24 @@ FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t> make_bytes_span(
return span<const uint8_t>(vec.Data(), vec.size() * sizeof(U)); return span<const uint8_t>(vec.Data(), vec.size() * sizeof(U));
} }
// Convenient helper functions to get a span of any vector, regardless
// of whether it is null or not (the field is not set).
template<class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> *ptr)
FLATBUFFERS_NOEXCEPT {
static_assert(Vector<U>::is_span_observable,
"wrong type U, only LE-scalar, or byte types are allowed");
return ptr ? make_span(*ptr) : span<U>();
}
template<class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
const Vector<U> *ptr) FLATBUFFERS_NOEXCEPT {
static_assert(Vector<U>::is_span_observable,
"wrong type U, only LE-scalar, or byte types are allowed");
return ptr ? make_span(*ptr) : span<const U>();
}
// Represent a vector much like the template above, but in this case we // 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). // don't know what the element types are (used with reflection.h).
class VectorOfAny { class VectorOfAny {
+1 -1
View File
@@ -24,7 +24,7 @@
namespace flatbuffers { namespace flatbuffers {
// This is a minimal replication of std::vector<uint8_t> functionality, // This is a minimal replication of std::vector<uint8_t> functionality,
// except growing from higher to lower addresses. i.e push_back() inserts data // except growing from higher to lower addresses. i.e. push_back() inserts data
// in the lowest address in the vector. // in the lowest address in the vector.
// Since this vector leaves the lower part unused, we support a "scratch-pad" // 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. // that can be stored there for temporary data, to share the allocated space.
+114 -67
View File
@@ -18,7 +18,6 @@
#define FLATBUFFERS_VERIFIER_H_ #define FLATBUFFERS_VERIFIER_H_
#include "flatbuffers/base.h" #include "flatbuffers/base.h"
#include "flatbuffers/util.h"
#include "flatbuffers/vector.h" #include "flatbuffers/vector.h"
namespace flatbuffers { namespace flatbuffers {
@@ -26,21 +25,37 @@ namespace flatbuffers {
// Helper class to verify the integrity of a FlatBuffer // Helper class to verify the integrity of a FlatBuffer
class Verifier FLATBUFFERS_FINAL_CLASS { class Verifier FLATBUFFERS_FINAL_CLASS {
public: public:
Verifier(const uint8_t *buf, size_t buf_len, uoffset_t _max_depth = 64, struct Options {
uoffset_t _max_tables = 1000000, bool _check_alignment = true) // The maximum nesting of tables and vectors before we call it invalid.
: buf_(buf), uoffset_t max_depth = 64;
size_(buf_len), // The maximum number of tables we will verify before we call it invalid.
depth_(0), uoffset_t max_tables = 1000000;
max_depth_(_max_depth), // If true, verify all data is aligned.
num_tables_(0), bool check_alignment = true;
max_tables_(_max_tables), // If true, run verifier on nested flatbuffers
upper_bound_(0), bool check_nested_flatbuffers = true;
check_alignment_(_check_alignment) { };
explicit Verifier(const uint8_t *const buf, const size_t buf_len,
const Options &opts)
: buf_(buf), size_(buf_len), opts_(opts) {
FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE); FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE);
} }
// Deprecated API, please construct with Verifier::Options.
Verifier(const uint8_t *const buf, const size_t buf_len,
const uoffset_t max_depth = 64, const uoffset_t max_tables = 1000000,
const bool check_alignment = true)
: Verifier(buf, buf_len, [&] {
Options opts;
opts.max_depth = max_depth;
opts.max_tables = max_tables;
opts.check_alignment = check_alignment;
return opts;
}()) {}
// Central location where any verification failures register. // Central location where any verification failures register.
bool Check(bool ok) const { bool Check(const bool ok) const {
// clang-format off // clang-format off
#ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE #ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE
FLATBUFFERS_ASSERT(ok); FLATBUFFERS_ASSERT(ok);
@@ -54,7 +69,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
} }
// Verify any range within the buffer. // Verify any range within the buffer.
bool Verify(size_t elem, size_t elem_len) const { bool Verify(const size_t elem, const size_t elem_len) const {
// clang-format off // clang-format off
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
auto upper_bound = elem + elem_len; auto upper_bound = elem + elem_len;
@@ -65,48 +80,52 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return Check(elem_len < size_ && elem <= size_ - elem_len); return Check(elem_len < size_ && elem <= size_ - elem_len);
} }
template<typename T> bool VerifyAlignment(size_t elem) const { bool VerifyAlignment(const size_t elem, const size_t align) const {
return Check((elem & (sizeof(T) - 1)) == 0 || !check_alignment_); return Check((elem & (align - 1)) == 0 || !opts_.check_alignment);
} }
// Verify a range indicated by sizeof(T). // Verify a range indicated by sizeof(T).
template<typename T> bool Verify(size_t elem) const { template<typename T> bool Verify(const size_t elem) const {
return VerifyAlignment<T>(elem) && Verify(elem, sizeof(T)); return VerifyAlignment(elem, sizeof(T)) && Verify(elem, sizeof(T));
} }
bool VerifyFromPointer(const uint8_t *p, size_t len) { bool VerifyFromPointer(const uint8_t *const p, const size_t len) {
auto o = static_cast<size_t>(p - buf_); return Verify(static_cast<size_t>(p - buf_), len);
return Verify(o, len);
} }
// Verify relative to a known-good base pointer. // Verify relative to a known-good base pointer.
bool Verify(const uint8_t *base, voffset_t elem_off, size_t elem_len) const { bool VerifyFieldStruct(const uint8_t *const base, const voffset_t elem_off,
return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len); const size_t elem_len, const size_t align) const {
const auto f = static_cast<size_t>(base - buf_) + elem_off;
return VerifyAlignment(f, align) && Verify(f, elem_len);
} }
template<typename T> template<typename T>
bool Verify(const uint8_t *base, voffset_t elem_off) const { bool VerifyField(const uint8_t *const base, const voffset_t elem_off,
return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T)); const size_t align) const {
const auto f = static_cast<size_t>(base - buf_) + elem_off;
return VerifyAlignment(f, align) && Verify(f, sizeof(T));
} }
// Verify a pointer (may be NULL) of a table type. // Verify a pointer (may be NULL) of a table type.
template<typename T> bool VerifyTable(const T *table) { template<typename T> bool VerifyTable(const T *const table) {
return !table || table->Verify(*this); return !table || table->Verify(*this);
} }
// Verify a pointer (may be NULL) of any vector type. // Verify a pointer (may be NULL) of any vector type.
template<typename T> bool VerifyVector(const Vector<T> *vec) const { template<typename T> bool VerifyVector(const Vector<T> *const vec) const {
return !vec || VerifyVectorOrString(reinterpret_cast<const uint8_t *>(vec), return !vec || VerifyVectorOrString(reinterpret_cast<const uint8_t *>(vec),
sizeof(T)); sizeof(T));
} }
// Verify a pointer (may be NULL) of a vector to struct. // Verify a pointer (may be NULL) of a vector to struct.
template<typename T> bool VerifyVector(const Vector<const T *> *vec) const { template<typename T>
bool VerifyVector(const Vector<const T *> *const vec) const {
return VerifyVector(reinterpret_cast<const Vector<T> *>(vec)); return VerifyVector(reinterpret_cast<const Vector<T> *>(vec));
} }
// Verify a pointer (may be NULL) to string. // Verify a pointer (may be NULL) to string.
bool VerifyString(const String *str) const { bool VerifyString(const String *const str) const {
size_t end; size_t end;
return !str || (VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str), return !str || (VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str),
1, &end) && 1, &end) &&
@@ -115,24 +134,24 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
} }
// Common code between vectors and strings. // Common code between vectors and strings.
bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size, bool VerifyVectorOrString(const uint8_t *const vec, const size_t elem_size,
size_t *end = nullptr) const { size_t *const end = nullptr) const {
auto veco = static_cast<size_t>(vec - buf_); const auto veco = static_cast<size_t>(vec - buf_);
// Check we can read the size field. // 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 // Check the whole array. If this is a string, the byte past the array must
// must be 0. // be 0.
auto size = ReadScalar<uoffset_t>(vec); const auto size = ReadScalar<uoffset_t>(vec);
auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size; const auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size;
if (!Check(size < max_elems)) if (!Check(size < max_elems))
return false; // Protect against byte_size overflowing. return false; // Protect against byte_size overflowing.
auto byte_size = sizeof(size) + elem_size * size; const auto byte_size = sizeof(size) + elem_size * size;
if (end) *end = veco + byte_size; if (end) *end = veco + byte_size;
return Verify(veco, byte_size); return Verify(veco, byte_size);
} }
// Special case for string contents, after the above has been called. // Special case for string contents, after the above has been called.
bool VerifyVectorOfStrings(const Vector<Offset<String>> *vec) const { bool VerifyVectorOfStrings(const Vector<Offset<String>> *const vec) const {
if (vec) { if (vec) {
for (uoffset_t i = 0; i < vec->size(); i++) { for (uoffset_t i = 0; i < vec->size(); i++) {
if (!VerifyString(vec->Get(i))) return false; if (!VerifyString(vec->Get(i))) return false;
@@ -142,7 +161,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
} }
// Special case for table contents, after the above has been called. // Special case for table contents, after the above has been called.
template<typename T> bool VerifyVectorOfTables(const Vector<Offset<T>> *vec) { template<typename T>
bool VerifyVectorOfTables(const Vector<Offset<T>> *const vec) {
if (vec) { if (vec) {
for (uoffset_t i = 0; i < vec->size(); i++) { for (uoffset_t i = 0; i < vec->size(); i++) {
if (!vec->Get(i)->Verify(*this)) return false; if (!vec->Get(i)->Verify(*this)) return false;
@@ -151,30 +171,41 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return true; return true;
} }
__supress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart( __suppress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart(
const uint8_t *table) { const uint8_t *const table) {
// Check the vtable offset. // Check the vtable offset.
auto tableo = static_cast<size_t>(table - buf_); const auto tableo = static_cast<size_t>(table - buf_);
if (!Verify<soffset_t>(tableo)) return false; if (!Verify<soffset_t>(tableo)) return false;
// This offset may be signed, but doing the subtraction unsigned always // This offset may be signed, but doing the subtraction unsigned always
// gives the result we want. // gives the result we want.
auto vtableo = tableo - static_cast<size_t>(ReadScalar<soffset_t>(table)); const auto vtableo =
tableo - static_cast<size_t>(ReadScalar<soffset_t>(table));
// Check the vtable size field, then check vtable fits in its entirety. // Check the vtable size field, then check vtable fits in its entirety.
return VerifyComplexity() && Verify<voffset_t>(vtableo) && if (!(VerifyComplexity() && Verify<voffset_t>(vtableo) &&
VerifyAlignment<voffset_t>(ReadScalar<voffset_t>(buf_ + vtableo)) && VerifyAlignment(ReadScalar<voffset_t>(buf_ + vtableo),
Verify(vtableo, ReadScalar<voffset_t>(buf_ + vtableo)); sizeof(voffset_t))))
return false;
const auto vsize = ReadScalar<voffset_t>(buf_ + vtableo);
return Check((vsize & 1) == 0) && Verify(vtableo, vsize);
} }
template<typename T> template<typename T>
bool VerifyBufferFromStart(const char *identifier, size_t start) { bool VerifyBufferFromStart(const char *const identifier, const size_t start) {
// Buffers have to be of some size to be valid. The reason it is a runtime
// check instead of static_assert, is that nested flatbuffers go through
// this call and their size is determined at runtime.
if (!Check(size_ >= FLATBUFFERS_MIN_BUFFER_SIZE)) return false;
// If an identifier is provided, check that we have a buffer
if (identifier && !Check((size_ >= 2 * sizeof(flatbuffers::uoffset_t) && if (identifier && !Check((size_ >= 2 * sizeof(flatbuffers::uoffset_t) &&
BufferHasIdentifier(buf_ + start, identifier)))) { BufferHasIdentifier(buf_ + start, identifier)))) {
return false; return false;
} }
// Call T::Verify, which must be in the generated code for this type. // Call T::Verify, which must be in the generated code for this type.
auto o = VerifyOffset(start); const auto o = VerifyOffset(start);
return o && reinterpret_cast<const T *>(buf_ + start + o)->Verify(*this) return Check(o != 0) &&
reinterpret_cast<const T *>(buf_ + start + o)->Verify(*this)
// clang-format off // clang-format off
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
&& GetComputedSize() && GetComputedSize()
@@ -184,9 +215,17 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
} }
template<typename T> template<typename T>
bool VerifyNestedFlatBuffer(const Vector<uint8_t> *buf, bool VerifyNestedFlatBuffer(const Vector<uint8_t> *const buf,
const char *identifier) { const char *const identifier) {
// Caller opted out of this.
if (!opts_.check_nested_flatbuffers) return true;
// An empty buffer is OK as it indicates not present.
if (!buf) return true; if (!buf) return true;
// If there is a nested buffer, it must be greater than the min size.
if (!Check(buf->size() >= FLATBUFFERS_MIN_BUFFER_SIZE)) return false;
Verifier nested_verifier(buf->data(), buf->size()); Verifier nested_verifier(buf->data(), buf->size());
return nested_verifier.VerifyBuffer<T>(identifier); return nested_verifier.VerifyBuffer<T>(identifier);
} }
@@ -194,19 +233,20 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
// Verify this whole buffer, starting with root type T. // Verify this whole buffer, starting with root type T.
template<typename T> bool VerifyBuffer() { return VerifyBuffer<T>(nullptr); } template<typename T> bool VerifyBuffer() { return VerifyBuffer<T>(nullptr); }
template<typename T> bool VerifyBuffer(const char *identifier) { template<typename T> bool VerifyBuffer(const char *const identifier) {
return VerifyBufferFromStart<T>(identifier, 0); return VerifyBufferFromStart<T>(identifier, 0);
} }
template<typename T> bool VerifySizePrefixedBuffer(const char *identifier) { template<typename T>
bool VerifySizePrefixedBuffer(const char *const identifier) {
return Verify<uoffset_t>(0U) && return Verify<uoffset_t>(0U) &&
ReadScalar<uoffset_t>(buf_) == size_ - sizeof(uoffset_t) && Check(ReadScalar<uoffset_t>(buf_) == size_ - sizeof(uoffset_t)) &&
VerifyBufferFromStart<T>(identifier, sizeof(uoffset_t)); VerifyBufferFromStart<T>(identifier, sizeof(uoffset_t));
} }
uoffset_t VerifyOffset(size_t start) const { uoffset_t VerifyOffset(const size_t start) const {
if (!Verify<uoffset_t>(start)) return 0; if (!Verify<uoffset_t>(start)) return 0;
auto o = ReadScalar<uoffset_t>(buf_ + start); const auto o = ReadScalar<uoffset_t>(buf_ + start);
// May not point to itself. // May not point to itself.
if (!Check(o != 0)) return 0; if (!Check(o != 0)) return 0;
// Can't wrap around / buffers are max 2GB. // Can't wrap around / buffers are max 2GB.
@@ -217,18 +257,18 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return o; return o;
} }
uoffset_t VerifyOffset(const uint8_t *base, voffset_t start) const { uoffset_t VerifyOffset(const uint8_t *const base,
const voffset_t start) const {
return VerifyOffset(static_cast<size_t>(base - buf_) + start); return VerifyOffset(static_cast<size_t>(base - buf_) + start);
} }
// Called at the start of a table to increase counters measuring data // Called at the start of a table to increase counters measuring data
// structure depth and amount, and possibly bails out with false if // structure depth and amount, and possibly bails out with false if limits set
// limits set by the constructor have been hit. Needs to be balanced // by the constructor have been hit. Needs to be balanced with EndTable().
// with EndTable().
bool VerifyComplexity() { bool VerifyComplexity() {
depth_++; depth_++;
num_tables_++; num_tables_++;
return Check(depth_ <= max_depth_ && num_tables_ <= max_tables_); return Check(depth_ <= opts_.max_depth && num_tables_ <= opts_.max_tables);
} }
// Called at the end of a table to pop the depth count. // Called at the end of a table to pop the depth count.
@@ -254,15 +294,22 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
// clang-format on // clang-format on
} }
std::vector<uint8_t> *GetFlexReuseTracker() { return flex_reuse_tracker_; }
void SetFlexReuseTracker(std::vector<uint8_t> *const rt) {
flex_reuse_tracker_ = rt;
}
private: private:
const uint8_t *buf_; const uint8_t *buf_;
size_t size_; const size_t size_;
uoffset_t depth_; const Options opts_;
uoffset_t max_depth_;
uoffset_t num_tables_; mutable size_t upper_bound_ = 0;
uoffset_t max_tables_;
mutable size_t upper_bound_; uoffset_t depth_ = 0;
bool check_alignment_; uoffset_t num_tables_ = 0;
std::vector<uint8_t> *flex_reuse_tracker_ = nullptr;
}; };
} // namespace flatbuffers } // namespace flatbuffers
+10 -3
View File
@@ -6,6 +6,13 @@
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 22 &&
FLATBUFFERS_VERSION_MINOR == 9 &&
FLATBUFFERS_VERSION_REVISION == 29,
"Non-compatible flatbuffers version included");
#include "header_generated.h" #include "header_generated.h"
namespace FlatGeobuf { namespace FlatGeobuf {
@@ -66,7 +73,7 @@ struct Geometry FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
verifier.VerifyVector(t()) && verifier.VerifyVector(t()) &&
VerifyOffset(verifier, VT_TM) && VerifyOffset(verifier, VT_TM) &&
verifier.VerifyVector(tm()) && verifier.VerifyVector(tm()) &&
VerifyField<uint8_t>(verifier, VT_TYPE) && VerifyField<uint8_t>(verifier, VT_TYPE, 1) &&
VerifyOffset(verifier, VT_PARTS) && VerifyOffset(verifier, VT_PARTS) &&
verifier.VerifyVector(parts()) && verifier.VerifyVector(parts()) &&
verifier.VerifyVectorOfTables(parts()) && verifier.VerifyVectorOfTables(parts()) &&
@@ -121,7 +128,7 @@ inline flatbuffers::Offset<Geometry> CreateGeometry(
flatbuffers::Offset<flatbuffers::Vector<double>> m = 0, flatbuffers::Offset<flatbuffers::Vector<double>> m = 0,
flatbuffers::Offset<flatbuffers::Vector<double>> t = 0, flatbuffers::Offset<flatbuffers::Vector<double>> t = 0,
flatbuffers::Offset<flatbuffers::Vector<uint64_t>> tm = 0, flatbuffers::Offset<flatbuffers::Vector<uint64_t>> tm = 0,
FlatGeobuf::GeometryType type = FlatGeobuf::GeometryType::Unknown, FlatGeobuf::GeometryType type = FlatGeobuf::GeometryType_Unknown,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<FlatGeobuf::Geometry>>> parts = 0) { flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<FlatGeobuf::Geometry>>> parts = 0) {
GeometryBuilder builder_(_fbb); GeometryBuilder builder_(_fbb);
builder_.add_parts(parts); builder_.add_parts(parts);
@@ -143,7 +150,7 @@ inline flatbuffers::Offset<Geometry> CreateGeometryDirect(
const std::vector<double> *m = nullptr, const std::vector<double> *m = nullptr,
const std::vector<double> *t = nullptr, const std::vector<double> *t = nullptr,
const std::vector<uint64_t> *tm = nullptr, const std::vector<uint64_t> *tm = nullptr,
FlatGeobuf::GeometryType type = FlatGeobuf::GeometryType::Unknown, FlatGeobuf::GeometryType type = FlatGeobuf::GeometryType_Unknown,
const std::vector<flatbuffers::Offset<FlatGeobuf::Geometry>> *parts = nullptr) { const std::vector<flatbuffers::Offset<FlatGeobuf::Geometry>> *parts = nullptr) {
auto ends__ = ends ? _fbb.CreateVector<uint32_t>(*ends) : 0; auto ends__ = ends ? _fbb.CreateVector<uint32_t>(*ends) : 0;
auto xy__ = xy ? _fbb.CreateVector<double>(*xy) : 0; auto xy__ = xy ? _fbb.CreateVector<double>(*xy) : 0;
+100 -93
View File
@@ -6,6 +6,13 @@
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 22 &&
FLATBUFFERS_VERSION_MINOR == 9 &&
FLATBUFFERS_VERSION_REVISION == 29,
"Non-compatible flatbuffers version included");
namespace FlatGeobuf { namespace FlatGeobuf {
struct Column; struct Column;
@@ -17,49 +24,49 @@ struct CrsBuilder;
struct Header; struct Header;
struct HeaderBuilder; struct HeaderBuilder;
enum class GeometryType : uint8_t { enum GeometryType : uint8_t {
Unknown = 0, GeometryType_Unknown = 0,
Point = 1, GeometryType_Point = 1,
LineString = 2, GeometryType_LineString = 2,
Polygon = 3, GeometryType_Polygon = 3,
MultiPoint = 4, GeometryType_MultiPoint = 4,
MultiLineString = 5, GeometryType_MultiLineString = 5,
MultiPolygon = 6, GeometryType_MultiPolygon = 6,
GeometryCollection = 7, GeometryType_GeometryCollection = 7,
CircularString = 8, GeometryType_CircularString = 8,
CompoundCurve = 9, GeometryType_CompoundCurve = 9,
CurvePolygon = 10, GeometryType_CurvePolygon = 10,
MultiCurve = 11, GeometryType_MultiCurve = 11,
MultiSurface = 12, GeometryType_MultiSurface = 12,
Curve = 13, GeometryType_Curve = 13,
Surface = 14, GeometryType_Surface = 14,
PolyhedralSurface = 15, GeometryType_PolyhedralSurface = 15,
TIN = 16, GeometryType_TIN = 16,
Triangle = 17, GeometryType_Triangle = 17,
MIN = Unknown, GeometryType_MIN = GeometryType_Unknown,
MAX = Triangle GeometryType_MAX = GeometryType_Triangle
}; };
inline const GeometryType (&EnumValuesGeometryType())[18] { inline const GeometryType (&EnumValuesGeometryType())[18] {
static const GeometryType values[] = { static const GeometryType values[] = {
GeometryType::Unknown, GeometryType_Unknown,
GeometryType::Point, GeometryType_Point,
GeometryType::LineString, GeometryType_LineString,
GeometryType::Polygon, GeometryType_Polygon,
GeometryType::MultiPoint, GeometryType_MultiPoint,
GeometryType::MultiLineString, GeometryType_MultiLineString,
GeometryType::MultiPolygon, GeometryType_MultiPolygon,
GeometryType::GeometryCollection, GeometryType_GeometryCollection,
GeometryType::CircularString, GeometryType_CircularString,
GeometryType::CompoundCurve, GeometryType_CompoundCurve,
GeometryType::CurvePolygon, GeometryType_CurvePolygon,
GeometryType::MultiCurve, GeometryType_MultiCurve,
GeometryType::MultiSurface, GeometryType_MultiSurface,
GeometryType::Curve, GeometryType_Curve,
GeometryType::Surface, GeometryType_Surface,
GeometryType::PolyhedralSurface, GeometryType_PolyhedralSurface,
GeometryType::TIN, GeometryType_TIN,
GeometryType::Triangle GeometryType_Triangle
}; };
return values; return values;
} }
@@ -90,48 +97,48 @@ inline const char * const *EnumNamesGeometryType() {
} }
inline const char *EnumNameGeometryType(GeometryType e) { inline const char *EnumNameGeometryType(GeometryType e) {
if (flatbuffers::IsOutRange(e, GeometryType::Unknown, GeometryType::Triangle)) return ""; if (flatbuffers::IsOutRange(e, GeometryType_Unknown, GeometryType_Triangle)) return "";
const size_t index = static_cast<size_t>(e); const size_t index = static_cast<size_t>(e);
return EnumNamesGeometryType()[index]; return EnumNamesGeometryType()[index];
} }
enum class ColumnType : uint8_t { enum ColumnType : uint8_t {
Byte = 0, ColumnType_Byte = 0,
UByte = 1, ColumnType_UByte = 1,
Bool = 2, ColumnType_Bool = 2,
Short = 3, ColumnType_Short = 3,
UShort = 4, ColumnType_UShort = 4,
Int = 5, ColumnType_Int = 5,
UInt = 6, ColumnType_UInt = 6,
Long = 7, ColumnType_Long = 7,
ULong = 8, ColumnType_ULong = 8,
Float = 9, ColumnType_Float = 9,
Double = 10, ColumnType_Double = 10,
String = 11, ColumnType_String = 11,
Json = 12, ColumnType_Json = 12,
DateTime = 13, ColumnType_DateTime = 13,
Binary = 14, ColumnType_Binary = 14,
MIN = Byte, ColumnType_MIN = ColumnType_Byte,
MAX = Binary ColumnType_MAX = ColumnType_Binary
}; };
inline const ColumnType (&EnumValuesColumnType())[15] { inline const ColumnType (&EnumValuesColumnType())[15] {
static const ColumnType values[] = { static const ColumnType values[] = {
ColumnType::Byte, ColumnType_Byte,
ColumnType::UByte, ColumnType_UByte,
ColumnType::Bool, ColumnType_Bool,
ColumnType::Short, ColumnType_Short,
ColumnType::UShort, ColumnType_UShort,
ColumnType::Int, ColumnType_Int,
ColumnType::UInt, ColumnType_UInt,
ColumnType::Long, ColumnType_Long,
ColumnType::ULong, ColumnType_ULong,
ColumnType::Float, ColumnType_Float,
ColumnType::Double, ColumnType_Double,
ColumnType::String, ColumnType_String,
ColumnType::Json, ColumnType_Json,
ColumnType::DateTime, ColumnType_DateTime,
ColumnType::Binary ColumnType_Binary
}; };
return values; return values;
} }
@@ -159,7 +166,7 @@ inline const char * const *EnumNamesColumnType() {
} }
inline const char *EnumNameColumnType(ColumnType e) { inline const char *EnumNameColumnType(ColumnType e) {
if (flatbuffers::IsOutRange(e, ColumnType::Byte, ColumnType::Binary)) return ""; if (flatbuffers::IsOutRange(e, ColumnType_Byte, ColumnType_Binary)) return "";
const size_t index = static_cast<size_t>(e); const size_t index = static_cast<size_t>(e);
return EnumNamesColumnType()[index]; return EnumNamesColumnType()[index];
} }
@@ -216,17 +223,17 @@ struct Column FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
return VerifyTableStart(verifier) && return VerifyTableStart(verifier) &&
VerifyOffsetRequired(verifier, VT_NAME) && VerifyOffsetRequired(verifier, VT_NAME) &&
verifier.VerifyString(name()) && verifier.VerifyString(name()) &&
VerifyField<uint8_t>(verifier, VT_TYPE) && VerifyField<uint8_t>(verifier, VT_TYPE, 1) &&
VerifyOffset(verifier, VT_TITLE) && VerifyOffset(verifier, VT_TITLE) &&
verifier.VerifyString(title()) && verifier.VerifyString(title()) &&
VerifyOffset(verifier, VT_DESCRIPTION) && VerifyOffset(verifier, VT_DESCRIPTION) &&
verifier.VerifyString(description()) && verifier.VerifyString(description()) &&
VerifyField<int32_t>(verifier, VT_WIDTH) && VerifyField<int32_t>(verifier, VT_WIDTH, 4) &&
VerifyField<int32_t>(verifier, VT_PRECISION) && VerifyField<int32_t>(verifier, VT_PRECISION, 4) &&
VerifyField<int32_t>(verifier, VT_SCALE) && VerifyField<int32_t>(verifier, VT_SCALE, 4) &&
VerifyField<uint8_t>(verifier, VT_NULLABLE) && VerifyField<uint8_t>(verifier, VT_NULLABLE, 1) &&
VerifyField<uint8_t>(verifier, VT_UNIQUE) && VerifyField<uint8_t>(verifier, VT_UNIQUE, 1) &&
VerifyField<uint8_t>(verifier, VT_PRIMARY_KEY) && VerifyField<uint8_t>(verifier, VT_PRIMARY_KEY, 1) &&
VerifyOffset(verifier, VT_METADATA) && VerifyOffset(verifier, VT_METADATA) &&
verifier.VerifyString(metadata()) && verifier.VerifyString(metadata()) &&
verifier.EndTable(); verifier.EndTable();
@@ -285,7 +292,7 @@ struct ColumnBuilder {
inline flatbuffers::Offset<Column> CreateColumn( inline flatbuffers::Offset<Column> CreateColumn(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0, flatbuffers::Offset<flatbuffers::String> name = 0,
FlatGeobuf::ColumnType type = FlatGeobuf::ColumnType::Byte, FlatGeobuf::ColumnType type = FlatGeobuf::ColumnType_Byte,
flatbuffers::Offset<flatbuffers::String> title = 0, flatbuffers::Offset<flatbuffers::String> title = 0,
flatbuffers::Offset<flatbuffers::String> description = 0, flatbuffers::Offset<flatbuffers::String> description = 0,
int32_t width = -1, int32_t width = -1,
@@ -313,7 +320,7 @@ inline flatbuffers::Offset<Column> CreateColumn(
inline flatbuffers::Offset<Column> CreateColumnDirect( inline flatbuffers::Offset<Column> CreateColumnDirect(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr, const char *name = nullptr,
FlatGeobuf::ColumnType type = FlatGeobuf::ColumnType::Byte, FlatGeobuf::ColumnType type = FlatGeobuf::ColumnType_Byte,
const char *title = nullptr, const char *title = nullptr,
const char *description = nullptr, const char *description = nullptr,
int32_t width = -1, int32_t width = -1,
@@ -374,7 +381,7 @@ struct Crs FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
return VerifyTableStart(verifier) && return VerifyTableStart(verifier) &&
VerifyOffset(verifier, VT_ORG) && VerifyOffset(verifier, VT_ORG) &&
verifier.VerifyString(org()) && verifier.VerifyString(org()) &&
VerifyField<int32_t>(verifier, VT_CODE) && VerifyField<int32_t>(verifier, VT_CODE, 4) &&
VerifyOffset(verifier, VT_NAME) && VerifyOffset(verifier, VT_NAME) &&
verifier.VerifyString(name()) && verifier.VerifyString(name()) &&
VerifyOffset(verifier, VT_DESCRIPTION) && VerifyOffset(verifier, VT_DESCRIPTION) &&
@@ -527,16 +534,16 @@ struct Header FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
verifier.VerifyString(name()) && verifier.VerifyString(name()) &&
VerifyOffset(verifier, VT_ENVELOPE) && VerifyOffset(verifier, VT_ENVELOPE) &&
verifier.VerifyVector(envelope()) && verifier.VerifyVector(envelope()) &&
VerifyField<uint8_t>(verifier, VT_GEOMETRY_TYPE) && VerifyField<uint8_t>(verifier, VT_GEOMETRY_TYPE, 1) &&
VerifyField<uint8_t>(verifier, VT_HAS_Z) && VerifyField<uint8_t>(verifier, VT_HAS_Z, 1) &&
VerifyField<uint8_t>(verifier, VT_HAS_M) && VerifyField<uint8_t>(verifier, VT_HAS_M, 1) &&
VerifyField<uint8_t>(verifier, VT_HAS_T) && VerifyField<uint8_t>(verifier, VT_HAS_T, 1) &&
VerifyField<uint8_t>(verifier, VT_HAS_TM) && VerifyField<uint8_t>(verifier, VT_HAS_TM, 1) &&
VerifyOffset(verifier, VT_COLUMNS) && VerifyOffset(verifier, VT_COLUMNS) &&
verifier.VerifyVector(columns()) && verifier.VerifyVector(columns()) &&
verifier.VerifyVectorOfTables(columns()) && verifier.VerifyVectorOfTables(columns()) &&
VerifyField<uint64_t>(verifier, VT_FEATURES_COUNT) && VerifyField<uint64_t>(verifier, VT_FEATURES_COUNT, 8) &&
VerifyField<uint16_t>(verifier, VT_INDEX_NODE_SIZE) && VerifyField<uint16_t>(verifier, VT_INDEX_NODE_SIZE, 2) &&
VerifyOffset(verifier, VT_CRS) && VerifyOffset(verifier, VT_CRS) &&
verifier.VerifyTable(crs()) && verifier.VerifyTable(crs()) &&
VerifyOffset(verifier, VT_TITLE) && VerifyOffset(verifier, VT_TITLE) &&
@@ -610,7 +617,7 @@ inline flatbuffers::Offset<Header> CreateHeader(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0, flatbuffers::Offset<flatbuffers::String> name = 0,
flatbuffers::Offset<flatbuffers::Vector<double>> envelope = 0, flatbuffers::Offset<flatbuffers::Vector<double>> envelope = 0,
FlatGeobuf::GeometryType geometry_type = FlatGeobuf::GeometryType::Unknown, FlatGeobuf::GeometryType geometry_type = FlatGeobuf::GeometryType_Unknown,
bool has_z = false, bool has_z = false,
bool has_m = false, bool has_m = false,
bool has_t = false, bool has_t = false,
@@ -644,7 +651,7 @@ inline flatbuffers::Offset<Header> CreateHeaderDirect(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr, const char *name = nullptr,
const std::vector<double> *envelope = nullptr, const std::vector<double> *envelope = nullptr,
FlatGeobuf::GeometryType geometry_type = FlatGeobuf::GeometryType::Unknown, FlatGeobuf::GeometryType geometry_type = FlatGeobuf::GeometryType_Unknown,
bool has_z = false, bool has_z = false,
bool has_m = false, bool has_m = false,
bool has_t = false, bool has_t = false,