17#ifndef FLATBUFFERS_FLEXBUFFERS_H_
18#define FLATBUFFERS_FLEXBUFFERS_H_
33# pragma warning(disable : 4127)
123 *len =
static_cast<uint8_t
>(fixed_type / 3 +
125 return static_cast<Type>(fixed_type % 3 +
FBT_INT);
138template<
typename R,
typename T1,
typename T2,
typename T4,
typename T8>
140 return byte_width < 4
142 ?
static_cast<R
>(flatbuffers::ReadScalar<T1>(data))
143 :
static_cast<R
>(flatbuffers::ReadScalar<T2>(data)))
145 ?
static_cast<R
>(flatbuffers::ReadScalar<T4>(data))
146 :
static_cast<R
>(flatbuffers::ReadScalar<T8>(data)));
149inline int64_t
ReadInt64(
const uint8_t *data, uint8_t byte_width) {
150 return ReadSizedScalar<int64_t, int8_t, int16_t, int32_t, int64_t>(
154inline uint64_t
ReadUInt64(
const uint8_t *data, uint8_t byte_width) {
162 #if defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC)
165 __movsb(
reinterpret_cast<uint8_t *
>(&u),
166 reinterpret_cast<const uint8_t *
>(data), byte_width);
167 return flatbuffers::EndianScalar(u);
169 return ReadSizedScalar<uint64_t, uint8_t, uint16_t, uint32_t, uint64_t>(
175inline double ReadDouble(
const uint8_t *data, uint8_t byte_width) {
176 return ReadSizedScalar<double, quarter, half, float, double>(data,
189#define FLATBUFFERS_GET_FIELD_BIT_WIDTH(value, width) \
191 if (!((u) & ~((1ULL << (width)) - 1ULL))) return BIT_WIDTH_##width; \
196#undef FLATBUFFERS_GET_FIELD_BIT_WIDTH
201 auto u =
static_cast<uint64_t
>(i) << 1;
202 return WidthU(i >= 0 ? u : ~u);
206 return static_cast<double>(
static_cast<float>(f)) == f ?
BIT_WIDTH_32
214 Object(
const uint8_t *data, uint8_t byte_width)
226 Sized(
const uint8_t *data, uint8_t byte_width)
229 Sized(
const uint8_t *data, uint8_t byte_width,
size_t sz)
244 String(
const uint8_t *data, uint8_t byte_width) :
Sized(data, byte_width) {}
246 String(
const uint8_t *data, uint8_t byte_width,
size_t sz)
247 :
Sized(data, byte_width, sz) {}
250 const char *
c_str()
const {
return reinterpret_cast<const char *
>(
data_); }
254 static const char *empty_string =
"";
255 return String(
reinterpret_cast<const uint8_t *
>(empty_string), 1, 0);
262 Blob(
const uint8_t *data_buf, uint8_t byte_width)
263 :
Sized(data_buf, byte_width) {}
266 static const uint8_t empty_blob[] = { 0 };
267 return Blob(empty_blob + 1, 1);
275 Vector(
const uint8_t *data, uint8_t byte_width) :
Sized(data, byte_width) {}
280 static const uint8_t empty_vector[] = { 0 };
281 return Vector(empty_vector + 1, 1);
289 :
Sized(data, byte_width), type_(element_type) {}
294 static const uint8_t empty_typed_vector[] = { 0 };
315 :
Object(data, byte_width), type_(element_type), len_(len) {}
320 static const uint8_t fixed_empty_vector[] = { 0 };
328 uint8_t
size()
const {
return len_; }
337 Map(
const uint8_t *data, uint8_t byte_width) :
Vector(data, byte_width) {}
345 const size_t num_prefixed_fields = 3;
348 static_cast<uint8_t
>(
354 static const uint8_t empty_map[] = {
357 return Map(empty_map + 4, 1);
366 for (
size_t i = 0; i < v.size(); i++) {
368 v[i].ToString(
true, keys_quoted, s);
376 : data_(nullptr), parent_width_(0), byte_width_(0), type_(
FBT_NULL) {}
378 Reference(
const uint8_t *data, uint8_t parent_width, uint8_t byte_width,
381 parent_width_(parent_width),
382 byte_width_(byte_width),
385 Reference(
const uint8_t *data, uint8_t parent_width, uint8_t packed_type)
387 parent_width_(parent_width),
388 byte_width_(static_cast<uint8_t>(1 << (packed_type & 3))),
389 type_(static_cast<
Type>(packed_type >> 2)) {}
435 return static_cast<int64_t
>(
ReadDouble(data_, parent_width_));
437 return static_cast<int64_t
>(
ReadDouble(Indirect(), byte_width_));
464 return static_cast<uint64_t
>(
ReadDouble(data_, parent_width_));
466 return static_cast<uint64_t
>(
ReadDouble(Indirect(), byte_width_));
489 return static_cast<double>(
ReadInt64(data_, parent_width_));
491 return static_cast<double>(
ReadUInt64(data_, parent_width_));
493 return static_cast<double>(
ReadInt64(Indirect(), byte_width_));
495 return static_cast<double>(
ReadUInt64(Indirect(), byte_width_));
504 return static_cast<double>(
ReadUInt64(data_, parent_width_));
515 return reinterpret_cast<const char *
>(Indirect());
525 return String(Indirect(), byte_width_);
527 auto key = Indirect();
528 return String(key, byte_width_,
529 strlen(
reinterpret_cast<const char *
>(key)));
546 void ToString(
bool strings_quoted,
bool keys_quoted, std::string &s)
const {
548 String str(Indirect(), byte_width_);
549 if (strings_quoted) {
552 s.append(str.c_str(), str.length());
554 }
else if (
IsKey()) {
561 }
else if (
IsInt()) {
570 s +=
AsBool() ?
"true" :
"false";
571 }
else if (
IsMap()) {
574 auto keys =
m.Keys();
575 auto vals =
m.Values();
576 for (
size_t i = 0; i < keys.size(); i++) {
577 bool kq = keys_quoted;
581 const char *
p = keys[i].AsKey();
593 keys[i].ToString(
true, kq, s);
595 vals[i].ToString(
true, keys_quoted, s);
596 if (i < keys.size() - 1) s +=
", ";
600 AppendToString<Vector>(s,
AsVector(), keys_quoted);
602 AppendToString<TypedVector>(s,
AsTypedVector(), keys_quoted);
608 blob.size(), &s,
true,
false);
618 return Blob(Indirect(), byte_width_);
628 return Vector(Indirect(), byte_width_);
630 return Vector::EmptyVector();
665 return Map(Indirect(), byte_width_);
671 template<
typename T> T
As()
const;
681 return Mutate(data_, i, parent_width_,
WidthI(i));
683 return Mutate(Indirect(), i, byte_width_,
WidthI(i));
685 auto u =
static_cast<uint64_t
>(i);
686 return Mutate(data_, u, parent_width_,
WidthU(u));
688 auto u =
static_cast<uint64_t
>(i);
689 return Mutate(Indirect(), u, byte_width_,
WidthU(u));
701 return Mutate(data_, u, parent_width_,
WidthU(u));
703 return Mutate(Indirect(), u, byte_width_,
WidthU(u));
705 auto i =
static_cast<int64_t
>(u);
706 return Mutate(data_, i, parent_width_,
WidthI(i));
708 auto i =
static_cast<int64_t
>(u);
709 return Mutate(Indirect(), i, byte_width_,
WidthI(i));
719 return MutateF(Indirect(), f, byte_width_,
BIT_WIDTH_32);
727 return MutateF(data_, d, parent_width_,
WidthF(d));
729 return MutateF(Indirect(), d, byte_width_,
WidthF(d));
737 if (s.IsTheEmptyString())
return false;
740 if (s.length() != len)
return false;
741 memcpy(
const_cast<char *
>(s.c_str()), str, len);
750 const uint8_t *Indirect()
const {
755 bool Mutate(
const uint8_t *dest, T t,
size_t byte_width,
757 auto fits =
static_cast<size_t>(
static_cast<size_t>(1U) << value_width) <=
760 t = flatbuffers::EndianScalar(t);
761 memcpy(
const_cast<uint8_t *
>(dest), &t, byte_width);
767 bool MutateF(
const uint8_t *dest, T t,
size_t byte_width,
769 if (byte_width ==
sizeof(
double))
770 return Mutate(dest,
static_cast<double>(t), byte_width, value_width);
771 if (byte_width ==
sizeof(
float))
772 return Mutate(dest,
static_cast<float>(t), byte_width, value_width);
779 const uint8_t *data_;
780 uint8_t parent_width_;
786template<>
inline bool Reference::As<bool>()
const {
return AsBool(); }
788template<>
inline int8_t Reference::As<int8_t>()
const {
return AsInt8(); }
789template<>
inline int16_t Reference::As<int16_t>()
const {
return AsInt16(); }
790template<>
inline int32_t Reference::As<int32_t>()
const {
return AsInt32(); }
791template<>
inline int64_t Reference::As<int64_t>()
const {
return AsInt64(); }
793template<>
inline uint8_t Reference::As<uint8_t>()
const {
return AsUInt8(); }
794template<>
inline uint16_t Reference::As<uint16_t>()
const {
797template<>
inline uint32_t Reference::As<uint32_t>()
const {
800template<>
inline uint64_t Reference::As<uint64_t>()
const {
804template<>
inline double Reference::As<double>()
const {
return AsDouble(); }
805template<>
inline float Reference::As<float>()
const {
return AsFloat(); }
808template<>
inline std::string Reference::As<std::string>()
const {
809 return AsString().str();
812template<>
inline Blob Reference::As<Blob>()
const {
return AsBlob(); }
820template<>
inline Map Reference::As<Map>()
const {
return AsMap(); }
823 return static_cast<uint8_t
>(bit_width | (
type << 2));
856template<
typename T>
int KeyCompare(
const void *key,
const void *elem) {
857 auto str_elem =
reinterpret_cast<const char *
>(
858 Indirect<T>(
reinterpret_cast<const uint8_t *
>(elem)));
859 auto skey =
reinterpret_cast<const char *
>(key);
860 return strcmp(skey, str_elem);
867 int (*comp)(
const void *,
const void *) =
nullptr;
868 switch (keys.byte_width_) {
869 case 1: comp = KeyCompare<uint8_t>;
break;
870 case 2: comp = KeyCompare<uint16_t>;
break;
871 case 4: comp = KeyCompare<uint32_t>;
break;
872 case 8: comp = KeyCompare<uint64_t>;
break;
875 auto res = std::bsearch(key, keys.data_, keys.size(), keys.byte_width_, comp);
877 auto i = (
reinterpret_cast<uint8_t *
>(res) - keys.data_) / keys.byte_width_;
878 return (*
static_cast<const Vector *
>(
this))[i];
882 return (*
this)[key.c_str()];
888 auto end = buffer +
size;
889 auto byte_width = *--end;
890 auto packed_type = *--end;
892 return Reference(end, byte_width, packed_type);
896 return GetRoot(buffer.data(), buffer.size());
922 : buf_(initial_size),
924 has_duplicate_keys_(false),
927 key_pool(KeyOffsetCompare(buf_)),
928 string_pool(StringOffsetCompare(buf_)) {
932#ifdef FLATBUFFERS_DEFAULT_DECLARATION
933 Builder(Builder &&) =
default;
934 Builder &operator=(Builder &&) =
default;
945 size_t GetSize()
const {
return buf_.size(); }
969 void Int(
const char *key, int64_t i) {
975 void UInt(
const char *key, uint64_t u) {
981 void Float(
const char *key,
float f) {
993 void Bool(
const char *key,
bool b) {
1028 size_t Key(
const char *str,
size_t len) {
1029 auto sloc = buf_.size();
1030 WriteBytes(str, len + 1);
1032 auto it = key_pool.find(sloc);
1033 if (it != key_pool.end()) {
1039 key_pool.insert(sloc);
1046 size_t Key(
const char *str) {
return Key(str, strlen(str)); }
1047 size_t Key(
const std::string &str) {
return Key(str.c_str(), str.size()); }
1050 auto reset_to = buf_.size();
1051 auto sloc = CreateBlob(str, len, 1,
FBT_STRING);
1053 StringOffset so(sloc, len);
1054 auto it = string_pool.find(so);
1055 if (it != string_pool.end()) {
1058 buf_.resize(reset_to);
1060 stack_.back().u_ = sloc;
1062 string_pool.insert(so);
1069 return String(str.c_str(), str.size());
1072 String(str.c_str(), str.length());
1075 void String(
const char *key,
const char *str) {
1079 void String(
const char *key,
const std::string &str) {
1088 size_t Blob(
const void *data,
size_t len) {
1089 return CreateBlob(data, len, 0,
FBT_BLOB);
1091 size_t Blob(
const std::vector<uint8_t> &v) {
1092 return CreateBlob(v.data(), v.size(), 0,
FBT_BLOB);
1095 void Blob(
const char *key,
const void *data,
size_t len) {
1099 void Blob(
const char *key,
const std::vector<uint8_t> &v) {
1111 return stack_.size();
1116 return stack_.size();
1122 auto vec = CreateVector(start, stack_.size() - start, 1, typed, fixed);
1124 stack_.resize(start);
1125 stack_.push_back(vec);
1126 return static_cast<size_t>(vec.u_);
1132 auto len = stack_.size() - start;
1136 for (
auto key = start; key < stack_.size(); key += 2) {
1154 auto dict =
reinterpret_cast<TwoValue *
>(stack_.data() + start);
1156 dict, dict + len, [&](
const TwoValue &a,
const TwoValue &b) ->
bool {
1157 auto as =
reinterpret_cast<const char *
>(buf_.data() + a.key.u_);
1158 auto bs =
reinterpret_cast<const char *
>(buf_.data() + b.key.u_);
1159 auto comp = strcmp(as, bs);
1169 if (!comp && &a != &b) has_duplicate_keys_ =
true;
1175 auto keys = CreateVector(start, len, 2,
true,
false);
1176 auto vec = CreateVector(start + 1, len, 2,
false,
false, &keys);
1178 stack_.resize(start);
1179 stack_.push_back(vec);
1180 return static_cast<size_t>(vec.u_);
1188 auto start = StartVector();
1190 return EndVector(start,
false,
false);
1192 template<
typename F,
typename T>
size_t Vector(F f, T &state) {
1193 auto start = StartVector();
1195 return EndVector(start,
false,
false);
1197 template<
typename F>
size_t Vector(
const char *key, F f) {
1198 auto start = StartVector(key);
1200 return EndVector(start,
false,
false);
1202 template<
typename F,
typename T>
1203 size_t Vector(
const char *key, F f, T &state) {
1204 auto start = StartVector(key);
1206 return EndVector(start,
false,
false);
1209 template<
typename T>
void Vector(
const T *elems,
size_t len) {
1212 ScalarVector(elems, len,
false);
1214 auto start = StartVector();
1215 for (
size_t i = 0; i < len; i++)
Add(elems[i]);
1216 EndVector(start,
false,
false);
1219 template<
typename T>
1220 void Vector(
const char *key,
const T *elems,
size_t len) {
1224 template<
typename T>
void Vector(
const std::vector<T> &vec) {
1225 Vector(vec.data(), vec.size());
1229 auto start = StartVector();
1231 return EndVector(start,
true,
false);
1234 auto start = StartVector();
1236 return EndVector(start,
true,
false);
1239 auto start = StartVector(key);
1241 return EndVector(start,
true,
false);
1243 template<
typename F,
typename T>
1245 auto start = StartVector(key);
1247 return EndVector(start,
true,
false);
1256 return ScalarVector(elems, len,
true);
1259 template<
typename T>
1265 template<
typename F>
size_t Map(F f) {
1266 auto start = StartMap();
1268 return EndMap(start);
1270 template<
typename F,
typename T>
size_t Map(F f, T &state) {
1271 auto start = StartMap();
1273 return EndMap(start);
1275 template<
typename F>
size_t Map(
const char *key, F f) {
1276 auto start = StartMap(key);
1278 return EndMap(start);
1280 template<
typename F,
typename T>
size_t Map(
const char *key, F f, T &state) {
1281 auto start = StartMap(key);
1283 return EndMap(start);
1285 template<
typename T>
void Map(
const std::map<std::string, T> &map) {
1286 auto start = StartMap();
1287 for (
auto it = map.begin(); it != map.end(); ++it)
1288 Add(it->first.c_str(), it->second);
1311 void Add(int8_t i) { Int(i); }
1312 void Add(int16_t i) { Int(i); }
1313 void Add(int32_t i) { Int(i); }
1314 void Add(int64_t i) { Int(i); }
1315 void Add(uint8_t u) { UInt(u); }
1316 void Add(uint16_t u) { UInt(u); }
1317 void Add(uint32_t u) { UInt(u); }
1318 void Add(uint64_t u) { UInt(u); }
1319 void Add(
float f) { Float(f); }
1320 void Add(
double d) { Double(d); }
1326 template<
typename T>
void Add(
const std::vector<T> &vec) {
Vector(vec); }
1328 template<
typename T>
void Add(
const char *key,
const T &t) {
1333 template<
typename T>
void Add(
const std::map<std::string, T> &map) {
1344 force_min_bit_width_ = bw;
1355 auto byte_width = Align(stack_[0].ElemWidth(buf_.size(), 0));
1356 WriteAny(stack_[0], byte_width);
1358 Write(stack_[0].StoredPackedType(), 1);
1360 Write(byte_width, 1);
1366 void Finished()
const {
1374 uint8_t Align(BitWidth alignment) {
1375 auto byte_width = 1U << alignment;
1376 buf_.insert(buf_.end(), flatbuffers::PaddingBytes(buf_.size(), byte_width),
1378 return static_cast<uint8_t
>(byte_width);
1381 void WriteBytes(
const void *val,
size_t size) {
1382 buf_.insert(buf_.end(),
reinterpret_cast<const uint8_t *
>(val),
1383 reinterpret_cast<const uint8_t *
>(val) +
size);
1386 template<
typename T>
void Write(T val,
size_t byte_width) {
1388 val = flatbuffers::EndianScalar(val);
1389 WriteBytes(&val, byte_width);
1392 void WriteDouble(
double f, uint8_t byte_width) {
1393 switch (byte_width) {
1394 case 8: Write(f, byte_width);
break;
1395 case 4: Write(
static_cast<float>(f), byte_width);
break;
1402 void WriteOffset(uint64_t o, uint8_t byte_width) {
1403 auto reloff = buf_.size() - o;
1405 Write(reloff, byte_width);
1408 template<
typename T>
void PushIndirect(T val, Type
type, BitWidth bit_width) {
1409 auto byte_width = Align(bit_width);
1410 auto iloc = buf_.size();
1411 Write(val, byte_width);
1412 stack_.push_back(Value(
static_cast<uint64_t
>(iloc),
type, bit_width));
1415 static BitWidth WidthB(
size_t byte_width) {
1416 switch (byte_width) {
1425 template<
typename T>
static Type GetScalarType() {
1450 : u_(static_cast<uint64_t>(b)),
1455 : i_(i), type_(t), min_bit_width_(bw) {}
1457 : u_(u), type_(t), min_bit_width_(bw) {}
1460 : f_(static_cast<double>(f)),
1466 return PackedType(StoredWidth(parent_bit_width_), type_);
1471 return min_bit_width_;
1478 for (
size_t byte_width = 1;
1479 byte_width <=
sizeof(flatbuffers::largest_scalar_t);
1482 auto offset_loc = buf_size +
1483 flatbuffers::PaddingBytes(buf_size, byte_width) +
1484 elem_index * byte_width;
1486 auto offset = offset_loc - u_;
1489 if (
static_cast<size_t>(
static_cast<size_t>(1U) << bit_width) ==
1500 return (std::max)(min_bit_width_, parent_bit_width_);
1502 return min_bit_width_;
1508 void WriteAny(
const Value &val, uint8_t byte_width) {
1509 switch (val.type_) {
1511 case FBT_INT: Write(val.i_, byte_width);
break;
1513 case FBT_UINT: Write(val.u_, byte_width);
break;
1514 case FBT_FLOAT: WriteDouble(val.f_, byte_width);
break;
1515 default: WriteOffset(val.u_, byte_width);
break;
1519 size_t CreateBlob(
const void *data,
size_t len,
size_t trailing, Type
type) {
1520 auto bit_width =
WidthU(len);
1521 auto byte_width = Align(bit_width);
1522 Write<uint64_t>(len, byte_width);
1523 auto sloc = buf_.size();
1524 WriteBytes(data, len + trailing);
1525 stack_.push_back(Value(
static_cast<uint64_t
>(sloc),
type, bit_width));
1529 template<
typename T>
1530 size_t ScalarVector(
const T *elems,
size_t len,
bool fixed) {
1531 auto vector_type = GetScalarType<T>();
1532 auto byte_width =
sizeof(T);
1533 auto bit_width = WidthB(byte_width);
1541 if (!fixed) Write<uint64_t>(len, byte_width);
1542 auto vloc = buf_.size();
1543 for (
size_t i = 0; i < len; i++) Write(elems[i], byte_width);
1544 stack_.push_back(Value(
static_cast<uint64_t
>(vloc),
1550 Value CreateVector(
size_t start,
size_t vec_len,
size_t step,
bool typed,
1551 bool fixed,
const Value *keys =
nullptr) {
1556 auto bit_width = (std::max)(force_min_bit_width_,
WidthU(vec_len));
1557 auto prefix_elems = 1;
1561 bit_width = (std::max)(bit_width, keys->ElemWidth(buf_.size(), 0));
1566 for (
size_t i = start; i < stack_.size(); i += step) {
1568 stack_[i].ElemWidth(buf_.size(), i - start + prefix_elems);
1569 bit_width = (std::max)(bit_width, elem_width);
1572 vector_type = stack_[i].type_;
1583 auto byte_width = Align(bit_width);
1586 WriteOffset(keys->u_, byte_width);
1587 Write<uint64_t>(1ULL << keys->min_bit_width_, byte_width);
1589 if (!fixed) Write<uint64_t>(vec_len, byte_width);
1591 auto vloc = buf_.size();
1592 for (
size_t i = start; i < stack_.size(); i += step) {
1593 WriteAny(stack_[i], byte_width);
1597 for (
size_t i = start; i < stack_.size(); i += step) {
1598 buf_.push_back(stack_[i].StoredPackedType(bit_width));
1601 return Value(
static_cast<uint64_t
>(vloc),
1609 Builder(
const Builder &);
1610 Builder &operator=(
const Builder &);
1612 std::vector<uint8_t> buf_;
1613 std::vector<Value> stack_;
1616 bool has_duplicate_keys_;
1622 struct KeyOffsetCompare {
1623 explicit KeyOffsetCompare(
const std::vector<uint8_t> &buf) : buf_(&
buf) {}
1624 bool operator()(
size_t a,
size_t b)
const {
1625 auto stra =
reinterpret_cast<const char *
>(buf_->data() + a);
1626 auto strb =
reinterpret_cast<const char *
>(buf_->data() +
b);
1627 return strcmp(stra, strb) < 0;
1629 const std::vector<uint8_t> *buf_;
1632 typedef std::pair<size_t, size_t> StringOffset;
1633 struct StringOffsetCompare {
1634 explicit StringOffsetCompare(
const std::vector<uint8_t> &buf)
1636 bool operator()(
const StringOffset &a,
const StringOffset &b)
const {
1637 auto stra = buf_->data() + a.first;
1638 auto strb = buf_->data() +
b.first;
1639 auto cr = memcmp(stra, strb, (std::min)(a.second,
b.second) + 1);
1640 return cr < 0 || (cr == 0 && a.second <
b.second);
1642 const std::vector<uint8_t> *buf_;
1645 typedef std::set<size_t, KeyOffsetCompare> KeyOffsetMap;
1646 typedef std::set<StringOffset, StringOffsetCompare> StringOffsetMap;
1648 KeyOffsetMap key_pool;
1649 StringOffsetMap string_pool;
1651 friend class Verifier;
1662 std::vector<uint8_t> *reuse_tracker =
nullptr,
1663 bool _check_alignment =
true,
size_t max_depth = 64)
1667 max_depth_(max_depth),
1669 max_vectors_(buf_len),
1670 check_alignment_(_check_alignment),
1671 reuse_tracker_(reuse_tracker) {
1673 if (reuse_tracker_) {
1674 reuse_tracker_->clear();
1681 bool Check(
bool ok)
const {
1683 #ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE
1691 bool VerifyFrom(
size_t elem,
size_t elem_len)
const {
1692 return Check(elem_len < size_ && elem <= size_ - elem_len);
1694 bool VerifyBefore(
size_t elem,
size_t elem_len)
const {
1695 return Check(elem_len <= elem);
1698 bool VerifyFromPointer(
const uint8_t *
p,
size_t len) {
1699 auto o =
static_cast<size_t>(
p - buf_);
1700 return VerifyFrom(o, len);
1702 bool VerifyBeforePointer(
const uint8_t *
p,
size_t len) {
1703 auto o =
static_cast<size_t>(
p - buf_);
1704 return VerifyBefore(o, len);
1707 bool VerifyByteWidth(
size_t width) {
1708 return Check(width == 1 || width == 2 || width == 4 || width == 8);
1711 bool VerifyType(
int type) {
return Check(
type >= 0 &&
type < FBT_MAX_TYPE); }
1713 bool VerifyOffset(uint64_t off,
const uint8_t *
p) {
1714 return Check(off <=
static_cast<uint64_t
>(size_)) &&
1715 off <= static_cast<uint64_t>(
p - buf_);
1718 bool VerifyAlignment(
const uint8_t *
p,
size_t size)
const {
1719 auto o =
static_cast<size_t>(
p - buf_);
1720 return Check((o & (
size - 1)) == 0 || !check_alignment_);
1724#define FLEX_CHECK_VERIFIED(P, PACKED_TYPE) \
1725 if (reuse_tracker_) { \
1726 auto packed_type = PACKED_TYPE; \
1727 auto existing = (*reuse_tracker_)[P - buf_]; \
1728 if (existing == packed_type) return true; \
1730 if (!Check(existing == 0)) return false; \
1731 (*reuse_tracker_)[P - buf_] = packed_type; \
1734 bool VerifyVector(Reference r,
const uint8_t *
p, Type elem_type) {
1739 if (!Check(depth_ <= max_depth_ && num_vectors_ <= max_vectors_))
1741 auto size_byte_width = r.byte_width_;
1742 if (!VerifyBeforePointer(
p, size_byte_width))
return false;
1744 PackedType(Builder::WidthB(size_byte_width), r.type_));
1745 auto sized = Sized(
p, size_byte_width);
1747 auto elem_byte_width = r.type_ == FBT_STRING || r.type_ == FBT_BLOB
1750 auto max_elems = SIZE_MAX / elem_byte_width;
1753 auto byte_size =
num_elems * elem_byte_width;
1754 if (!VerifyFromPointer(
p, byte_size))
return false;
1755 if (elem_type == FBT_NULL) {
1757 if (!VerifyFromPointer(
p + byte_size,
num_elems))
return false;
1758 auto v =
Vector(
p, size_byte_width);
1760 if (!VerifyRef(v[i]))
return false;
1761 }
else if (elem_type == FBT_KEY) {
1762 auto v = TypedVector(
p, elem_byte_width, FBT_KEY);
1764 if (!VerifyRef(v[i]))
return false;
1772 bool VerifyKeys(
const uint8_t *
p, uint8_t byte_width) {
1774 const size_t num_prefixed_fields = 3;
1775 if (!VerifyBeforePointer(
p, byte_width * num_prefixed_fields))
return false;
1776 p -= byte_width * num_prefixed_fields;
1778 if (!VerifyOffset(off,
p))
return false;
1779 auto key_byte_with =
1780 static_cast<uint8_t
>(
ReadUInt64(
p + byte_width, byte_width));
1781 if (!VerifyByteWidth(key_byte_with))
return false;
1782 return VerifyVector(Reference(
p, byte_width, key_byte_with, FBT_VECTOR_KEY),
1786 bool VerifyKey(
const uint8_t *
p) {
1788 while (
p < buf_ + size_)
1789 if (*
p++)
return true;
1793#undef FLEX_CHECK_VERIFIED
1795 bool VerifyTerminator(
const String &s) {
1796 return VerifyFromPointer(
reinterpret_cast<const uint8_t *
>(
s.c_str()),
1800 bool VerifyRef(Reference r) {
1802 if (!VerifyByteWidth(
r.byte_width_) || !VerifyType(
r.type_)) {
1811 if (!VerifyOffset(off,
r.data_))
return false;
1812 auto p =
r.Indirect();
1813 if (!VerifyAlignment(
p,
r.byte_width_))
return false;
1820 return VerifyVector(r,
p, FBT_NULL) && VerifyKeys(
p,
r.byte_width_);
1821 case FBT_VECTOR:
return VerifyVector(r,
p, FBT_NULL);
1829 return VerifyVector(r,
p, FBT_KEY);
1830 case FBT_BLOB:
return VerifyVector(r,
p, FBT_UINT);
1832 return VerifyVector(r,
p, FBT_UINT) &&
1833 VerifyTerminator(String(
p,
r.byte_width_));
1845 if (!VerifyType(vtype))
return false;
1846 return VerifyFromPointer(
p,
static_cast<size_t>(
r.byte_width_) * len);
1848 default:
return false;
1854 if (!Check(size_ >= 3))
return false;
1855 auto end = buf_ + size_;
1856 auto byte_width = *--end;
1857 auto packed_type = *--end;
1858 return VerifyByteWidth(byte_width) && Check(end - buf_ >= byte_width) &&
1859 VerifyRef(
Reference(end - byte_width, byte_width, packed_type));
1863 const uint8_t *buf_;
1866 const size_t max_depth_;
1867 size_t num_vectors_;
1868 const size_t max_vectors_;
1869 bool check_alignment_;
1870 std::vector<uint8_t> *reuse_tracker_;
1876 std::vector<uint8_t> *reuse_tracker =
nullptr) {
1877 Verifier verifier(buf, buf_len, reuse_tracker);
1878 return verifier.VerifyBuffer();
1883#if defined(_MSC_VER)
1884# pragma warning(pop)
void Add(const float *input1_data, const Dims< 4 > &input1_dims, const float *input2_data, const Dims< 4 > &input2_dims, float *output_data, const Dims< 4 > &output_dims)
#define FLATBUFFERS_ASSERT
Blob(const uint8_t *data_buf, uint8_t byte_width)
const uint8_t * data() const
bool IsTheEmptyBlob() const
size_t StartMap(const char *key)
void IndirectFloat(const char *key, float f)
void ReuseValue(const char *key, Value v)
size_t TypedVector(const char *key, F f)
size_t Map(const char *key, F f)
size_t Vector(const char *key, F f)
void Vector(const std::vector< T > &vec)
void Float(const char *key, float f)
void String(const flexbuffers::String &str)
void Null(const char *key)
size_t Key(const std::string &str)
void Blob(const char *key, const void *data, size_t len)
bool HasDuplicateKeys() const
size_t Key(const char *str)
void Blob(const char *key, const std::vector< uint8_t > &v)
void IndirectInt(const char *key, int64_t i)
size_t EndMap(size_t start)
size_t TypedVector(F f, T &state)
size_t Map(const char *key, F f, T &state)
void ForceMinimumBitWidth(BitWidth bw=BIT_WIDTH_8)
void String(const char *key, const flexbuffers::String &str)
void Int(const char *key, int64_t i)
void Bool(const char *key, bool b)
void IndirectUInt(uint64_t u)
void Add(const flexbuffers::String &str)
size_t StartVector(const char *key)
void Add(const std::vector< T > &vec)
void IndirectInt(int64_t i)
void Vector(const T *elems, size_t len)
void Add(const char *str)
void Map(const std::map< std::string, T > &map)
size_t String(const char *str, size_t len)
Verifier(const uint8_t *buf, size_t buf_len, std::vector< uint8_t > *reuse_tracker=nullptr, bool _check_alignment=true, size_t max_depth=64)
size_t Key(const char *str, size_t len)
void IndirectDouble(double f)
size_t TypedVector(const char *key, F f, T &state)
void UInt(const char *key, uint64_t u)
void IndirectUInt(const char *key, uint64_t u)
void Double(const char *key, double d)
size_t Map(F f, T &state)
size_t Vector(F f, T &state)
void String(const char *key, const std::string &str)
void Add(const std::string &str)
size_t EndVector(size_t start, bool typed, bool fixed)
size_t String(const char *str)
size_t String(const std::string &str)
void Add(const char *key, const T &t)
void IndirectDouble(const char *key, double d)
void Vector(const char *key, const T *elems, size_t len)
size_t Blob(const std::vector< uint8_t > &v)
Builder(size_t initial_size=256, BuilderFlag flags=BUILDER_FLAG_SHARE_KEYS)
size_t Blob(const void *data, size_t len)
void IndirectFloat(float f)
size_t Vector(const char *key, F f, T &state)
void Add(const std::map< std::string, T > &map)
size_t FixedTypedVector(const T *elems, size_t len)
void operator+=(const T &t)
const std::vector< uint8_t > & GetBuffer() const
Get the serialized buffer (after you call Finish()).
size_t FixedTypedVector(const char *key, const T *elems, size_t len)
void String(const char *key, const char *str)
Reference operator[](size_t i) const
static FixedTypedVector EmptyFixedTypedVector()
FixedTypedVector(const uint8_t *data, uint8_t byte_width, Type element_type, uint8_t len)
bool IsTheEmptyFixedTypedVector() const
Map(const uint8_t *data, uint8_t byte_width)
bool IsTheEmptyMap() const
Reference operator[](const char *key) const
Object(const uint8_t *data, uint8_t byte_width)
bool MutateString(const char *str, size_t len)
bool MutateString(const std::string &str)
std::string ToString() const
bool MutateFloat(float f)
bool MutateFloat(double d)
Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width, Type type)
TypedVector AsTypedVector() const
void ToString(bool strings_quoted, bool keys_quoted, std::string &s) const
uint32_t AsUInt32() const
bool MutateUInt(uint64_t u)
const char * AsKey() const
bool IsFixedTypedVector() const
uint16_t AsUInt16() const
FixedTypedVector AsFixedTypedVector() const
uint64_t AsUInt64() const
bool MutateInt(int64_t i)
bool IsTypedVector() const
bool MutateString(const char *str)
Reference(const uint8_t *data, uint8_t parent_width, uint8_t packed_type)
bool IsUntypedVector() const
Sized(const uint8_t *data, uint8_t byte_width)
Sized(const uint8_t *data, uint8_t byte_width, size_t sz)
String(const uint8_t *data, uint8_t byte_width, size_t sz)
bool IsTheEmptyString() const
String(const uint8_t *data, uint8_t byte_width)
static String EmptyString()
const char * c_str() const
Reference operator[](size_t i) const
static TypedVector EmptyTypedVector()
bool IsTheEmptyVector() const
TypedVector(const uint8_t *data, uint8_t byte_width, Type element_type)
static Vector EmptyVector()
Vector(const uint8_t *data, uint8_t byte_width)
Reference operator[](size_t i) const
bool IsTheEmptyVector() const
#define FLEX_CHECK_VERIFIED(P, PACKED_TYPE)
#define FLATBUFFERS_GET_FIELD_BIT_WIDTH(value, width)
__global uchar * offset(const Image *img, int x, int y)
uint64_t num_elems(const nnfw_tensorinfo *ti)
std::string NumToString(T t)
int64_t StringToInt(const char *s, int base=10)
bool EscapeString(const char *s, size_t length, std::string *_text, bool allow_non_utf8, bool natural_utf8)
bool StringToNumber(const char *s, T *val)
uint64_t StringToUInt(const char *s, int base=10)
bool VerifyBuffer(const uint8_t *buf, size_t buf_len, std::vector< uint8_t > *reuse_tracker=nullptr)
BitWidth WidthI(int64_t i)
@ BUILDER_FLAG_SHARE_KEY_VECTORS
@ BUILDER_FLAG_SHARE_KEYS_AND_STRINGS
@ BUILDER_FLAG_SHARE_KEYS
@ BUILDER_FLAG_SHARE_STRINGS
Reference GetRoot(const uint8_t *buffer, size_t size)
double ReadDouble(const uint8_t *data, uint8_t byte_width)
int KeyCompare(const void *key, const void *elem)
BitWidth WidthF(double f)
Type ToTypedVector(Type t, size_t fixed_len=0)
bool IsTypedVectorElementType(Type t)
Type ToFixedTypedVectorElementType(Type t, uint8_t *len)
Type ToTypedVectorElementType(Type t)
uint64_t ReadUInt64(const uint8_t *data, uint8_t byte_width)
bool IsTypedVector(Type t)
@ FBT_VECTOR_STRING_DEPRECATED
int64_t ReadInt64(const uint8_t *data, uint8_t byte_width)
bool IsFixedTypedVector(Type t)
R ReadSizedScalar(const uint8_t *data, uint8_t byte_width)
void AppendToString(std::string &s, T &&v, bool keys_quoted)
uint8_t PackedType(BitWidth bit_width, Type type)
const uint8_t * Indirect(const uint8_t *offset, uint8_t byte_width)
BitWidth WidthU(uint64_t u)
BitWidth ElemWidth(size_t buf_size, size_t elem_index) const
BitWidth StoredWidth(BitWidth parent_bit_width_=BIT_WIDTH_8) const
Value(uint64_t u, Type t, BitWidth bw)
uint8_t StoredPackedType(BitWidth parent_bit_width_=BIT_WIDTH_8) const
Value(int64_t i, Type t, BitWidth bw)