File indexing completed on 2025-08-27 09:30:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef FLATBUFFERS_REFLECTION_H_
0018 #define FLATBUFFERS_REFLECTION_H_
0019
0020
0021
0022
0023
0024
0025 #include "flatbuffers/reflection_generated.h"
0026
0027
0028
0029 namespace flatbuffers {
0030
0031
0032
0033 inline bool IsScalar(reflection::BaseType t) {
0034 return t >= reflection::UType && t <= reflection::Double;
0035 }
0036 inline bool IsInteger(reflection::BaseType t) {
0037 return t >= reflection::UType && t <= reflection::ULong;
0038 }
0039 inline bool IsFloat(reflection::BaseType t) {
0040 return t == reflection::Float || t == reflection::Double;
0041 }
0042 inline bool IsLong(reflection::BaseType t) {
0043 return t == reflection::Long || t == reflection::ULong;
0044 }
0045
0046
0047 inline size_t GetTypeSize(reflection::BaseType base_type) {
0048
0049 static size_t sizes[] = {
0050 0,
0051 1,
0052 1,
0053 1,
0054 1,
0055 2,
0056 2,
0057 4,
0058 4,
0059 8,
0060 8,
0061 4,
0062 8,
0063 4,
0064 4,
0065 4,
0066 4,
0067 0,
0068
0069 8,
0070
0071 0
0072 };
0073 static_assert(sizeof(sizes) / sizeof(size_t) == reflection::MaxBaseType + 1,
0074 "Size of sizes[] array does not match the count of BaseType "
0075 "enum values.");
0076 return sizes[base_type];
0077 }
0078
0079
0080
0081 inline size_t GetTypeSizeInline(reflection::BaseType base_type, int type_index,
0082 const reflection::Schema &schema) {
0083 if (base_type == reflection::Obj &&
0084 schema.objects()->Get(type_index)->is_struct()) {
0085 return schema.objects()->Get(type_index)->bytesize();
0086 } else {
0087 return GetTypeSize(base_type);
0088 }
0089 }
0090
0091
0092 inline Table *GetAnyRoot(uint8_t *const flatbuf) {
0093 return GetMutableRoot<Table>(flatbuf);
0094 }
0095
0096 inline const Table *GetAnyRoot(const uint8_t *const flatbuf) {
0097 return GetRoot<Table>(flatbuf);
0098 }
0099
0100 inline Table *GetAnySizePrefixedRoot(uint8_t *const flatbuf) {
0101 return GetMutableSizePrefixedRoot<Table>(flatbuf);
0102 }
0103
0104 inline const Table *GetAnySizePrefixedRoot(const uint8_t *const flatbuf) {
0105 return GetSizePrefixedRoot<Table>(flatbuf);
0106 }
0107
0108
0109 template<typename T> T GetFieldDefaultI(const reflection::Field &field) {
0110 FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
0111 return static_cast<T>(field.default_integer());
0112 }
0113
0114
0115 template<typename T> T GetFieldDefaultF(const reflection::Field &field) {
0116 FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
0117 return static_cast<T>(field.default_real());
0118 }
0119
0120
0121 template<typename T>
0122 T GetFieldI(const Table &table, const reflection::Field &field) {
0123 FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
0124 return table.GetField<T>(field.offset(),
0125 static_cast<T>(field.default_integer()));
0126 }
0127
0128
0129 template<typename T>
0130 T GetFieldF(const Table &table, const reflection::Field &field) {
0131 FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
0132 return table.GetField<T>(field.offset(),
0133 static_cast<T>(field.default_real()));
0134 }
0135
0136
0137 inline const String *GetFieldS(const Table &table,
0138 const reflection::Field &field) {
0139 FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::String);
0140 return table.GetPointer<const String *>(field.offset());
0141 }
0142
0143
0144 template<typename T>
0145 Vector<T> *GetFieldV(const Table &table, const reflection::Field &field) {
0146 FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Vector &&
0147 sizeof(T) == GetTypeSize(field.type()->element()));
0148 return table.GetPointer<Vector<T> *>(field.offset());
0149 }
0150
0151
0152
0153
0154 inline VectorOfAny *GetFieldAnyV(const Table &table,
0155 const reflection::Field &field) {
0156 return table.GetPointer<VectorOfAny *>(field.offset());
0157 }
0158
0159
0160 inline Table *GetFieldT(const Table &table, const reflection::Field &field) {
0161 FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj ||
0162 field.type()->base_type() == reflection::Union);
0163 return table.GetPointer<Table *>(field.offset());
0164 }
0165
0166
0167 inline const Struct *GetFieldStruct(const Table &table,
0168 const reflection::Field &field) {
0169
0170
0171 FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj);
0172 return table.GetStruct<const Struct *>(field.offset());
0173 }
0174
0175
0176 inline const Struct *GetFieldStruct(const Struct &structure,
0177 const reflection::Field &field) {
0178 FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj);
0179 return structure.GetStruct<const Struct *>(field.offset());
0180 }
0181
0182
0183
0184
0185
0186 int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data);
0187
0188
0189 double GetAnyValueF(reflection::BaseType type, const uint8_t *data);
0190
0191
0192 std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
0193 const reflection::Schema *schema, int type_index);
0194
0195
0196 inline int64_t GetAnyFieldI(const Table &table,
0197 const reflection::Field &field) {
0198 auto field_ptr = table.GetAddressOf(field.offset());
0199 return field_ptr ? GetAnyValueI(field.type()->base_type(), field_ptr)
0200 : field.default_integer();
0201 }
0202
0203
0204 inline double GetAnyFieldF(const Table &table, const reflection::Field &field) {
0205 auto field_ptr = table.GetAddressOf(field.offset());
0206 return field_ptr ? GetAnyValueF(field.type()->base_type(), field_ptr)
0207 : field.default_real();
0208 }
0209
0210
0211
0212
0213 inline std::string GetAnyFieldS(const Table &table,
0214 const reflection::Field &field,
0215 const reflection::Schema *schema) {
0216 auto field_ptr = table.GetAddressOf(field.offset());
0217 return field_ptr ? GetAnyValueS(field.type()->base_type(), field_ptr, schema,
0218 field.type()->index())
0219 : "";
0220 }
0221
0222
0223 inline int64_t GetAnyFieldI(const Struct &st, const reflection::Field &field) {
0224 return GetAnyValueI(field.type()->base_type(),
0225 st.GetAddressOf(field.offset()));
0226 }
0227
0228
0229 inline double GetAnyFieldF(const Struct &st, const reflection::Field &field) {
0230 return GetAnyValueF(field.type()->base_type(),
0231 st.GetAddressOf(field.offset()));
0232 }
0233
0234
0235 inline std::string GetAnyFieldS(const Struct &st,
0236 const reflection::Field &field) {
0237 return GetAnyValueS(field.type()->base_type(),
0238 st.GetAddressOf(field.offset()), nullptr, -1);
0239 }
0240
0241
0242 inline int64_t GetAnyVectorElemI(const VectorOfAny *vec,
0243 reflection::BaseType elem_type, size_t i) {
0244 return GetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i);
0245 }
0246
0247
0248 inline double GetAnyVectorElemF(const VectorOfAny *vec,
0249 reflection::BaseType elem_type, size_t i) {
0250 return GetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i);
0251 }
0252
0253
0254 inline std::string GetAnyVectorElemS(const VectorOfAny *vec,
0255 reflection::BaseType elem_type, size_t i) {
0256 return GetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i,
0257 nullptr, -1);
0258 }
0259
0260
0261
0262
0263 template<typename T>
0264 T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) {
0265 auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i;
0266 return reinterpret_cast<T *>(elem_ptr + ReadScalar<uoffset_t>(elem_ptr));
0267 }
0268
0269
0270
0271
0272
0273
0274 template<typename T>
0275 T *GetAnyVectorElemAddressOf(const VectorOfAny *vec, size_t i,
0276 size_t elem_size) {
0277 return reinterpret_cast<T *>(vec->Data() + elem_size * i);
0278 }
0279
0280
0281 template<typename T>
0282 T *GetAnyFieldAddressOf(const Table &table, const reflection::Field &field) {
0283 return reinterpret_cast<T *>(table.GetAddressOf(field.offset()));
0284 }
0285
0286
0287 template<typename T>
0288 T *GetAnyFieldAddressOf(const Struct &st, const reflection::Field &field) {
0289 return reinterpret_cast<T *>(st.GetAddressOf(field.offset()));
0290 }
0291
0292
0293
0294
0295 void ForAllFields(const reflection::Object *object, bool reverse,
0296 std::function<void(const reflection::Field *)> func);
0297
0298
0299
0300
0301 template<typename T>
0302 bool SetField(Table *table, const reflection::Field &field, T val) {
0303 reflection::BaseType type = field.type()->base_type();
0304 if (!IsScalar(type)) { return false; }
0305 FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(type));
0306 T def;
0307 if (IsInteger(type)) {
0308 def = GetFieldDefaultI<T>(field);
0309 } else {
0310 FLATBUFFERS_ASSERT(IsFloat(type));
0311 def = GetFieldDefaultF<T>(field);
0312 }
0313 return table->SetField(field.offset(), val, def);
0314 }
0315
0316
0317
0318
0319
0320 void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val);
0321 void SetAnyValueF(reflection::BaseType type, uint8_t *data, double val);
0322 void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val);
0323
0324
0325 inline bool SetAnyFieldI(Table *table, const reflection::Field &field,
0326 int64_t val) {
0327 auto field_ptr = table->GetAddressOf(field.offset());
0328 if (!field_ptr) return val == GetFieldDefaultI<int64_t>(field);
0329 SetAnyValueI(field.type()->base_type(), field_ptr, val);
0330 return true;
0331 }
0332
0333
0334 inline bool SetAnyFieldF(Table *table, const reflection::Field &field,
0335 double val) {
0336 auto field_ptr = table->GetAddressOf(field.offset());
0337 if (!field_ptr) return val == GetFieldDefaultF<double>(field);
0338 SetAnyValueF(field.type()->base_type(), field_ptr, val);
0339 return true;
0340 }
0341
0342
0343 inline bool SetAnyFieldS(Table *table, const reflection::Field &field,
0344 const char *val) {
0345 auto field_ptr = table->GetAddressOf(field.offset());
0346 if (!field_ptr) return false;
0347 SetAnyValueS(field.type()->base_type(), field_ptr, val);
0348 return true;
0349 }
0350
0351
0352 inline void SetAnyFieldI(Struct *st, const reflection::Field &field,
0353 int64_t val) {
0354 SetAnyValueI(field.type()->base_type(), st->GetAddressOf(field.offset()),
0355 val);
0356 }
0357
0358
0359 inline void SetAnyFieldF(Struct *st, const reflection::Field &field,
0360 double val) {
0361 SetAnyValueF(field.type()->base_type(), st->GetAddressOf(field.offset()),
0362 val);
0363 }
0364
0365
0366 inline void SetAnyFieldS(Struct *st, const reflection::Field &field,
0367 const char *val) {
0368 SetAnyValueS(field.type()->base_type(), st->GetAddressOf(field.offset()),
0369 val);
0370 }
0371
0372
0373 inline void SetAnyVectorElemI(VectorOfAny *vec, reflection::BaseType elem_type,
0374 size_t i, int64_t val) {
0375 SetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
0376 }
0377
0378
0379 inline void SetAnyVectorElemF(VectorOfAny *vec, reflection::BaseType elem_type,
0380 size_t i, double val) {
0381 SetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
0382 }
0383
0384
0385 inline void SetAnyVectorElemS(VectorOfAny *vec, reflection::BaseType elem_type,
0386 size_t i, const char *val) {
0387 SetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
0388 }
0389
0390
0391
0392
0393
0394 template<typename T, typename U> class pointer_inside_vector {
0395 public:
0396 pointer_inside_vector(T *ptr, std::vector<U> &vec)
0397 : offset_(reinterpret_cast<uint8_t *>(ptr) -
0398 reinterpret_cast<uint8_t *>(vec.data())),
0399 vec_(vec) {}
0400
0401 T *operator*() const {
0402 return reinterpret_cast<T *>(reinterpret_cast<uint8_t *>(vec_.data()) +
0403 offset_);
0404 }
0405 T *operator->() const { return operator*(); }
0406
0407 private:
0408 size_t offset_;
0409 std::vector<U> &vec_;
0410 };
0411
0412
0413 template<typename T, typename U>
0414 pointer_inside_vector<T, U> piv(T *ptr, std::vector<U> &vec) {
0415 return pointer_inside_vector<T, U>(ptr, vec);
0416 }
0417
0418 inline const char *UnionTypeFieldSuffix() { return "_type"; }
0419
0420
0421 inline const reflection::Object &GetUnionType(
0422 const reflection::Schema &schema, const reflection::Object &parent,
0423 const reflection::Field &unionfield, const Table &table) {
0424 auto enumdef = schema.enums()->Get(unionfield.type()->index());
0425
0426 auto type_field = parent.fields()->LookupByKey(
0427 (unionfield.name()->str() + UnionTypeFieldSuffix()).c_str());
0428 FLATBUFFERS_ASSERT(type_field);
0429 auto union_type = GetFieldI<uint8_t>(table, *type_field);
0430 auto enumval = enumdef->values()->LookupByKey(union_type);
0431 return *schema.objects()->Get(enumval->union_type()->index());
0432 }
0433
0434
0435
0436
0437
0438
0439 void SetString(const reflection::Schema &schema, const std::string &val,
0440 const String *str, std::vector<uint8_t> *flatbuf,
0441 const reflection::Object *root_table = nullptr);
0442
0443
0444
0445
0446
0447
0448 uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
0449 const VectorOfAny *vec, uoffset_t num_elems,
0450 uoffset_t elem_size, std::vector<uint8_t> *flatbuf,
0451 const reflection::Object *root_table = nullptr);
0452
0453 template<typename T>
0454 void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
0455 const Vector<T> *vec, std::vector<uint8_t> *flatbuf,
0456 const reflection::Object *root_table = nullptr) {
0457 auto delta_elem = static_cast<int>(newsize) - static_cast<int>(vec->size());
0458 auto newelems = ResizeAnyVector(
0459 schema, newsize, reinterpret_cast<const VectorOfAny *>(vec), vec->size(),
0460 static_cast<uoffset_t>(sizeof(T)), flatbuf, root_table);
0461
0462 for (int i = 0; i < delta_elem; i++) {
0463 auto loc = newelems + i * sizeof(T);
0464 auto is_scalar = flatbuffers::is_scalar<T>::value;
0465 if (is_scalar) {
0466 WriteScalar(loc, val);
0467 } else {
0468 *reinterpret_cast<T *>(loc) = val;
0469 }
0470 }
0471 }
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481 const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf,
0482 const uint8_t *newbuf, size_t newlen);
0483
0484 inline bool SetFieldT(Table *table, const reflection::Field &field,
0485 const uint8_t *val) {
0486 FLATBUFFERS_ASSERT(sizeof(uoffset_t) ==
0487 GetTypeSize(field.type()->base_type()));
0488 return table->SetPointer(field.offset(), val);
0489 }
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502 Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
0503 const reflection::Schema &schema,
0504 const reflection::Object &objectdef,
0505 const Table &table,
0506 bool use_string_pooling = false);
0507
0508
0509
0510
0511
0512 bool Verify(const reflection::Schema &schema, const reflection::Object &root,
0513 const uint8_t *buf, size_t length, uoffset_t max_depth = 64,
0514 uoffset_t max_tables = 1000000);
0515
0516 bool VerifySizePrefixed(const reflection::Schema &schema,
0517 const reflection::Object &root, const uint8_t *buf,
0518 size_t length, uoffset_t max_depth = 64,
0519 uoffset_t max_tables = 1000000);
0520
0521 }
0522
0523 #endif