17 #ifndef FLATBUFFERS_H_
18 #define FLATBUFFERS_H_
23 #ifndef FLATBUFFERS_CPP98_STL
27 #if defined(FLATBUFFERS_NAN_DEFAULTS)
42 #if defined(FLATBUFFERS_NAN_DEFAULTS) && defined(FLATBUFFERS_HAS_NEW_STRTOD) && \
43 (FLATBUFFERS_HAS_NEW_STRTOD > 0)
46 inline bool IsFloatTheSameAs(T e, T def)
48 return (e == def) || ((def != def) && (e != e));
51 inline bool IsTheSameAs<float>(
float e,
float def)
53 return IsFloatTheSameAs(e, def);
56 inline bool IsTheSameAs<double>(
double e,
double def)
58 return IsFloatTheSameAs(e, def);
66 inline bool IsOutRange(
const T& v,
const T& low,
const T& high)
68 return (v < low) || (high < v);
73 inline bool IsInRange(
const T& v,
const T& low,
const T& high)
102 FLATBUFFERS_ASSERT(*
reinterpret_cast<char*
>(&endiantest) == FLATBUFFERS_LITTLEENDIAN);
106 template <
typename T>
114 return __alignof__(T);
130 template <
typename T>
138 return EndianScalar((
reinterpret_cast<const T*
>(p))[i]);
141 template <
typename T>
149 p += i *
sizeof(uoffset_t);
150 return reinterpret_cast<return_type>(p + ReadScalar<uoffset_t>(p));
153 template <
typename T>
158 static const size_t element_stride =
sizeof(T);
159 static return_type
Read(
const uint8_t* p, uoffset_t i)
161 return reinterpret_cast<const T*
>(p + i *
sizeof(T));
167 template <
typename T,
typename IT>
191 #if !defined(FLATBUFFERS_CPP98_STL)
196 #endif // !defined(FLATBUFFERS_CPP98_STL)
281 template <
typename Iterator>
289 return *(std::reverse_iterator<Iterator>::current);
294 return *(std::reverse_iterator<Iterator>::current);
302 template <
typename T>
318 uoffset_t Length()
const
341 template <
typename E>
344 return static_cast<E
>(
Get(i));
349 template <
typename U>
352 return reinterpret_cast<const U*
>(
Get(i));
359 return reinterpret_cast<const String*
>(
Get(i));
364 return reinterpret_cast<const void*
>(
Data() + o);
428 WriteScalar(
data() + i, val);
437 static_assert(
sizeof(T) ==
sizeof(uoffset_t),
"Unrelated types");
438 WriteScalar(
data() + i,
439 static_cast<uoffset_t
>(val - (
Data() + i *
sizeof(uoffset_t))));
452 return reinterpret_cast<const uint8_t*
>(&
length_ + 1);
457 return reinterpret_cast<uint8_t*
>(&
length_ + 1);
463 return reinterpret_cast<const T*
>(
Data());
467 return reinterpret_cast<T*
>(
Data());
470 template <
typename K>
473 void* search_result = std::bsearch(&key,
Data(),
size(),
481 const uint8_t* element =
reinterpret_cast<const uint8_t*
>(search_result);
499 template <
typename K>
502 const K* key =
reinterpret_cast<const K*
>(ap);
503 const uint8_t*
data =
reinterpret_cast<const uint8_t*
>(bp);
508 return -table->KeyCompareWithValue(*key);
524 return reinterpret_cast<const uint8_t*
>(&
length_ + 1);
528 return reinterpret_cast<uint8_t*
>(&
length_ + 1);
541 #ifndef FLATBUFFERS_CPP98_STL
542 template <
typename T,
typename U>
545 static_assert(std::is_base_of<T, U>::value,
"Unrelated types");
549 template <
typename T,
typename U>
552 static_assert(std::is_base_of<T, U>::value,
"Unrelated types");
559 template <
typename T>
562 return v ? v->
size() : 0;
566 template <
typename T, u
int16_t length>
580 FLATBUFFERS_CONSTEXPR uint16_t
size()
const
599 template <
typename E>
602 return static_cast<E
>(
Get(i));
650 return const_cast<T*
>(&
data()[i]);
673 return reinterpret_cast<const T*
>(
Data());
677 return reinterpret_cast<T*
>(
Data());
684 const auto p1 =
reinterpret_cast<const uint8_t*
>(src.data());
685 const auto p2 =
Data();
687 !(p2 >= p1 && p2 < (p1 + length)));
693 !scalar_tag::value ||
sizeof(T) == 1 || FLATBUFFERS_LITTLEENDIAN > (), src);
700 WriteScalar(
data() + i, val);
709 flatbuffers::span<const T, length> src)
714 std::memcpy(
data(), src.data(), length *
sizeof(T));
719 flatbuffers::span<const T, length> src)
732 #if defined(__cpp_constexpr)
749 template <
typename T, u
int16_t length>
780 template <
typename T, u
int16_t length>
786 template <
typename T, u
int16_t length>
792 template <
typename E,
typename T, u
int16_t length>
795 static_assert(
sizeof(E) ==
sizeof(T),
"invalid enum type E");
799 template <
typename E,
typename T, u
int16_t length>
802 static_assert(
sizeof(E) ==
sizeof(T),
"invalid enum type E");
809 const char* b_data, uoffset_t b_size)
811 const auto cmp = memcmp(a_data, b_data, (std::min)(a_size, b_size));
812 return cmp == 0 ? a_size < b_size : cmp < 0;
819 return reinterpret_cast<const char*
>(
Data());
827 #ifdef FLATBUFFERS_HAS_STRING_VIEW
828 flatbuffers::string_view string_view()
const {
829 return flatbuffers::string_view(
c_str(),
size());
831 #endif // FLATBUFFERS_HAS_STRING_VIEW
844 return str ? str->
str() :
"";
851 return str ? str->
c_str() :
"";
854 #ifdef FLATBUFFERS_HAS_STRING_VIEW
857 static inline flatbuffers::string_view GetStringView(
const String* str)
859 return str ? str->string_view() : flatbuffers::string_view();
861 #endif // FLATBUFFERS_HAS_STRING_VIEW
872 virtual uint8_t*
allocate(
size_t size) = 0;
875 virtual void deallocate(uint8_t* p,
size_t size) = 0;
883 size_t in_use_back,
size_t in_use_front)
886 uint8_t* new_p =
allocate(new_size);
887 memcpy_downward(old_p, old_size, new_p, new_size, in_use_back, in_use_front);
897 void memcpy_downward(uint8_t* old_p,
size_t old_size, uint8_t* new_p,
size_t new_size,
898 size_t in_use_back,
size_t in_use_front)
900 memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back, in_use_back);
901 memcpy(new_p, old_p, in_use_front);
909 uint8_t*
allocate(
size_t size) FLATBUFFERS_OVERRIDE
911 return new uint8_t[size];
921 delete[]
static_cast<uint8_t*
>(p);
943 size_t new_size,
size_t in_use_back,
947 in_use_back, in_use_front) :
949 in_use_back, in_use_front);
968 uint8_t* cur,
size_t sz) :
978 #if !defined(FLATBUFFERS_CPP98_STL)
991 #endif // !defined(FLATBUFFERS_CPP98_STL)
995 #if !defined(FLATBUFFERS_CPP98_STL)
1009 size_ = other.size_;
1016 #endif // !defined(FLATBUFFERS_CPP98_STL)
1040 #if 0 // disabled for now due to the ordering of classes in this header
1042 bool Verify()
const {
1044 return verifier.Verify<T>(
nullptr);
1048 const T* GetRoot()
const {
1049 return flatbuffers::GetRoot<T>(
data());
1054 return flatbuffers::GetRoot<T>(
data());
1060 #if !defined(FLATBUFFERS_CPP98_STL)
1066 #endif // !defined(FLATBUFFERS_CPP98_STL)
1109 size_t buffer_minalign) :
1121 #if !defined(FLATBUFFERS_CPP98_STL)
1125 #endif // defined(FLATBUFFERS_CPP98_STL)
1142 other.
buf_ =
nullptr;
1143 other.
cur_ =
nullptr;
1148 #if !defined(FLATBUFFERS_CPP98_STL)
1158 #endif // defined(FLATBUFFERS_CPP98_STL)
1214 offset =
static_cast<size_t>(
cur_ -
buf_);
1302 void push(
const uint8_t* bytes,
size_t num)
1311 template <
typename T>
1315 *
reinterpret_cast<T*
>(
cur_) = little_endian_t;
1318 template <
typename T>
1322 *
reinterpret_cast<T*
>(
scratch_) = t;
1331 for (
size_t i = 0; i < zero_pad_bytes; i++)
1339 memset(
make_space(zero_pad_bytes), 0, zero_pad_bytes);
1342 void pop(
size_t bytes_to_remove)
1344 cur_ += bytes_to_remove;
1388 auto old_size =
size();
1410 const int fixed_fields = 2;
1411 return static_cast<voffset_t
>((field_id + fixed_fields) *
sizeof(voffset_t));
1414 template <
typename T,
typename Alloc>
1415 const T*
data(
const std::vector<T, Alloc>& v)
1420 return v.empty() ?
reinterpret_cast<const T*
>(&t) : &v.front();
1422 template <
typename T,
typename Alloc>
1428 return v.empty() ?
reinterpret_cast<T*
>(&t) : &v.front();
1457 bool own_allocator =
false,
1458 size_t buffer_minalign = AlignOf<largest_scalar_t>()) :
1459 buf_(initial_size, allocator, own_allocator, buffer_minalign),
1474 #if !defined(FLATBUFFERS_CPP98_STL)
1478 #endif // #if !defined(FLATBUFFERS_CPP98_STL)
1479 :
buf_(1024,
nullptr,
false, AlignOf<largest_scalar_t>()),
1496 #if !defined(FLATBUFFERS_CPP98_STL)
1507 #endif // defined(FLATBUFFERS_CPP98_STL)
1627 void Finished()
const
1656 void Pad(
size_t num_bytes)
1661 void TrackMinAlign(
size_t elem_size)
1667 void Align(
size_t elem_size)
1669 TrackMinAlign(elem_size);
1673 void PushFlatBuffer(
const uint8_t* bytes,
size_t size)
1675 PushBytes(bytes, size);
1679 void PushBytes(
const uint8_t* bytes,
size_t size)
1684 void PopBytes(
size_t amount)
1689 template <
typename T>
1690 void AssertScalarT()
1697 template <
typename T>
1698 uoffset_t PushElement(T element)
1701 T litle_endian_element = EndianScalar(element);
1707 template <
typename T>
1708 uoffset_t PushElement(Offset<T> off)
1711 return PushElement(ReferTo(off.o));
1716 void TrackField(voffset_t field, uoffset_t off)
1718 FieldLoc fl = {off, field};
1725 template <
typename T>
1726 void AddElement(voffset_t field, T e, T def)
1731 auto off = PushElement(e);
1732 TrackField(field, off);
1735 template <
typename T>
1736 void AddElement(voffset_t field, T e)
1738 auto off = PushElement(e);
1739 TrackField(field, off);
1742 template <
typename T>
1743 void AddOffset(voffset_t field, Offset<T> off)
1747 AddElement(field, ReferTo(off.o),
static_cast<uoffset_t
>(0));
1750 template <
typename T>
1751 void AddStruct(voffset_t field,
const T* structptr)
1755 Align(AlignOf<T>());
1760 void AddStructOffset(voffset_t field, uoffset_t off)
1762 TrackField(field, off);
1768 uoffset_t ReferTo(uoffset_t off)
1771 Align(
sizeof(uoffset_t));
1774 return GetSize() - off +
static_cast<uoffset_t
>(
sizeof(uoffset_t));
1794 uoffset_t StartTable()
1804 uoffset_t EndTable(uoffset_t start)
1810 auto vtableoffsetloc = PushElement<soffset_t>(0);
1819 auto table_object_size = vtableoffsetloc - start;
1822 WriteScalar<voffset_t>(
buf_.
data() +
sizeof(voffset_t),
1823 static_cast<voffset_t
>(table_object_size));
1829 auto field_location =
reinterpret_cast<FieldLoc*
>(it);
1830 auto pos =
static_cast<voffset_t
>(vtableoffsetloc - field_location->off);
1833 WriteScalar<voffset_t>(
buf_.
data() + field_location->id, pos);
1836 auto vt1 =
reinterpret_cast<voffset_t*
>(
buf_.
data());
1837 auto vt1_size = ReadScalar<voffset_t>(vt1);
1844 it +=
sizeof(uoffset_t))
1846 auto vt_offset_ptr =
reinterpret_cast<uoffset_t*
>(it);
1847 auto vt2 =
reinterpret_cast<voffset_t*
>(
buf_.
data_at(*vt_offset_ptr));
1848 auto vt2_size = ReadScalar<voffset_t>(vt2);
1849 if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size))
1851 vt_use = *vt_offset_ptr;
1867 static_cast<soffset_t
>(vt_use) -
static_cast<soffset_t
>(vtableoffsetloc));
1870 return vtableoffsetloc;
1874 uoffset_t EndTable(uoffset_t start, voffset_t )
1876 return EndTable(start);
1881 template <
typename T>
1882 void Required(Offset<T> table, voffset_t field);
1884 uoffset_t StartStruct(
size_t alignment)
1890 uoffset_t EndStruct()
1904 void PreAlign(
size_t len,
size_t alignment)
1906 TrackMinAlign(alignment);
1909 template <
typename T>
1910 void PreAlign(
size_t len)
1913 PreAlign(len,
sizeof(T));
1924 PreAlign<uoffset_t>(len + 1);
1926 PushBytes(
reinterpret_cast<const uint8_t*
>(str), len);
1927 PushElement(
static_cast<uoffset_t
>(len));
1956 #ifdef FLATBUFFERS_HAS_STRING_VIEW
1963 #endif // FLATBUFFERS_HAS_STRING_VIEW
1978 template <
typename T>
1994 auto size_before_string =
buf_.
size();
2011 #ifdef FLATBUFFERS_HAS_STRING_VIEW
2054 uoffset_t EndVector(
size_t len)
2058 return PushElement(
static_cast<uoffset_t
>(len));
2061 void StartVector(
size_t len,
size_t elemsize)
2065 PreAlign<uoffset_t>(len * elemsize);
2066 PreAlign(len * elemsize, elemsize);
2074 void ForceVectorAlignment(
size_t len,
size_t elemsize,
size_t alignment)
2077 PreAlign(len * elemsize, alignment);
2081 void ForceStringAlignment(
size_t len,
size_t alignment)
2084 PreAlign((len + 1) *
sizeof(
char), alignment);
2096 template <
typename T>
2102 StartVector(len,
sizeof(T));
2108 #if FLATBUFFERS_LITTLEENDIAN
2109 PushBytes(
reinterpret_cast<const uint8_t *
>(v), len *
sizeof(T));
2111 if (
sizeof(T) == 1) {
2112 PushBytes(
reinterpret_cast<const uint8_t *
>(v), len);
2114 for (
auto i = len; i > 0; ) {
2115 PushElement(v[--i]);
2123 template <
typename T>
2127 for (
auto i = len; i > 0;)
2129 PushElement(v[--i]);
2140 template <
typename T>
2151 StartVector(v.size(),
sizeof(uint8_t));
2152 for (
auto i = v.size(); i > 0;)
2154 PushElement(
static_cast<uint8_t
>(v[--i]));
2160 #ifndef FLATBUFFERS_CPP98_STL
2169 const std::function<T (
size_t i)> &f) {
2170 std::vector<T> elems(vector_size);
2171 for (
size_t i = 0; i < vector_size; i++) elems[i] = f(i);
2186 template <
typename T,
typename F,
typename S>
2189 std::vector<T> elems(vector_size);
2190 for (
size_t i = 0; i < vector_size; i++)
2191 elems[i] = f(i, state);
2203 std::vector<Offset<String>> offsets(v.size());
2204 for (
size_t i = 0; i < v.size(); i++)
2216 template <
typename T>
2219 StartVector(len *
sizeof(T) / AlignOf<T>(), AlignOf<T>());
2220 PushBytes(
reinterpret_cast<const uint8_t*
>(v),
sizeof(T) * len);
2234 template <
typename T,
typename S>
2236 T((*
const pack_func)(
const S&)))
2239 std::vector<T> vv(len);
2240 std::transform(v, v + len, vv.begin(), pack_func);
2241 return CreateVectorOfStructs<T>(
data(vv), vv.size());
2252 template <
typename T,
typename S>
2255 extern T Pack(
const S&);
2260 #ifndef FLATBUFFERS_CPP98_STL
2270 size_t vector_size,
const std::function<
void(
size_t i, T *)> &filler) {
2271 T* structs = StartVectorOfStructs<T>(vector_size);
2272 for (
size_t i = 0; i < vector_size; i++) {
2276 return EndVectorOfStructs<T>(vector_size);
2290 template <
typename T,
typename F,
typename S>
2293 T* structs = StartVectorOfStructs<T>(vector_size);
2294 for (
size_t i = 0; i < vector_size; i++)
2296 f(i, structs, state);
2299 return EndVectorOfStructs<T>(vector_size);
2308 template <
typename T,
typename Alloc>
2324 template <
typename T,
typename S>
2326 T((*
const pack_func)(
const S&)))
2328 return CreateVectorOfNativeStructs<T, S>(
data(v), v.size(), pack_func);
2339 template <
typename T,
typename S>
2342 return CreateVectorOfNativeStructs<T, S>(
data(v), v.size());
2346 template <
typename T>
2347 struct StructKeyComparator
2349 bool operator()(
const T& a,
const T& b)
const
2351 return a.KeyCompareLessThan(&b);
2354 FLATBUFFERS_DELETE_FUNC(StructKeyComparator&
operator=(
const StructKeyComparator&));
2365 template <
typename T>
2379 template <
typename T,
typename S>
2382 return CreateVectorOfSortedNativeStructs<T, S>(
data(*v), v->size());
2393 template <
typename T>
2396 std::sort(v, v + len, StructKeyComparator<T>());
2409 template <
typename T,
typename S>
2412 extern T Pack(
const S&);
2413 typedef T (*Pack_t)(
const S&);
2414 std::vector<T> vv(len);
2415 std::transform(v, v + len, vv.begin(),
static_cast<Pack_t&
>(Pack));
2416 return CreateVectorOfSortedStructs<T>(vv, len);
2420 template <
typename T>
2421 struct TableKeyComparator
2425 TableKeyComparator(
const TableKeyComparator& other) :
buf_(other.
buf_)
2427 bool operator()(
const Offset<T>& a,
const Offset<T>& b)
const
2429 auto table_a =
reinterpret_cast<T*
>(
buf_.
data_at(a.o));
2430 auto table_b =
reinterpret_cast<T*
>(
buf_.
data_at(b.o));
2431 return table_a->KeyCompareLessThan(table_b);
2433 vector_downward&
buf_;
2436 FLATBUFFERS_DELETE_FUNC(
2437 TableKeyComparator&
operator=(
const TableKeyComparator& other));
2449 template <
typename T>
2452 std::sort(v, v + len, TableKeyComparator<T>(
buf_));
2463 template <
typename T>
2479 StartVector(len, elemsize);
2482 auto vec_end = EndVector(len);
2495 template <
typename T>
2502 template <
typename T>
2511 template <
typename T,
typename U>
2516 StartVector(len,
sizeof(T));
2517 for (
auto i = len; i > 0;)
2519 PushElement(
static_cast<T
>(v[--i]));
2525 template <
typename T>
2529 Align(AlignOf<T>());
2540 template <
typename T>
2543 Finish(root.
o, file_identifier,
false);
2553 template <
typename T>
2556 Finish(root.
o, file_identifier,
true);
2569 void Finish(uoffset_t root,
const char* file_identifier,
bool size_prefix)
2574 PreAlign((size_prefix ?
sizeof(uoffset_t) : 0) +
sizeof(uoffset_t) +
2577 if (file_identifier)
2582 PushElement(ReferTo(root));
2625 return StringLessThan(stra->data(), stra->size(), strb->data(), strb->size());
2637 template <
typename T>
2640 StartVector(vector_size *
sizeof(T) / AlignOf<T>(), AlignOf<T>());
2641 return reinterpret_cast<T*
>(
buf_.
make_space(vector_size *
sizeof(T)));
2646 template <
typename T>
2656 template <
typename T>
2657 T* GetMutableRoot(
void* buf)
2660 return reinterpret_cast<T*
>(
reinterpret_cast<uint8_t*
>(buf) +
2661 EndianScalar(*
reinterpret_cast<uoffset_t*
>(buf)));
2664 template <
typename T>
2665 const T* GetRoot(
const void* buf)
2667 return GetMutableRoot<T>(
const_cast<void*
>(buf));
2670 template <
typename T>
2671 const T* GetSizePrefixedRoot(
const void* buf)
2673 return GetRoot<T>(
reinterpret_cast<const uint8_t*
>(buf) +
sizeof(uoffset_t));
2679 template <
typename T>
2680 T* GetMutableTemporaryPointer(FlatBufferBuilder& fbb, Offset<T> offset)
2682 return reinterpret_cast<T*
>(fbb.GetCurrentBufferPointer() + fbb.GetSize() - offset.o);
2685 template <
typename T>
2686 const T* GetTemporaryPointer(FlatBufferBuilder& fbb, Offset<T> offset)
2688 return GetMutableTemporaryPointer<T>(fbb, offset);
2698 inline const char* GetBufferIdentifier(
const void* buf,
bool size_prefixed =
false)
2700 return reinterpret_cast<const char*
>(buf) +
2701 ((size_prefixed) ? 2 *
sizeof(uoffset_t) :
sizeof(uoffset_t));
2705 inline bool BufferHasIdentifier(
const void* buf,
const char* identifier,
2706 bool size_prefixed =
false)
2708 return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
2713 class Verifier FLATBUFFERS_FINAL_CLASS
2716 Verifier(
const uint8_t* buf,
size_t buf_len, uoffset_t _max_depth = 64,
2717 uoffset_t _max_tables = 1000000,
bool _check_alignment =
true) :
2721 max_depth_(_max_depth),
2723 max_tables_(_max_tables),
2725 check_alignment_(_check_alignment)
2731 bool Check(
bool ok)
const
2734 #ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE
2737 #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
2746 bool Verify(
size_t elem,
size_t elem_len)
const
2749 #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
2750 auto upper_bound = elem + elem_len;
2751 if (upper_bound_ < upper_bound)
2752 upper_bound_ = upper_bound;
2755 return Check(elem_len < size_ && elem <= size_ - elem_len);
2758 template <
typename T>
2759 bool VerifyAlignment(
size_t elem)
const
2761 return Check((elem & (
sizeof(T) - 1)) == 0 || !check_alignment_);
2765 template <
typename T>
2766 bool Verify(
size_t elem)
const
2768 return VerifyAlignment<T>(elem) && Verify(elem,
sizeof(T));
2771 bool VerifyFromPointer(
const uint8_t* p,
size_t len)
2773 auto o =
static_cast<size_t>(p - buf_);
2774 return Verify(o, len);
2778 bool Verify(
const uint8_t* base, voffset_t elem_off,
size_t elem_len)
const
2780 return Verify(
static_cast<size_t>(base - buf_) + elem_off, elem_len);
2783 template <
typename T>
2784 bool Verify(
const uint8_t* base, voffset_t elem_off)
const
2786 return Verify(
static_cast<size_t>(base - buf_) + elem_off,
sizeof(T));
2790 template <
typename T>
2791 bool VerifyTable(
const T* table)
2793 return !table || table->Verify(*
this);
2797 template <
typename T>
2798 bool VerifyVector(
const Vector<T>* vec)
const
2800 return !vec || VerifyVectorOrString(
reinterpret_cast<const uint8_t*
>(vec),
sizeof(T));
2804 template <
typename T>
2805 bool VerifyVector(
const Vector<const T*>* vec)
const
2807 return VerifyVector(
reinterpret_cast<const Vector<T>*
>(vec));
2811 bool VerifyString(
const String* str)
const
2815 (VerifyVectorOrString(
reinterpret_cast<const uint8_t*
>(str), 1, &end) &&
2817 Check(buf_[end] ==
'\0'));
2821 bool VerifyVectorOrString(
const uint8_t* vec,
size_t elem_size,
2822 size_t* end =
nullptr)
const
2824 auto veco =
static_cast<size_t>(vec - buf_);
2826 if (!Verify<uoffset_t>(veco))
2830 auto size = ReadScalar<uoffset_t>(vec);
2831 auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size;
2832 if (!Check(size < max_elems))
2834 auto byte_size =
sizeof(size) + elem_size * size;
2836 *end = veco + byte_size;
2837 return Verify(veco, byte_size);
2841 bool VerifyVectorOfStrings(
const Vector<Offset<String>>* vec)
const
2845 for (uoffset_t i = 0; i < vec->size(); i++)
2847 if (!VerifyString(vec->Get(i)))
2855 template <
typename T>
2856 bool VerifyVectorOfTables(
const Vector<Offset<T>>* vec)
2860 for (uoffset_t i = 0; i < vec->size(); i++)
2862 if (!vec->Get(i)->Verify(*
this))
2869 __supress_ubsan__(
"unsigned-integer-overflow") bool VerifyTableStart(
2870 const uint8_t* table)
2873 auto tableo =
static_cast<size_t>(table - buf_);
2874 if (!Verify<soffset_t>(tableo))
2878 auto vtableo = tableo -
static_cast<size_t>(ReadScalar<soffset_t>(table));
2880 return VerifyComplexity() && Verify<voffset_t>(vtableo) &&
2881 VerifyAlignment<voffset_t>(ReadScalar<voffset_t>(buf_ + vtableo)) &&
2882 Verify(vtableo, ReadScalar<voffset_t>(buf_ + vtableo));
2885 template <
typename T>
2886 bool VerifyBufferFromStart(
const char* identifier,
size_t start)
2888 if (identifier && !Check((size_ >= 2 *
sizeof(flatbuffers::uoffset_t) &&
2889 BufferHasIdentifier(buf_ + start, identifier))))
2895 auto o = VerifyOffset(start);
2896 return o &&
reinterpret_cast<const T*
>(buf_ + start + o)->Verify(*
this)
2898 #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
2899 && GetComputedSize()
2906 template <
typename T>
2909 return VerifyBuffer<T>(
nullptr);
2912 template <
typename T>
2913 bool VerifyBuffer(
const char* identifier)
2915 return VerifyBufferFromStart<T>(identifier, 0);
2918 template <
typename T>
2919 bool VerifySizePrefixedBuffer(
const char* identifier)
2921 return Verify<uoffset_t>(0U) &&
2922 ReadScalar<uoffset_t>(buf_) == size_ -
sizeof(uoffset_t) &&
2923 VerifyBufferFromStart<T>(identifier,
sizeof(uoffset_t));
2926 uoffset_t VerifyOffset(
size_t start)
const
2928 if (!Verify<uoffset_t>(start))
2930 auto o = ReadScalar<uoffset_t>(buf_ + start);
2935 if (!Check(
static_cast<soffset_t
>(o) >= 0))
2939 if (!Verify(start + o, 1))
2944 uoffset_t VerifyOffset(
const uint8_t* base, voffset_t start)
const
2946 return VerifyOffset(
static_cast<size_t>(base - buf_) + start);
2953 bool VerifyComplexity()
2957 return Check(depth_ <= max_depth_ && num_tables_ <= max_tables_);
2968 size_t GetComputedSize()
const
2971 #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
2972 uintptr_t size = upper_bound_;
2974 size = (size - 1 +
sizeof(uoffset_t)) & ~(
sizeof(uoffset_t) - 1);
2975 return (size > size_) ? 0 : size;
2986 const uint8_t* buf_;
2989 uoffset_t max_depth_;
2990 uoffset_t num_tables_;
2991 uoffset_t max_tables_;
2992 mutable size_t upper_bound_;
2993 bool check_alignment_;
2999 struct BufferRefBase
3002 template <
typename T>
3003 struct BufferRef : BufferRefBase
3005 BufferRef() : buf(nullptr), len(0), must_free(false)
3007 BufferRef(uint8_t* _buf, uoffset_t _len) : buf(_buf), len(_len), must_free(false)
3016 const T* GetRoot()
const
3018 return flatbuffers::GetRoot<T>(buf);
3023 Verifier verifier(buf, len);
3024 return verifier.VerifyBuffer<T>(
nullptr);
3036 class Struct FLATBUFFERS_FINAL_CLASS
3039 template <
typename T>
3040 T GetField(uoffset_t o)
const
3042 return ReadScalar<T>(&data_[o]);
3045 template <
typename T>
3046 T GetStruct(uoffset_t o)
const
3048 return reinterpret_cast<T
>(&data_[o]);
3051 const uint8_t* GetAddressOf(uoffset_t o)
const
3055 uint8_t* GetAddressOf(uoffset_t o)
3064 Struct(
const Struct&);
3065 Struct& operator=(
const Struct&);
3075 const uint8_t* GetVTable()
const
3077 return data_ - ReadScalar<soffset_t>(data_);
3082 voffset_t GetOptionalFieldOffset(voffset_t field)
const
3085 auto vtable = GetVTable();
3087 auto vtsize = ReadScalar<voffset_t>(vtable);
3090 return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0;
3093 template <
typename T>
3094 T GetField(voffset_t field, T defaultval)
const
3096 auto field_offset = GetOptionalFieldOffset(field);
3097 return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval;
3100 template <
typename P>
3101 P GetPointer(voffset_t field)
3103 auto field_offset = GetOptionalFieldOffset(field);
3104 auto p = data_ + field_offset;
3105 return field_offset ?
reinterpret_cast<P
>(p + ReadScalar<uoffset_t>(p)) :
nullptr;
3107 template <
typename P>
3108 P GetPointer(voffset_t field)
const
3110 return const_cast<Table*
>(
this)->GetPointer<P>(field);
3113 template <
typename P>
3114 P GetStruct(voffset_t field)
const
3116 auto field_offset = GetOptionalFieldOffset(field);
3117 auto p =
const_cast<uint8_t*
>(data_ + field_offset);
3118 return field_offset ?
reinterpret_cast<P
>(p) :
nullptr;
3121 template <
typename Raw,
typename Face>
3122 flatbuffers::Optional<Face> GetOptional(voffset_t field)
const
3124 auto field_offset = GetOptionalFieldOffset(field);
3125 auto p = data_ + field_offset;
3126 return field_offset ? Optional<Face>(
static_cast<Face
>(ReadScalar<Raw>(p))) :
3130 template <
typename T>
3131 bool SetField(voffset_t field, T val, T def)
3133 auto field_offset = GetOptionalFieldOffset(field);
3136 WriteScalar(data_ + field_offset, val);
3139 template <
typename T>
3140 bool SetField(voffset_t field, T val)
3142 auto field_offset = GetOptionalFieldOffset(field);
3145 WriteScalar(data_ + field_offset, val);
3149 bool SetPointer(voffset_t field,
const uint8_t* val)
3151 auto field_offset = GetOptionalFieldOffset(field);
3154 WriteScalar(data_ + field_offset,
3155 static_cast<uoffset_t
>(val - (data_ + field_offset)));
3159 uint8_t* GetAddressOf(voffset_t field)
3161 auto field_offset = GetOptionalFieldOffset(field);
3162 return field_offset ? data_ + field_offset :
nullptr;
3164 const uint8_t* GetAddressOf(voffset_t field)
const
3166 return const_cast<Table*
>(
this)->GetAddressOf(field);
3169 bool CheckField(voffset_t field)
const
3171 return GetOptionalFieldOffset(field) != 0;
3176 bool VerifyTableStart(Verifier& verifier)
const
3178 return verifier.VerifyTableStart(data_);
3182 template <
typename T>
3183 bool VerifyField(
const Verifier& verifier, voffset_t field)
const
3187 auto field_offset = GetOptionalFieldOffset(field);
3189 return !field_offset || verifier.Verify<T>(data_, field_offset);
3193 template <
typename T>
3194 bool VerifyFieldRequired(
const Verifier& verifier, voffset_t field)
const
3196 auto field_offset = GetOptionalFieldOffset(field);
3197 return verifier.Check(field_offset != 0) && verifier.Verify<T>(data_, field_offset);
3201 bool VerifyOffset(
const Verifier& verifier, voffset_t field)
const
3203 auto field_offset = GetOptionalFieldOffset(field);
3204 return !field_offset || verifier.VerifyOffset(data_, field_offset);
3207 bool VerifyOffsetRequired(
const Verifier& verifier, voffset_t field)
const
3209 auto field_offset = GetOptionalFieldOffset(field);
3210 return verifier.Check(field_offset != 0) &&
3211 verifier.VerifyOffset(data_, field_offset);
3218 Table(
const Table& other);
3219 Table& operator=(
const Table&);
3227 inline flatbuffers::Optional<bool>
3228 Table::GetOptional<uint8_t, bool>(voffset_t field)
const
3230 auto field_offset = GetOptionalFieldOffset(field);
3231 auto p = data_ + field_offset;
3232 return field_offset ? Optional<bool>(ReadScalar<uint8_t>(p) != 0) :
Optional<bool>();
3235 template <
typename T>
3236 void FlatBufferBuilder::Required(Offset<T> table, voffset_t field)
3238 auto table_ptr =
reinterpret_cast<const Table*
>(
buf_.
data_at(table.o));
3239 bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
3249 inline const uint8_t* GetBufferStartFromRootPointer(
const void* root)
3251 auto table =
reinterpret_cast<const Table*
>(root);
3252 auto vtable = table->GetVTable();
3254 auto start = (std::min)(vtable,
reinterpret_cast<const uint8_t*
>(root));
3256 start =
reinterpret_cast<const uint8_t*
>(
reinterpret_cast<uintptr_t
>(start) &
3257 ~(
sizeof(uoffset_t) - 1));
3277 for (
auto possible_roots = FLATBUFFERS_MAX_ALIGNMENT /
sizeof(uoffset_t) + 1;
3278 possible_roots; possible_roots--)
3280 start -=
sizeof(uoffset_t);
3281 if (ReadScalar<uoffset_t>(start) + start ==
reinterpret_cast<const uint8_t*
>(root))
3293 inline uoffset_t GetPrefixedSize(
const uint8_t* buf)
3295 return ReadScalar<uoffset_t>(buf);
3313 typedef uint64_t hash_value_t;
3315 #ifdef FLATBUFFERS_CPP98_STL
3316 typedef void (*resolver_function_t)(
void **pointer_adr, hash_value_t hash);
3317 typedef hash_value_t (*rehasher_function_t)(
void *pointer);
3319 typedef std::function<void (
void **pointer_adr, hash_value_t hash)>
3320 resolver_function_t;
3321 typedef std::function<hash_value_t (
void *pointer)> rehasher_function_t;
3332 template <
typename T>
3333 bool IsFieldPresent(
const T* table,
typename T::FlatBuffersVTableOffset field)
3336 return reinterpret_cast<const Table*
>(table)->CheckField(
static_cast<voffset_t
>(field));
3342 inline int LookupEnum(
const char** names,
const char* name)
3344 for (
const char** p = names; *p; p++)
3345 if (!strcmp(*p, name))
3346 return static_cast<int>(p - names);
3361 #if defined(_MSC_VER)
3362 #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
3364 struct __declspec(align(alignment))
3365 #define FLATBUFFERS_STRUCT_END(name, size) \
3367 static_assert(sizeof(name) == size, "compiler breaks packing rules")
3368 #elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
3369 #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
3370 _Pragma("pack(1)") \
3371 struct __attribute__((aligned(alignment)))
3372 #define FLATBUFFERS_STRUCT_END(name, size) \
3374 static_assert(sizeof(name) == size, "compiler breaks packing rules")
3376 #error Unknown compiler, please define structure alignment macros
3400 #define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \
3414 ET(ET_SEQUENCE) // See SequenceType.
3416 enum ElementaryType {
3417 #define FLATBUFFERS_ET(E) E,
3418 FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
3419 #undef FLATBUFFERS_ET
3422 inline const char *
const *ElementaryTypeNames() {
3423 static const char *
const names[] = {
3424 #define FLATBUFFERS_ET(E) #E,
3425 FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
3426 #undef FLATBUFFERS_ET
3439 unsigned short base_type : 4;
3441 unsigned short is_repeating : 1;
3443 signed short sequence_ref : 11;
3446 static_assert(
sizeof(TypeCode) == 2,
"TypeCode");
3451 typedef const TypeTable* (*TypeFunction)();
3457 const TypeCode* type_codes;
3458 const TypeFunction* type_refs;
3459 const int16_t* array_sizes;
3460 const int64_t* values;
3461 const char*
const* names;
3475 #if !defined(_WIN32) && !defined(__CYGWIN__)
3477 extern volatile __attribute__((weak))
const char *flatbuffer_version_string;
3478 volatile __attribute__((weak))
const char *flatbuffer_version_string =
3480 FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR)
"."
3481 FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR)
"."
3482 FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
3484 #endif // !defined(_WIN32) && !defined(__CYGWIN__)
3486 #define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\
3487 inline E operator | (E lhs, E rhs){\
3488 return E(T(lhs) | T(rhs));\
3490 inline E operator & (E lhs, E rhs){\
3491 return E(T(lhs) & T(rhs));\
3493 inline E operator ^ (E lhs, E rhs){\
3494 return E(T(lhs) ^ T(rhs));\
3496 inline E operator ~ (E lhs){\
3499 inline E operator |= (E &lhs, E rhs){\
3503 inline E operator &= (E &lhs, E rhs){\
3507 inline E operator ^= (E &lhs, E rhs){\
3511 inline bool operator !(E rhs) \
3513 return !bool(T(rhs)); \
3520 #endif // FLATBUFFERS_H_