17 #ifndef FLATBUFFERS_H_ 18 #define FLATBUFFERS_H_ 20 #include "flatbuffers/base.h" 28 Offset(uoffset_t _o) : o(_o) {}
30 bool IsNull()
const {
return !o; }
33 inline void EndianCheck() {
36 assert(*reinterpret_cast<char *>(&endiantest) == FLATBUFFERS_LITTLEENDIAN);
40 template<
typename T> FLATBUFFERS_CONSTEXPR
size_t AlignOf() {
46 return __alignof__(T);
63 typedef T return_type;
64 typedef T mutable_return_type;
65 static const size_t element_stride =
sizeof(T);
66 static return_type Read(
const uint8_t *p, uoffset_t i) {
67 return EndianScalar((reinterpret_cast<const T *>(p))[i]);
71 typedef const T *return_type;
72 typedef T *mutable_return_type;
73 static const size_t element_stride =
sizeof(uoffset_t);
74 static return_type Read(
const uint8_t *p, uoffset_t i) {
75 p += i *
sizeof(uoffset_t);
76 return reinterpret_cast<return_type
>(p + ReadScalar<uoffset_t>(p));
80 typedef const T *return_type;
81 typedef T *mutable_return_type;
82 static const size_t element_stride =
sizeof(T);
83 static return_type Read(
const uint8_t *p, uoffset_t i) {
84 return reinterpret_cast<const T *
>(p + i *
sizeof(T));
91 typedef std::random_access_iterator_tag iterator_category;
92 typedef IT value_type;
93 typedef uoffset_t difference_type;
95 typedef IT &reference;
112 return data_ == other.data_;
116 return data_ < other.data_;
120 return data_ != other.data_;
174 const uint8_t *data_;
188 uoffset_t size()
const {
return EndianScalar(length_); }
191 uoffset_t Length()
const {
return size(); }
193 typedef typename IndirectHelper<T>::return_type return_type;
194 typedef typename IndirectHelper<T>::mutable_return_type mutable_return_type;
196 return_type Get(uoffset_t i)
const {
201 return_type operator[](uoffset_t i)
const {
return Get(i); }
206 template<
typename E> E GetEnum(uoffset_t i)
const {
207 return static_cast<E
>(Get(i));
212 template<
typename U>
const U *GetAs(uoffset_t i)
const {
213 return reinterpret_cast<const U *
>(Get(i));
218 const String *GetAsString(uoffset_t i)
const {
219 return reinterpret_cast<const String *
>(Get(i));
222 const void *GetStructFromOffset(
size_t o)
const {
223 return reinterpret_cast<const void *
>(Data() + o);
226 iterator begin() {
return iterator(Data(), 0); }
227 const_iterator begin()
const {
return const_iterator(Data(), 0); }
229 iterator end() {
return iterator(Data(), size()); }
230 const_iterator end()
const {
return const_iterator(Data(), size()); }
234 void Mutate(uoffset_t i,
const T &val) {
236 WriteScalar(data() + i, val);
242 void MutateOffset(uoffset_t i,
const uint8_t *val) {
244 assert(
sizeof(T) ==
sizeof(uoffset_t));
245 WriteScalar(data() + i,
246 static_cast<uoffset_t>(val - (Data() + i *
sizeof(uoffset_t))));
250 mutable_return_type GetMutableObject(uoffset_t i)
const {
256 const uint8_t *Data()
const {
257 return reinterpret_cast<const uint8_t *
>(&length_ + 1);
260 uint8_t *Data() {
return reinterpret_cast<uint8_t *
>(&length_ + 1); }
263 const T *data()
const {
return reinterpret_cast<const T *
>(Data()); }
264 T *data() {
return reinterpret_cast<T *
>(Data()); }
266 template<
typename K> return_type LookupByKey(K key)
const {
267 void *search_result = std::bsearch(
270 if (!search_result) {
274 const uint8_t *element =
reinterpret_cast<const uint8_t *
>(search_result);
291 template<
typename K>
static int KeyCompare(
const void *ap,
const void *bp) {
292 const K *key =
reinterpret_cast<const K *
>(ap);
293 const uint8_t *data =
reinterpret_cast<const uint8_t *
>(bp);
298 return -table->KeyCompareWithValue(*key);
306 uoffset_t size()
const {
return EndianScalar(length_); }
308 const uint8_t *Data()
const {
309 return reinterpret_cast<const uint8_t *
>(&length_ + 1);
311 uint8_t *Data() {
return reinterpret_cast<uint8_t *
>(&length_ + 1); }
322 #ifndef FLATBUFFERS_CPP98_STL 323 template<
typename T,
typename U>
325 static_assert(std::is_base_of<T, U>::value,
"Unrelated types");
329 template<
typename T,
typename U>
331 static_assert(std::is_base_of<T, U>::value,
"Unrelated types");
338 template<
typename T>
static inline size_t VectorLength(
const Vector<T> *v) {
339 return v ? v->Length() : 0;
343 const char *c_str()
const {
return reinterpret_cast<const char *
>(Data()); }
344 std::string str()
const {
return std::string(c_str(), Length()); }
346 bool operator<(
const String &o)
const {
347 return strcmp(c_str(), o.c_str()) < 0;
358 virtual uint8_t *allocate(
size_t size) = 0;
361 virtual void deallocate(uint8_t *p,
size_t size) = 0;
368 virtual uint8_t *reallocate_downward(uint8_t *old_p,
size_t old_size,
369 size_t new_size,
size_t in_use_back,
370 size_t in_use_front) {
371 assert(new_size > old_size);
372 uint8_t *new_p = allocate(new_size);
373 memcpy_downward(old_p, old_size, new_p, new_size, in_use_back,
375 deallocate(old_p, old_size);
384 void memcpy_downward(uint8_t *old_p,
size_t old_size,
385 uint8_t *new_p,
size_t new_size,
386 size_t in_use_back,
size_t in_use_front) {
387 memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back,
389 memcpy(new_p, old_p, in_use_front);
396 virtual uint8_t *allocate(
size_t size) FLATBUFFERS_OVERRIDE {
397 return new uint8_t[size];
400 virtual void deallocate(uint8_t *p,
size_t) FLATBUFFERS_OVERRIDE {
416 : allocator_(
nullptr),
417 own_allocator_(
false),
424 size_t reserved, uint8_t *cur,
size_t sz)
425 : allocator_(allocator),
426 own_allocator_(own_allocator),
435 : allocator_(other.allocator_),
436 own_allocator_(other.own_allocator_),
438 reserved_(other.reserved_),
447 allocator_ = other.allocator_;
448 own_allocator_ = other.own_allocator_;
450 reserved_ = other.reserved_;
461 const uint8_t *data()
const {
return cur_; }
463 uint8_t *data() {
return cur_; }
465 size_t size()
const {
return size_; }
468 #if 0 // disabled for now due to the ordering of classes in this header 470 bool Verify()
const {
471 Verifier verifier(data(), size());
472 return verifier.Verify<T>(
nullptr);
476 const T* GetRoot()
const {
477 return flatbuffers::GetRoot<T>(data());
482 return flatbuffers::GetRoot<T>(data());
489 FLATBUFFERS_DELETE_FUNC(
500 inline void destroy() {
503 allocator_->deallocate(buf_, reserved_);
505 if (own_allocator_ && allocator_) {
delete allocator_; }
510 inline void reset() {
511 allocator_ =
nullptr;
512 own_allocator_ =
false;
531 size_t buffer_minalign)
532 : allocator_(allocator ? allocator : &DefaultAllocator::instance()),
533 own_allocator_(own_allocator),
534 initial_size_(initial_size),
535 buffer_minalign_(buffer_minalign),
546 allocator_->deallocate(buf_, reserved_);
548 if (own_allocator_ && allocator_) {
delete allocator_; }
554 allocator_->deallocate(buf_, reserved_);
562 cur_ = buf_ + reserved_;
570 void clear_scratch() {
576 DetachedBuffer fb(allocator_, own_allocator_, buf_, reserved_, cur_,
578 allocator_ =
nullptr;
579 own_allocator_ =
false;
585 size_t ensure_space(
size_t len) {
586 assert(cur_ >= scratch_ && scratch_ >= buf_);
587 if (len > static_cast<size_t>(cur_ - scratch_)) { reallocate(len); }
590 assert(size() < FLATBUFFERS_MAX_BUFFER_SIZE);
594 inline uint8_t *make_space(
size_t len) {
595 cur_ -= ensure_space(len);
599 Allocator &get_allocator() {
return *allocator_; }
601 uoffset_t size()
const {
602 return static_cast<uoffset_t
>(reserved_ - (cur_ - buf_));
605 uoffset_t scratch_size()
const {
606 return static_cast<uoffset_t
>(scratch_ - buf_);
609 size_t capacity()
const {
return reserved_; }
611 uint8_t *data()
const {
616 uint8_t *scratch_data()
const {
621 uint8_t *scratch_end()
const {
626 uint8_t *data_at(
size_t offset)
const {
return buf_ + reserved_ - offset; }
628 void push(
const uint8_t *bytes,
size_t num) {
629 memcpy(make_space(num), bytes, num);
633 template<
typename T>
void push_small(
const T &little_endian_t) {
634 make_space(
sizeof(T));
635 *
reinterpret_cast<T *
>(cur_) = little_endian_t;
638 template<
typename T>
void scratch_push_small(
const T &t) {
639 ensure_space(
sizeof(T));
640 *
reinterpret_cast<T *
>(scratch_) = t;
641 scratch_ +=
sizeof(T);
646 void fill(
size_t zero_pad_bytes) {
647 make_space(zero_pad_bytes);
648 for (
size_t i = 0; i < zero_pad_bytes; i++) cur_[i] = 0;
652 void fill_big(
size_t zero_pad_bytes) {
653 memset(make_space(zero_pad_bytes), 0, zero_pad_bytes);
656 void pop(
size_t bytes_to_remove) { cur_ += bytes_to_remove; }
657 void scratch_pop(
size_t bytes_to_remove) { scratch_ -= bytes_to_remove; }
666 size_t initial_size_;
667 size_t buffer_minalign_;
673 void reallocate(
size_t len) {
675 auto old_reserved = reserved_;
676 auto old_size = size();
677 auto old_scratch_size = scratch_size();
678 reserved_ += (std::max)(len,
679 old_reserved ? old_reserved / 2 : initial_size_);
680 reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1);
682 buf_ = allocator_->reallocate_downward(buf_, old_reserved, reserved_,
683 old_size, old_scratch_size);
685 buf_ = allocator_->allocate(reserved_);
687 cur_ = buf_ + reserved_ - old_size;
688 scratch_ = buf_ + old_scratch_size;
693 inline voffset_t FieldIndexToOffset(voffset_t field_id) {
695 const int fixed_fields = 2;
696 return static_cast<voffset_t
>((field_id + fixed_fields) *
sizeof(voffset_t));
699 template<
typename T,
typename Alloc>
700 const T *data(
const std::vector<T, Alloc> &v) {
701 return v.empty() ? nullptr : &v.front();
703 template<
typename T,
typename Alloc> T *data(std::vector<T, Alloc> &v) {
704 return v.empty() ? nullptr : &v.front();
733 bool own_allocator =
false,
734 size_t buffer_minalign =
735 AlignOf<largest_scalar_t>())
736 : buf_(initial_size, allocator, own_allocator, buffer_minalign),
742 force_defaults_(false),
743 dedup_vtables_(true),
744 string_pool(nullptr) {
749 if (string_pool)
delete string_pool;
765 if (string_pool) string_pool->clear();
770 uoffset_t
GetSize()
const {
return buf_.size(); }
791 return buf_.release();
798 return buf_.release();
812 void Finished()
const {
832 void Pad(
size_t num_bytes) { buf_.fill(num_bytes); }
834 void TrackMinAlign(
size_t elem_size) {
835 if (elem_size > minalign_) minalign_ = elem_size;
838 void Align(
size_t elem_size) {
839 TrackMinAlign(elem_size);
840 buf_.fill(PaddingBytes(buf_.size(), elem_size));
843 void PushFlatBuffer(
const uint8_t *bytes,
size_t size) {
844 PushBytes(bytes, size);
848 void PushBytes(
const uint8_t *bytes,
size_t size) { buf_.push(bytes, size); }
850 void PopBytes(
size_t amount) { buf_.pop(amount); }
852 template<
typename T>
void AssertScalarT() {
854 static_assert(flatbuffers::is_scalar<T>::value,
"T must be a scalar type");
858 template<
typename T> uoffset_t PushElement(T element) {
860 T litle_endian_element = EndianScalar(element);
862 buf_.push_small(litle_endian_element);
866 template<
typename T> uoffset_t PushElement(
Offset<T> off) {
868 return PushElement(ReferTo(off.o));
873 void TrackField(voffset_t field, uoffset_t off) {
875 buf_.scratch_push_small(fl);
877 max_voffset_ = (std::max)(max_voffset_, field);
881 template<
typename T>
void AddElement(voffset_t field, T e, T def) {
883 if (e == def && !force_defaults_)
return;
884 auto off = PushElement(e);
885 TrackField(field, off);
888 template<
typename T>
void AddOffset(voffset_t field,
Offset<T> off) {
889 if (off.IsNull())
return;
890 AddElement(field, ReferTo(off.o), static_cast<uoffset_t>(0));
893 template<
typename T>
void AddStruct(voffset_t field,
const T *structptr) {
894 if (!structptr)
return;
896 buf_.push_small(*structptr);
897 TrackField(field, GetSize());
900 void AddStructOffset(voffset_t field, uoffset_t off) {
901 TrackField(field, off);
907 uoffset_t ReferTo(uoffset_t off) {
909 Align(
sizeof(uoffset_t));
911 assert(off && off <= GetSize());
912 return GetSize() - off +
static_cast<uoffset_t
>(
sizeof(uoffset_t));
926 assert(!num_field_loc);
931 uoffset_t StartTable() {
940 uoffset_t EndTable(uoffset_t start) {
945 auto vtableoffsetloc = PushElement<soffset_t>(0);
952 (std::max)(static_cast<voffset_t>(max_voffset_ +
sizeof(voffset_t)),
953 FieldIndexToOffset(0));
954 buf_.fill_big(max_voffset_);
955 auto table_object_size = vtableoffsetloc - start;
956 assert(table_object_size < 0x10000);
957 WriteScalar<voffset_t>(buf_.data() +
sizeof(voffset_t),
958 static_cast<voffset_t>(table_object_size));
959 WriteScalar<voffset_t>(buf_.data(), max_voffset_);
961 for (
auto it = buf_.scratch_end() - num_field_loc *
sizeof(
FieldLoc);
962 it < buf_.scratch_end(); it +=
sizeof(
FieldLoc)) {
963 auto field_location =
reinterpret_cast<FieldLoc *
>(it);
964 auto pos =
static_cast<voffset_t
>(vtableoffsetloc - field_location->off);
966 assert(!ReadScalar<voffset_t>(buf_.data() + field_location->id));
967 WriteScalar<voffset_t>(buf_.data() + field_location->id, pos);
970 auto vt1 =
reinterpret_cast<voffset_t *
>(buf_.data());
971 auto vt1_size = ReadScalar<voffset_t>(vt1);
972 auto vt_use = GetSize();
975 if (dedup_vtables_) {
976 for (
auto it = buf_.scratch_data(); it < buf_.scratch_end();
977 it +=
sizeof(uoffset_t)) {
978 auto vt_offset_ptr =
reinterpret_cast<uoffset_t *
>(it);
979 auto vt2 =
reinterpret_cast<voffset_t *
>(buf_.data_at(*vt_offset_ptr));
980 auto vt2_size = *vt2;
981 if (vt1_size != vt2_size || memcmp(vt2, vt1, vt1_size))
continue;
982 vt_use = *vt_offset_ptr;
983 buf_.pop(GetSize() - vtableoffsetloc);
988 if (vt_use == GetSize()) { buf_.scratch_push_small(vt_use); }
994 WriteScalar(buf_.data_at(vtableoffsetloc),
995 static_cast<soffset_t
>(vt_use) -
996 static_cast<soffset_t>(vtableoffsetloc));
999 return vtableoffsetloc;
1003 uoffset_t EndTable(uoffset_t start, voffset_t ) {
1004 return EndTable(start);
1009 template<
typename T>
void Required(
Offset<T> table, voffset_t field) {
1010 auto table_ptr = buf_.data_at(table.o);
1011 auto vtable_ptr = table_ptr - ReadScalar<soffset_t>(table_ptr);
1012 bool ok = ReadScalar<voffset_t>(vtable_ptr + field) != 0;
1018 uoffset_t StartStruct(
size_t alignment) {
1023 uoffset_t EndStruct() {
return GetSize(); }
1025 void ClearOffsets() {
1026 buf_.scratch_pop(num_field_loc *
sizeof(
FieldLoc));
1033 void PreAlign(
size_t len,
size_t alignment) {
1034 TrackMinAlign(alignment);
1035 buf_.fill(PaddingBytes(GetSize() + len, alignment));
1037 template<
typename T>
void PreAlign(
size_t len) {
1039 PreAlign(len,
sizeof(T));
1049 PreAlign<uoffset_t>(len + 1);
1051 PushBytes(reinterpret_cast<const uint8_t *>(str), len);
1052 PushElement(static_cast<uoffset_t>(len));
1060 return CreateString(str, strlen(str));
1067 return CreateString(str, strlen(str));
1074 return CreateString(str.c_str(), str.length());
1081 return str ? CreateString(str->c_str(), str->Length()) : 0;
1089 return CreateString(str.c_str(), str.length());
1101 auto size_before_string = buf_.size();
1104 auto off = CreateString(str, len);
1105 auto it = string_pool->find(off);
1107 if (it != string_pool->end()) {
1109 buf_.pop(buf_.size() - size_before_string);
1113 string_pool->insert(off);
1123 return CreateSharedString(str, strlen(str));
1132 return CreateSharedString(str.c_str(), str.length());
1141 return CreateSharedString(str->c_str(), str->Length());
1145 uoffset_t EndVector(
size_t len) {
1148 return PushElement(static_cast<uoffset_t>(len));
1151 void StartVector(
size_t len,
size_t elemsize) {
1154 PreAlign<uoffset_t>(len * elemsize);
1155 PreAlign(len * elemsize, elemsize);
1163 void ForceVectorAlignment(
size_t len,
size_t elemsize,
size_t alignment) {
1164 PreAlign(len * elemsize, alignment);
1180 StartVector(len,
sizeof(T));
1182 #if FLATBUFFERS_LITTLEENDIAN 1183 PushBytes(reinterpret_cast<const uint8_t *>(v), len *
sizeof(T));
1185 if (
sizeof(T) == 1) {
1186 PushBytes(reinterpret_cast<const uint8_t *>(v), len);
1188 for (
auto i = len; i > 0; ) {
1189 PushElement(v[--i]);
1197 template<
typename T>
1200 for (
auto i = len; i > 0;) { PushElement(v[--i]); }
1211 return CreateVector(data(v), v.size());
1218 StartVector(v.size(),
sizeof(uint8_t));
1219 for (
auto i = v.size(); i > 0;) {
1220 PushElement(static_cast<uint8_t>(v[--i]));
1226 #ifndef FLATBUFFERS_CPP98_STL 1235 const std::function<T (
size_t i)> &f) {
1236 std::vector<T> elems(vector_size);
1237 for (
size_t i = 0; i < vector_size; i++) elems[i] = f(i);
1238 return CreateVector(elems);
1252 template<
typename T,
typename F,
typename S>
1254 std::vector<T> elems(vector_size);
1255 for (
size_t i = 0; i < vector_size; i++) elems[i] = f(i, state);
1256 return CreateVector(elems);
1266 const std::vector<std::string> &v) {
1267 std::vector<Offset<String>> offsets(v.size());
1268 for (
size_t i = 0; i < v.size(); i++) offsets[i] = CreateString(v[i]);
1269 return CreateVector(offsets);
1279 template<
typename T>
1281 StartVector(len *
sizeof(T) / AlignOf<T>(), AlignOf<T>());
1282 PushBytes(reinterpret_cast<const uint8_t *>(v),
sizeof(T) * len);
1294 template<
typename T,
typename S>
1297 extern T Pack(
const S &);
1298 typedef T (*Pack_t)(
const S &);
1299 std::vector<T> vv(len);
1300 std::transform(v, v + len, vv.begin(), *(Pack_t)&Pack);
1301 return CreateVectorOfStructs<T>(vv.data(), vv.size());
1305 #ifndef FLATBUFFERS_CPP98_STL 1315 size_t vector_size,
const std::function<
void(
size_t i, T *)> &filler) {
1316 T* structs = StartVectorOfStructs<T>(vector_size);
1317 for (
size_t i = 0; i < vector_size; i++) {
1321 return EndVectorOfStructs<T>(vector_size);
1335 template<
typename T,
typename F,
typename S>
1338 T *structs = StartVectorOfStructs<T>(vector_size);
1339 for (
size_t i = 0; i < vector_size; i++) {
1340 f(i, structs, state);
1343 return EndVectorOfStructs<T>(vector_size);
1352 template<
typename T,
typename Alloc>
1354 const std::vector<T, Alloc> &v) {
1355 return CreateVectorOfStructs(data(v), v.size());
1366 template<
typename T,
typename S>
1368 const std::vector<S> &v) {
1369 return CreateVectorOfNativeStructs<T, S>(data(v), v.size());
1373 template<
typename T>
struct StructKeyComparator {
1374 bool operator()(
const T &a,
const T &b)
const {
1375 return a.KeyCompareLessThan(&b);
1379 StructKeyComparator &operator=(
const StructKeyComparator &);
1390 template<
typename T>
1392 return CreateVectorOfSortedStructs(data(*v), v->size());
1403 template<
typename T,
typename S>
1405 std::vector<S> *v) {
1406 return CreateVectorOfSortedNativeStructs<T, S>(data(*v), v->size());
1417 template<
typename T>
1419 std::sort(v, v + len, StructKeyComparator<T>());
1420 return CreateVectorOfStructs(v, len);
1432 template<
typename T,
typename S>
1435 extern T Pack(
const S &);
1436 typedef T (*Pack_t)(
const S &);
1437 std::vector<T> vv(len);
1438 std::transform(v, v + len, vv.begin(), *(Pack_t)&Pack);
1439 return CreateVectorOfSortedStructs<T>(vv, len);
1443 template<
typename T>
struct TableKeyComparator {
1446 auto table_a =
reinterpret_cast<T *
>(buf_.data_at(a.o));
1447 auto table_b =
reinterpret_cast<T *
>(buf_.data_at(b.o));
1448 return table_a->KeyCompareLessThan(table_b);
1453 TableKeyComparator &operator=(
const TableKeyComparator &);
1465 template<
typename T>
1468 std::sort(v, v + len, TableKeyComparator<T>(buf_));
1469 return CreateVector(v, len);
1479 template<
typename T>
1482 return CreateVectorOfSortedTables(data(*v), v->size());
1495 StartVector(len, elemsize);
1496 buf_.make_space(len * elemsize);
1497 auto vec_start = GetSize();
1498 auto vec_end = EndVector(len);
1499 *buf = buf_.data_at(vec_start);
1511 template<
typename T>
1513 return CreateUninitializedVector(len,
sizeof(T),
1514 reinterpret_cast<uint8_t **>(buf));
1520 Align(AlignOf<T>());
1521 buf_.push_small(structobj);
1526 static const size_t kFileIdentifierLength = 4;
1531 template<
typename T>
1533 Finish(root.o, file_identifier,
false);
1543 template<
typename T>
1545 const char *file_identifier =
nullptr) {
1546 Finish(root.o, file_identifier,
true);
1554 void Finish(uoffset_t root,
const char *file_identifier,
bool size_prefix) {
1556 buf_.clear_scratch();
1558 PreAlign((size_prefix ?
sizeof(uoffset_t) : 0) +
sizeof(uoffset_t) +
1559 (file_identifier ? kFileIdentifierLength : 0),
1561 if (file_identifier) {
1562 assert(strlen(file_identifier) == kFileIdentifierLength);
1563 PushBytes(reinterpret_cast<const uint8_t *>(file_identifier),
1564 kFileIdentifierLength);
1566 PushElement(ReferTo(root));
1567 if (size_prefix) { PushElement(GetSize()); }
1580 uoffset_t num_field_loc;
1583 voffset_t max_voffset_;
1593 bool force_defaults_;
1595 bool dedup_vtables_;
1600 auto stra =
reinterpret_cast<const String *
>(buf_->data_at(a.o));
1601 auto strb =
reinterpret_cast<const String *
>(buf_->data_at(b.o));
1602 return strncmp(stra->c_str(), strb->c_str(),
1603 (std::min)(stra->size(), strb->size()) + 1) < 0;
1610 StringOffsetMap *string_pool;
1615 template<
typename T> T *StartVectorOfStructs(
size_t vector_size) {
1616 StartVector(vector_size *
sizeof(T) / AlignOf<T>(), AlignOf<T>());
1617 return reinterpret_cast<T *
>(buf_.make_space(vector_size *
sizeof(T)));
1622 template<
typename T>
1631 template<
typename T> T *GetMutableRoot(
void *buf) {
1633 return reinterpret_cast<T *
>(
1634 reinterpret_cast<uint8_t *
>(buf) +
1635 EndianScalar(*reinterpret_cast<uoffset_t *>(buf)));
1638 template<
typename T>
const T *GetRoot(
const void *buf) {
1639 return GetMutableRoot<T>(
const_cast<void *
>(buf));
1642 template<
typename T>
const T *GetSizePrefixedRoot(
const void *buf) {
1643 return GetRoot<T>(
reinterpret_cast<const uint8_t *
>(buf) +
sizeof(uoffset_t));
1649 template<
typename T>
1655 template<
typename T>
1657 return GetMutableTemporaryPointer<T>(fbb, offset);
1667 inline const char *GetBufferIdentifier(
const void *buf,
bool size_prefixed =
false) {
1668 return reinterpret_cast<const char *
>(buf) +
1669 ((size_prefixed) ? 2 *
sizeof(uoffset_t) :
sizeof(uoffset_t));
1673 inline bool BufferHasIdentifier(
const void *buf,
const char *identifier,
bool size_prefixed =
false) {
1674 return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
1679 class Verifier FLATBUFFERS_FINAL_CLASS {
1681 Verifier(
const uint8_t *buf,
size_t buf_len, uoffset_t _max_depth = 64,
1682 uoffset_t _max_tables = 1000000)
1684 end_(buf + buf_len),
1686 max_depth_(_max_depth),
1688 max_tables_(_max_tables)
1690 #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE 1698 bool Check(
bool ok)
const {
1700 #ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE 1703 #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE 1705 upper_bound_ = buf_;
1712 bool Verify(
const void *elem,
size_t elem_len)
const {
1714 #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE 1715 auto upper_bound =
reinterpret_cast<const uint8_t *
>(elem) + elem_len;
1716 if (upper_bound_ < upper_bound)
1717 upper_bound_ = upper_bound;
1720 return Check(elem_len <= (
size_t)(end_ - buf_) && elem >= buf_ &&
1721 elem <= end_ - elem_len);
1725 template<
typename T>
bool Verify(
const void *elem)
const {
1726 return Verify(elem,
sizeof(T));
1730 template<
typename T>
bool VerifyTable(
const T *table) {
1731 return !table || table->Verify(*
this);
1735 template<
typename T>
bool Verify(
const Vector<T> *vec)
const {
1737 return !vec || VerifyVector(reinterpret_cast<const uint8_t *>(vec),
1743 return Verify(
reinterpret_cast<const Vector<T> *
>(vec));
1747 bool Verify(
const String *str)
const {
1750 (VerifyVector(reinterpret_cast<const uint8_t *>(str), 1, &end) &&
1752 Check(*end ==
'\0'));
1756 bool VerifyVector(
const uint8_t *vec,
size_t elem_size,
1757 const uint8_t **end)
const {
1759 if (!Verify<uoffset_t>(vec))
return false;
1762 auto size = ReadScalar<uoffset_t>(vec);
1763 auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size;
1764 if (!Check(size < max_elems))
1766 auto byte_size =
sizeof(size) + elem_size * size;
1767 *end = vec + byte_size;
1768 return Verify(vec, byte_size);
1774 for (uoffset_t i = 0; i < vec->size(); i++) {
1775 if (!Verify(vec->Get(i)))
return false;
1782 template<
typename T>
bool VerifyVectorOfTables(
const Vector<
Offset<T>> *vec) {
1784 for (uoffset_t i = 0; i < vec->size(); i++) {
1785 if (!vec->Get(i)->Verify(*
this))
return false;
1791 template<
typename T>
1792 bool VerifyBufferFromStart(
const char *identifier,
const uint8_t *start) {
1794 (
size_t(end_ - start) < 2 *
sizeof(flatbuffers::uoffset_t) ||
1795 !BufferHasIdentifier(start, identifier))) {
1800 auto o = VerifyOffset(start);
1801 return o &&
reinterpret_cast<const T *
>(start + o)->Verify(*
this)
1802 #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE 1803 && GetComputedSize()
1809 template<
typename T>
bool VerifyBuffer() {
return VerifyBuffer<T>(
nullptr); }
1811 template<
typename T>
bool VerifyBuffer(
const char *identifier) {
1812 return VerifyBufferFromStart<T>(identifier, buf_);
1815 template<
typename T>
bool VerifySizePrefixedBuffer(
const char *identifier) {
1816 return Verify<uoffset_t>(buf_) &&
1817 ReadScalar<uoffset_t>(buf_) == end_ - buf_ -
sizeof(uoffset_t) &&
1818 VerifyBufferFromStart<T>(identifier, buf_ +
sizeof(uoffset_t));
1821 uoffset_t VerifyOffset(
const uint8_t *start)
const {
1822 if (!Verify<uoffset_t>(start))
return false;
1823 auto o = ReadScalar<uoffset_t>(start);
1832 bool VerifyComplexity() {
1835 return Check(depth_ <= max_depth_ && num_tables_ <= max_tables_);
1845 #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE 1847 size_t GetComputedSize()
const {
1848 uintptr_t size = upper_bound_ - buf_;
1850 size = (size - 1 +
sizeof(uoffset_t)) & ~(
sizeof(uoffset_t) - 1);
1851 return (buf_ + size > end_) ? 0 : size;
1857 const uint8_t *buf_;
1858 const uint8_t *end_;
1860 uoffset_t max_depth_;
1861 uoffset_t num_tables_;
1862 uoffset_t max_tables_;
1864 #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE 1865 mutable const uint8_t *upper_bound_;
1873 struct BufferRefBase {};
1874 template<
typename T>
struct BufferRef : BufferRefBase {
1875 BufferRef() : buf(
nullptr), len(0), must_free(
false) {}
1876 BufferRef(uint8_t *_buf, uoffset_t _len)
1877 : buf(_buf), len(_len), must_free(
false) {}
1880 if (must_free) free(buf);
1883 const T *GetRoot()
const {
return flatbuffers::GetRoot<T>(buf); }
1886 Verifier verifier(buf, len);
1887 return verifier.VerifyBuffer<T>(
nullptr);
1899 class Struct FLATBUFFERS_FINAL_CLASS {
1901 template<
typename T> T GetField(uoffset_t o)
const {
1902 return ReadScalar<T>(&data_[o]);
1905 template<
typename T> T GetStruct(uoffset_t o)
const {
1906 return reinterpret_cast<T
>(&data_[o]);
1909 const uint8_t *GetAddressOf(uoffset_t o)
const {
return &data_[o]; }
1910 uint8_t *GetAddressOf(uoffset_t o) {
return &data_[o]; }
1920 const uint8_t *GetVTable()
const {
1921 return data_ - ReadScalar<soffset_t>(data_);
1926 voffset_t GetOptionalFieldOffset(voffset_t field)
const {
1928 auto vtable = GetVTable();
1930 auto vtsize = ReadScalar<voffset_t>(vtable);
1933 return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0;
1936 template<
typename T> T GetField(voffset_t field, T defaultval)
const {
1937 auto field_offset = GetOptionalFieldOffset(field);
1938 return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval;
1941 template<
typename P> P GetPointer(voffset_t field) {
1942 auto field_offset = GetOptionalFieldOffset(field);
1943 auto p = data_ + field_offset;
1944 return field_offset ?
reinterpret_cast<P
>(p + ReadScalar<uoffset_t>(p))
1947 template<
typename P> P GetPointer(voffset_t field)
const {
1948 return const_cast<Table *
>(
this)->GetPointer<P>(field);
1951 template<
typename P> P GetStruct(voffset_t field)
const {
1952 auto field_offset = GetOptionalFieldOffset(field);
1953 auto p =
const_cast<uint8_t *
>(data_ + field_offset);
1954 return field_offset ?
reinterpret_cast<P
>(p) :
nullptr;
1957 template<
typename T>
bool SetField(voffset_t field, T val, T def) {
1958 auto field_offset = GetOptionalFieldOffset(field);
1959 if (!field_offset)
return val == def;
1960 WriteScalar(data_ + field_offset, val);
1964 bool SetPointer(voffset_t field,
const uint8_t *val) {
1965 auto field_offset = GetOptionalFieldOffset(field);
1966 if (!field_offset)
return false;
1967 WriteScalar(data_ + field_offset,
1968 static_cast<uoffset_t>(val - (data_ + field_offset)));
1972 uint8_t *GetAddressOf(voffset_t field) {
1973 auto field_offset = GetOptionalFieldOffset(field);
1974 return field_offset ? data_ + field_offset :
nullptr;
1976 const uint8_t *GetAddressOf(voffset_t field)
const {
1977 return const_cast<Table *
>(
this)->GetAddressOf(field);
1980 bool CheckField(voffset_t field)
const {
1981 return GetOptionalFieldOffset(field) != 0;
1986 bool VerifyTableStart(Verifier &verifier)
const {
1988 if (!verifier.Verify<soffset_t>(data_))
return false;
1989 auto vtable = GetVTable();
1991 return verifier.VerifyComplexity() && verifier.Verify<voffset_t>(vtable) &&
1992 (ReadScalar<voffset_t>(vtable) & (
sizeof(voffset_t) - 1)) == 0 &&
1993 verifier.Verify(vtable, ReadScalar<voffset_t>(vtable));
1997 template<
typename T>
1998 bool VerifyField(
const Verifier &verifier, voffset_t field)
const {
2001 auto field_offset = GetOptionalFieldOffset(field);
2003 return !field_offset || verifier.Verify<T>(data_ + field_offset);
2007 template<
typename T>
2008 bool VerifyFieldRequired(
const Verifier &verifier, voffset_t field)
const {
2009 auto field_offset = GetOptionalFieldOffset(field);
2010 return verifier.Check(field_offset != 0) &&
2011 verifier.Verify<T>(data_ + field_offset);
2015 bool VerifyOffset(
const Verifier &verifier, voffset_t field)
const {
2016 auto field_offset = GetOptionalFieldOffset(field);
2017 return !field_offset || verifier.VerifyOffset(data_ + field_offset);
2020 bool VerifyOffsetRequired(
const Verifier &verifier, voffset_t field)
const {
2021 auto field_offset = GetOptionalFieldOffset(field);
2022 return verifier.Check(field_offset != 0) &&
2023 verifier.VerifyOffset(data_ + field_offset);
2030 Table(
const Table &other);
2039 inline const uint8_t *GetBufferStartFromRootPointer(
const void *root) {
2040 auto table =
reinterpret_cast<const Table *
>(root);
2041 auto vtable = table->GetVTable();
2043 auto start = (std::min)(vtable, reinterpret_cast<const uint8_t *>(root));
2045 start =
reinterpret_cast<const uint8_t *
>(
reinterpret_cast<uintptr_t
>(start) &
2046 ~(
sizeof(uoffset_t) - 1));
2057 "file_identifier is assumed to be the same size as uoffset_t");
2058 for (
auto possible_roots = FLATBUFFERS_MAX_ALIGNMENT /
sizeof(uoffset_t) + 1;
2059 possible_roots; possible_roots--) {
2060 start -=
sizeof(uoffset_t);
2061 if (ReadScalar<uoffset_t>(start) + start ==
2062 reinterpret_cast<const uint8_t *
>(root))
2074 inline uoffset_t GetPrefixedSize(
const uint8_t* buf){
return ReadScalar<uoffset_t>(buf); }
2079 struct NativeTable {};
2089 typedef uint64_t hash_value_t;
2091 #ifdef FLATBUFFERS_CPP98_STL 2092 typedef void (*resolver_function_t)(
void **pointer_adr, hash_value_t hash);
2093 typedef hash_value_t (*rehasher_function_t)(
void *pointer);
2095 typedef std::function<void (void **pointer_adr, hash_value_t hash)>
2096 resolver_function_t;
2097 typedef std::function<hash_value_t (void *pointer)> rehasher_function_t;
2108 template<
typename T>
bool IsFieldPresent(
const T *table, voffset_t field) {
2110 return reinterpret_cast<const Table *
>(table)->CheckField(field);
2116 inline int LookupEnum(
const char **names,
const char *name) {
2117 for (
const char **p = names; *p; p++)
2118 if (!strcmp(*p, name))
return static_cast<int>(p - names);
2133 #if defined(_MSC_VER) 2134 #define MANUALLY_ALIGNED_STRUCT(alignment) \ 2135 __pragma(pack(1)); \ 2136 struct __declspec(align(alignment)) 2137 #define STRUCT_END(name, size) \ 2139 static_assert(sizeof(name) == size, "compiler breaks packing rules") 2140 #elif defined(__GNUC__) || defined(__clang__) 2141 #define MANUALLY_ALIGNED_STRUCT(alignment) \ 2142 _Pragma("pack(1)") \ 2143 struct __attribute__((aligned(alignment))) 2144 #define STRUCT_END(name, size) \ 2146 static_assert(sizeof(name) == size, "compiler breaks packing rules") 2148 #error Unknown compiler, please define structure alignment macros 2162 enum SequenceType { ST_TABLE, ST_STRUCT, ST_UNION, ST_ENUM };
2166 #define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \ 2180 ET(ET_SEQUENCE) // See SequenceType. 2182 enum ElementaryType {
2183 #define FLATBUFFERS_ET(E) E, 2184 FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
2185 #undef FLATBUFFERS_ET 2188 inline const char *
const *ElementaryTypeNames() {
2189 static const char *
const names[] = {
2190 #define FLATBUFFERS_ET(E) #E, 2191 FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
2192 #undef FLATBUFFERS_ET 2200 uint16_t base_type : 4;
2201 uint16_t is_vector : 1;
2202 int16_t sequence_ref : 11;
2205 static_assert(
sizeof(TypeCode) == 2,
"TypeCode");
2210 typedef const TypeTable *(*TypeFunction)();
2215 const TypeCode *type_codes;
2216 const TypeFunction *type_refs;
2217 const int32_t *values;
2218 const char *
const *names;
2232 #if !defined(_WIN32) && !defined(__CYGWIN__) 2234 extern volatile __attribute__((weak))
const char *flatbuffer_version_string;
2235 volatile __attribute__((weak))
const char *flatbuffer_version_string =
2237 FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR)
"." 2238 FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR)
"." 2239 FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
2241 #endif // !defined(_WIN32) && !defined(__CYGWIN__) 2243 #define DEFINE_BITMASK_OPERATORS(E, T)\ 2244 inline E operator | (E lhs, E rhs){\ 2245 return E(T(lhs) | T(rhs));\ 2247 inline E operator & (E lhs, E rhs){\ 2248 return E(T(lhs) & T(rhs));\ 2250 inline E operator ^ (E lhs, E rhs){\ 2251 return E(T(lhs) ^ T(rhs));\ 2253 inline E operator ~ (E lhs){\ 2256 inline E operator |= (E &lhs, E rhs){\ 2260 inline E operator &= (E &lhs, E rhs){\ 2264 inline E operator ^= (E &lhs, E rhs){\ 2268 inline bool operator !(E rhs) \ 2270 return !bool(T(rhs)); \ 2275 #if defined(_MSC_VER) 2276 #pragma warning(pop) 2280 #endif // FLATBUFFERS_H_ Definition: flatbuffers.h:25
Offset< Vector< T > > CreateVector(size_t vector_size, const std::function< T(size_t i)> &f)
Serialize values returned by a function into a FlatBuffer vector.
Definition: flatbuffers.h:1234
uoffset_t CreateUninitializedVector(size_t len, size_t elemsize, uint8_t **buf)
Specialized version of CreateVector for non-copying use cases.
Definition: flatbuffers.h:1492
Offset< Vector< const T * > > CreateVectorOfStructs(size_t vector_size, const std::function< void(size_t i, T *)> &filler)
Serialize an array of structs into a FlatBuffer vector.
Definition: flatbuffers.h:1314
Offset< Vector< const T * > > CreateVectorOfSortedStructs(T *v, size_t len)
Serialize an array of structs into a FlatBuffer vector in sorted order.
Definition: flatbuffers.h:1418
Offset< Vector< const T * > > CreateVectorOfSortedNativeStructs(std::vector< S > *v)
Serialize a std::vector of native structs into a FlatBuffer vector in sorted order.
Definition: flatbuffers.h:1404
uoffset_t GetSize() const
The current size of the serialized buffer, counting from the end.
Definition: flatbuffers.h:770
Offset< Vector< Offset< T > > > CreateVectorOfSortedTables(std::vector< Offset< T >> *v)
Serialize an array of table offsets as a vector in the buffer in sorted order.
Definition: flatbuffers.h:1480
Definition: flatbuffers.h:90
Helper class to hold data needed in creation of a FlatBuffer.
Definition: flatbuffers.h:718
Offset< String > CreateString(char *str)
Store a string in the buffer, which is null-terminated.
Definition: flatbuffers.h:1066
void Clear()
Reset all the state in this FlatBufferBuilder so it can be reused to construct another buffer...
Definition: flatbuffers.h:759
Offset< Vector< const T * > > CreateVectorOfStructs(size_t vector_size, F f, S *state)
Serialize an array of structs into a FlatBuffer vector.
Definition: flatbuffers.h:1336
Offset< Vector< const T * > > CreateVectorOfNativeStructs(const S *v, size_t len)
Serialize an array of native structs into a FlatBuffer vector.
Definition: flatbuffers.h:1295
Offset< const T * > CreateStruct(const T &structobj)
Write a struct by itself, typically to be part of a union.
Definition: flatbuffers.h:1518
Definition: flatbuffers.h:22
void FinishSizePrefixed(Offset< T > root, const char *file_identifier=nullptr)
Finish a buffer with a 32 bit size field pre-fixed (size of the buffer following the size field)...
Definition: flatbuffers.h:1544
Definition: flatbuffers.h:413
Offset< String > CreateSharedString(const char *str)
Store a string in the buffer, which null-terminated.
Definition: flatbuffers.h:1122
Definition: flatbuffers.h:304
Definition: flatbuffers.h:62
Offset< String > CreateString(const char *str, size_t len)
Store a string in the buffer, which can contain any binary data.
Definition: flatbuffers.h:1047
void ForceDefaults(bool fd)
In order to save space, fields that are set to their default value don't get serialized into the buff...
Definition: flatbuffers.h:825
uint8_t * GetBufferPointer() const
Get the serialized buffer (after you call Finish()).
Definition: flatbuffers.h:775
Definition: flatbuffers.h:394
void DedupVtables(bool dedup)
By default vtables are deduped in order to save space.
Definition: flatbuffers.h:829
static const size_t kFileIdentifierLength
The length of a FlatBuffer file header.
Definition: flatbuffers.h:1526
FlatBufferBuilder(size_t initial_size=1024, Allocator *allocator=nullptr, bool own_allocator=false, size_t buffer_minalign=AlignOf< largest_scalar_t >())
Default constructor for FlatBufferBuilder.
Definition: flatbuffers.h:731
Offset< String > CreateString(const String *str)
Store a string in the buffer, which can contain any binary data.
Definition: flatbuffers.h:1080
Definition: flatbuffers.h:526
Offset< Vector< const T * > > CreateVectorOfSortedNativeStructs(S *v, size_t len)
Serialize an array of native structs into a FlatBuffer vector in sorted order.
Definition: flatbuffers.h:1433
Offset< String > CreateSharedString(const String *str)
Store a string in the buffer, which can contain any binary data.
Definition: flatbuffers.h:1140
uint8_t * GetCurrentBufferPointer() const
Get a pointer to an unfinished buffer.
Definition: flatbuffers.h:782
Offset< String > CreateString(const T &str)
Store a string in the buffer, which can contain any binary data.
Definition: flatbuffers.h:1088
Offset< Vector< const T * > > CreateVectorOfSortedStructs(std::vector< T > *v)
Serialize a std::vector of structs into a FlatBuffer vector in sorted order.
Definition: flatbuffers.h:1391
Offset< Vector< Offset< String > > > CreateVectorOfStrings(const std::vector< std::string > &v)
Serialize a std::vector<std::string> into a FlatBuffer vector.
Definition: flatbuffers.h:1265
Offset< Vector< T > > CreateVector(size_t vector_size, F f, S *state)
Serialize values returned by a function into a FlatBuffer vector.
Definition: flatbuffers.h:1253
size_t GetBufferMinAlignment()
get the minimum alignment this buffer needs to be accessed properly.
Definition: flatbuffers.h:806
Offset< Vector< const T * > > CreateVectorOfStructs(const std::vector< T, Alloc > &v)
Serialize a std::vector of structs into a FlatBuffer vector.
Definition: flatbuffers.h:1353
Offset< Vector< const T * > > CreateVectorOfStructs(const T *v, size_t len)
Serialize an array of structs into a FlatBuffer vector.
Definition: flatbuffers.h:1280
Offset< Vector< const T * > > CreateVectorOfNativeStructs(const std::vector< S > &v)
Serialize a std::vector of native structs into a FlatBuffer vector.
Definition: flatbuffers.h:1367
Offset< String > CreateString(const char *str)
Store a string in the buffer, which is null-terminated.
Definition: flatbuffers.h:1059
Definition: flatbuffers.h:353
Definition: flatbuffers.h:342
Definition: flatbuffers.h:1571
Offset< String > CreateString(const std::string &str)
Store a string in the buffer, which can contain any binary data.
Definition: flatbuffers.h:1073
Offset< Vector< T > > CreateVector(const std::vector< T > &v)
Serialize a std::vector into a FlatBuffer vector.
Definition: flatbuffers.h:1210
Offset< Vector< T > > CreateUninitializedVector(size_t len, T **buf)
Specialized version of CreateVector for non-copying use cases.
Definition: flatbuffers.h:1512
Offset< Vector< T > > CreateVector(const T *v, size_t len)
Serialize an array into a FlatBuffer vector.
Definition: flatbuffers.h:1176
Offset< String > CreateSharedString(const std::string &str)
Store a string in the buffer, which can contain any binary data.
Definition: flatbuffers.h:1131
Offset< Vector< Offset< T > > > CreateVectorOfSortedTables(Offset< T > *v, size_t len)
Serialize an array of table offsets as a vector in the buffer in sorted order.
Definition: flatbuffers.h:1466
DetachedBuffer Release()
Get the released DetachedBuffer.
Definition: flatbuffers.h:796
Offset< String > CreateSharedString(const char *str, size_t len)
Store a string in the buffer, which can contain any binary data.
Definition: flatbuffers.h:1098
Definition: flatbuffers.h:181
DetachedBuffer ReleaseBufferPointer()
Get the released pointer to the serialized buffer.
Definition: flatbuffers.h:789
void Finish(Offset< T > root, const char *file_identifier=nullptr)
Finish serializing a buffer by writing the root offset.
Definition: flatbuffers.h:1532
Definition: flatbuffers.h:1597