diff options
author | qrort <[email protected]> | 2022-12-02 11:31:25 +0300 |
---|---|---|
committer | qrort <[email protected]> | 2022-12-02 11:31:25 +0300 |
commit | b1f4ffc9c8abff3ba58dc1ec9a9f92d2f0de6806 (patch) | |
tree | 2a23209faf0fea5586a6d4b9cee60d1b318d29fe /contrib/libs/flatbuffers/src/reflection.cpp | |
parent | 559174a9144de40d6bb3997ea4073c82289b4974 (diff) |
remove kikimr/driver DEPENDS
Diffstat (limited to 'contrib/libs/flatbuffers/src/reflection.cpp')
-rw-r--r-- | contrib/libs/flatbuffers/src/reflection.cpp | 713 |
1 files changed, 0 insertions, 713 deletions
diff --git a/contrib/libs/flatbuffers/src/reflection.cpp b/contrib/libs/flatbuffers/src/reflection.cpp deleted file mode 100644 index 2dedcb4f18d..00000000000 --- a/contrib/libs/flatbuffers/src/reflection.cpp +++ /dev/null @@ -1,713 +0,0 @@ -/* - * Copyright 2015 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "flatbuffers/reflection.h" - -#include "flatbuffers/util.h" - -// Helper functionality for reflection. - -namespace flatbuffers { - -int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data) { -// clang-format off - #define FLATBUFFERS_GET(T) static_cast<int64_t>(ReadScalar<T>(data)) - switch (type) { - case reflection::UType: - case reflection::Bool: - case reflection::UByte: return FLATBUFFERS_GET(uint8_t); - case reflection::Byte: return FLATBUFFERS_GET(int8_t); - case reflection::Short: return FLATBUFFERS_GET(int16_t); - case reflection::UShort: return FLATBUFFERS_GET(uint16_t); - case reflection::Int: return FLATBUFFERS_GET(int32_t); - case reflection::UInt: return FLATBUFFERS_GET(uint32_t); - case reflection::Long: return FLATBUFFERS_GET(int64_t); - case reflection::ULong: return FLATBUFFERS_GET(uint64_t); - case reflection::Float: return FLATBUFFERS_GET(float); - case reflection::Double: return FLATBUFFERS_GET(double); - case reflection::String: { - auto s = reinterpret_cast<const String *>(ReadScalar<uoffset_t>(data) + - data); - return s ? StringToInt(s->c_str()) : 0; - } - default: return 0; // Tables & vectors do not make sense. - } - #undef FLATBUFFERS_GET - // clang-format on -} - -double GetAnyValueF(reflection::BaseType type, const uint8_t *data) { - switch (type) { - case reflection::Float: return static_cast<double>(ReadScalar<float>(data)); - case reflection::Double: return ReadScalar<double>(data); - case reflection::String: { - auto s = - reinterpret_cast<const String *>(ReadScalar<uoffset_t>(data) + data); - if (s) { - double d; - StringToNumber(s->c_str(), &d); - return d; - } else { - return 0.0; - } - } - default: return static_cast<double>(GetAnyValueI(type, data)); - } -} - -std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data, - const reflection::Schema *schema, int type_index) { - switch (type) { - case reflection::Float: - case reflection::Double: return NumToString(GetAnyValueF(type, data)); - case reflection::String: { - auto s = - reinterpret_cast<const String *>(ReadScalar<uoffset_t>(data) + data); - return s ? s->c_str() : ""; - } - case reflection::Obj: - if (schema) { - // Convert the table to a string. This is mostly for debugging purposes, - // and does NOT promise to be JSON compliant. - // Also prefixes the type. - auto &objectdef = *schema->objects()->Get(type_index); - auto s = objectdef.name()->str(); - if (objectdef.is_struct()) { - s += "(struct)"; // TODO: implement this as well. - } else { - auto table_field = reinterpret_cast<const Table *>( - ReadScalar<uoffset_t>(data) + data); - s += " { "; - auto fielddefs = objectdef.fields(); - for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) { - auto &fielddef = **it; - if (!table_field->CheckField(fielddef.offset())) continue; - auto val = GetAnyFieldS(*table_field, fielddef, schema); - if (fielddef.type()->base_type() == reflection::String) { - std::string esc; - flatbuffers::EscapeString(val.c_str(), val.length(), &esc, true, - false); - val = esc; - } - s += fielddef.name()->str(); - s += ": "; - s += val; - s += ", "; - } - s += "}"; - } - return s; - } else { - return "(table)"; - } - case reflection::Vector: - return "[(elements)]"; // TODO: implement this as well. - case reflection::Union: return "(union)"; // TODO: implement this as well. - default: return NumToString(GetAnyValueI(type, data)); - } -} - -void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val) { -// clang-format off - #define FLATBUFFERS_SET(T) WriteScalar(data, static_cast<T>(val)) - switch (type) { - case reflection::UType: - case reflection::Bool: - case reflection::UByte: FLATBUFFERS_SET(uint8_t ); break; - case reflection::Byte: FLATBUFFERS_SET(int8_t ); break; - case reflection::Short: FLATBUFFERS_SET(int16_t ); break; - case reflection::UShort: FLATBUFFERS_SET(uint16_t); break; - case reflection::Int: FLATBUFFERS_SET(int32_t ); break; - case reflection::UInt: FLATBUFFERS_SET(uint32_t); break; - case reflection::Long: FLATBUFFERS_SET(int64_t ); break; - case reflection::ULong: FLATBUFFERS_SET(uint64_t); break; - case reflection::Float: FLATBUFFERS_SET(float ); break; - case reflection::Double: FLATBUFFERS_SET(double ); break; - // TODO: support strings - default: break; - } - #undef FLATBUFFERS_SET - // clang-format on -} - -void SetAnyValueF(reflection::BaseType type, uint8_t *data, double val) { - switch (type) { - case reflection::Float: WriteScalar(data, static_cast<float>(val)); break; - case reflection::Double: WriteScalar(data, val); break; - // TODO: support strings. - default: SetAnyValueI(type, data, static_cast<int64_t>(val)); break; - } -} - -void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val) { - switch (type) { - case reflection::Float: - case reflection::Double: { - double d; - StringToNumber(val, &d); - SetAnyValueF(type, data, d); - break; - } - // TODO: support strings. - default: SetAnyValueI(type, data, StringToInt(val)); break; - } -} - -// Resize a FlatBuffer in-place by iterating through all offsets in the buffer -// and adjusting them by "delta" if they straddle the start offset. -// Once that is done, bytes can now be inserted/deleted safely. -// "delta" may be negative (shrinking). -// Unless "delta" is a multiple of the largest alignment, you'll create a small -// amount of garbage space in the buffer (usually 0..7 bytes). -// If your FlatBuffer's root table is not the schema's root table, you should -// pass in your root_table type as well. -class ResizeContext { - public: - ResizeContext(const reflection::Schema &schema, uoffset_t start, int delta, - std::vector<uint8_t> *flatbuf, - const reflection::Object *root_table = nullptr) - : schema_(schema), - startptr_(vector_data(*flatbuf) + start), - delta_(delta), - buf_(*flatbuf), - dag_check_(flatbuf->size() / sizeof(uoffset_t), false) { - auto mask = static_cast<int>(sizeof(largest_scalar_t) - 1); - delta_ = (delta_ + mask) & ~mask; - if (!delta_) return; // We can't shrink by less than largest_scalar_t. - // Now change all the offsets by delta_. - auto root = GetAnyRoot(vector_data(buf_)); - Straddle<uoffset_t, 1>(vector_data(buf_), root, vector_data(buf_)); - ResizeTable(root_table ? *root_table : *schema.root_table(), root); - // We can now add or remove bytes at start. - if (delta_ > 0) - buf_.insert(buf_.begin() + start, delta_, 0); - else - buf_.erase(buf_.begin() + start + delta_, buf_.begin() + start); - } - - // Check if the range between first (lower address) and second straddles - // the insertion point. If it does, change the offset at offsetloc (of - // type T, with direction D). - template<typename T, int D> - void Straddle(const void *first, const void *second, void *offsetloc) { - if (first <= startptr_ && second >= startptr_) { - WriteScalar<T>(offsetloc, ReadScalar<T>(offsetloc) + delta_ * D); - DagCheck(offsetloc) = true; - } - } - - // This returns a boolean that records if the corresponding offset location - // has been modified already. If so, we can't even read the corresponding - // offset, since it is pointing to a location that is illegal until the - // resize actually happens. - // This must be checked for every offset, since we can't know which offsets - // will straddle and which won't. - uint8_t &DagCheck(const void *offsetloc) { - auto dag_idx = reinterpret_cast<const uoffset_t *>(offsetloc) - - reinterpret_cast<const uoffset_t *>(vector_data(buf_)); - return dag_check_[dag_idx]; - } - - void ResizeTable(const reflection::Object &objectdef, Table *table) { - if (DagCheck(table)) return; // Table already visited. - auto vtable = table->GetVTable(); - // Early out: since all fields inside the table must point forwards in - // memory, if the insertion point is before the table we can stop here. - auto tableloc = reinterpret_cast<uint8_t *>(table); - if (startptr_ <= tableloc) { - // Check if insertion point is between the table and a vtable that - // precedes it. This can't happen in current construction code, but check - // just in case we ever change the way flatbuffers are built. - Straddle<soffset_t, -1>(vtable, table, table); - } else { - // Check each field. - auto fielddefs = objectdef.fields(); - for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) { - auto &fielddef = **it; - auto base_type = fielddef.type()->base_type(); - // Ignore scalars. - if (base_type <= reflection::Double) continue; - // Ignore fields that are not stored. - auto offset = table->GetOptionalFieldOffset(fielddef.offset()); - if (!offset) continue; - // Ignore structs. - auto subobjectdef = - base_type == reflection::Obj - ? schema_.objects()->Get(fielddef.type()->index()) - : nullptr; - if (subobjectdef && subobjectdef->is_struct()) continue; - // Get this fields' offset, and read it if safe. - auto offsetloc = tableloc + offset; - if (DagCheck(offsetloc)) continue; // This offset already visited. - auto ref = offsetloc + ReadScalar<uoffset_t>(offsetloc); - Straddle<uoffset_t, 1>(offsetloc, ref, offsetloc); - // Recurse. - switch (base_type) { - case reflection::Obj: { - ResizeTable(*subobjectdef, reinterpret_cast<Table *>(ref)); - break; - } - case reflection::Vector: { - auto elem_type = fielddef.type()->element(); - if (elem_type != reflection::Obj && elem_type != reflection::String) - break; - auto vec = reinterpret_cast<Vector<uoffset_t> *>(ref); - auto elemobjectdef = - elem_type == reflection::Obj - ? schema_.objects()->Get(fielddef.type()->index()) - : nullptr; - if (elemobjectdef && elemobjectdef->is_struct()) break; - for (uoffset_t i = 0; i < vec->size(); i++) { - auto loc = vec->Data() + i * sizeof(uoffset_t); - if (DagCheck(loc)) continue; // This offset already visited. - auto dest = loc + vec->Get(i); - Straddle<uoffset_t, 1>(loc, dest, loc); - if (elemobjectdef) - ResizeTable(*elemobjectdef, reinterpret_cast<Table *>(dest)); - } - break; - } - case reflection::Union: { - ResizeTable(GetUnionType(schema_, objectdef, fielddef, *table), - reinterpret_cast<Table *>(ref)); - break; - } - case reflection::String: break; - default: FLATBUFFERS_ASSERT(false); - } - } - // Check if the vtable offset points beyond the insertion point. - // Must do this last, since GetOptionalFieldOffset above still reads - // this value. - Straddle<soffset_t, -1>(table, vtable, table); - } - } - - private: - const reflection::Schema &schema_; - uint8_t *startptr_; - int delta_; - std::vector<uint8_t> &buf_; - std::vector<uint8_t> dag_check_; -}; - -void SetString(const reflection::Schema &schema, const std::string &val, - const String *str, std::vector<uint8_t> *flatbuf, - const reflection::Object *root_table) { - auto delta = static_cast<int>(val.size()) - static_cast<int>(str->size()); - auto str_start = static_cast<uoffset_t>( - reinterpret_cast<const uint8_t *>(str) - vector_data(*flatbuf)); - auto start = str_start + static_cast<uoffset_t>(sizeof(uoffset_t)); - if (delta) { - // Clear the old string, since we don't want parts of it remaining. - memset(vector_data(*flatbuf) + start, 0, str->size()); - // Different size, we must expand (or contract). - ResizeContext(schema, start, delta, flatbuf, root_table); - // Set the new length. - WriteScalar(vector_data(*flatbuf) + str_start, - static_cast<uoffset_t>(val.size())); - } - // Copy new data. Safe because we created the right amount of space. - memcpy(vector_data(*flatbuf) + start, val.c_str(), val.size() + 1); -} - -uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize, - const VectorOfAny *vec, uoffset_t num_elems, - uoffset_t elem_size, std::vector<uint8_t> *flatbuf, - const reflection::Object *root_table) { - auto delta_elem = static_cast<int>(newsize) - static_cast<int>(num_elems); - auto delta_bytes = delta_elem * static_cast<int>(elem_size); - auto vec_start = - reinterpret_cast<const uint8_t *>(vec) - vector_data(*flatbuf); - auto start = static_cast<uoffset_t>(vec_start + sizeof(uoffset_t) + - elem_size * num_elems); - if (delta_bytes) { - if (delta_elem < 0) { - // Clear elements we're throwing away, since some might remain in the - // buffer. - auto size_clear = -delta_elem * elem_size; - memset(vector_data(*flatbuf) + start - size_clear, 0, size_clear); - } - ResizeContext(schema, start, delta_bytes, flatbuf, root_table); - WriteScalar(vector_data(*flatbuf) + vec_start, newsize); // Length field. - // Set new elements to 0.. this can be overwritten by the caller. - if (delta_elem > 0) { - memset(vector_data(*flatbuf) + start, 0, delta_elem * elem_size); - } - } - return vector_data(*flatbuf) + start; -} - -const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf, - const uint8_t *newbuf, size_t newlen) { - // Align to sizeof(uoffset_t) past sizeof(largest_scalar_t) since we're - // going to chop off the root offset. - while ((flatbuf.size() & (sizeof(uoffset_t) - 1)) || - !(flatbuf.size() & (sizeof(largest_scalar_t) - 1))) { - flatbuf.push_back(0); - } - auto insertion_point = static_cast<uoffset_t>(flatbuf.size()); - // Insert the entire FlatBuffer minus the root pointer. - flatbuf.insert(flatbuf.end(), newbuf + sizeof(uoffset_t), newbuf + newlen); - auto root_offset = ReadScalar<uoffset_t>(newbuf) - sizeof(uoffset_t); - return vector_data(flatbuf) + insertion_point + root_offset; -} - -void CopyInline(FlatBufferBuilder &fbb, const reflection::Field &fielddef, - const Table &table, size_t align, size_t size) { - fbb.Align(align); - fbb.PushBytes(table.GetStruct<const uint8_t *>(fielddef.offset()), size); - fbb.TrackField(fielddef.offset(), fbb.GetSize()); -} - -Offset<const Table *> CopyTable(FlatBufferBuilder &fbb, - const reflection::Schema &schema, - const reflection::Object &objectdef, - const Table &table, bool use_string_pooling) { - // Before we can construct the table, we have to first generate any - // subobjects, and collect their offsets. - std::vector<uoffset_t> offsets; - auto fielddefs = objectdef.fields(); - for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) { - auto &fielddef = **it; - // Skip if field is not present in the source. - if (!table.CheckField(fielddef.offset())) continue; - uoffset_t offset = 0; - switch (fielddef.type()->base_type()) { - case reflection::String: { - offset = use_string_pooling - ? fbb.CreateSharedString(GetFieldS(table, fielddef)).o - : fbb.CreateString(GetFieldS(table, fielddef)).o; - break; - } - case reflection::Obj: { - auto &subobjectdef = *schema.objects()->Get(fielddef.type()->index()); - if (!subobjectdef.is_struct()) { - offset = CopyTable(fbb, schema, subobjectdef, - *GetFieldT(table, fielddef), use_string_pooling) - .o; - } - break; - } - case reflection::Union: { - auto &subobjectdef = GetUnionType(schema, objectdef, fielddef, table); - offset = CopyTable(fbb, schema, subobjectdef, - *GetFieldT(table, fielddef), use_string_pooling) - .o; - break; - } - case reflection::Vector: { - auto vec = - table.GetPointer<const Vector<Offset<Table>> *>(fielddef.offset()); - auto element_base_type = fielddef.type()->element(); - auto elemobjectdef = - element_base_type == reflection::Obj - ? schema.objects()->Get(fielddef.type()->index()) - : nullptr; - switch (element_base_type) { - case reflection::String: { - std::vector<Offset<const String *>> elements(vec->size()); - auto vec_s = reinterpret_cast<const Vector<Offset<String>> *>(vec); - for (uoffset_t i = 0; i < vec_s->size(); i++) { - elements[i] = use_string_pooling - ? fbb.CreateSharedString(vec_s->Get(i)).o - : fbb.CreateString(vec_s->Get(i)).o; - } - offset = fbb.CreateVector(elements).o; - break; - } - case reflection::Obj: { - if (!elemobjectdef->is_struct()) { - std::vector<Offset<const Table *>> elements(vec->size()); - for (uoffset_t i = 0; i < vec->size(); i++) { - elements[i] = CopyTable(fbb, schema, *elemobjectdef, - *vec->Get(i), use_string_pooling); - } - offset = fbb.CreateVector(elements).o; - break; - } - } - FLATBUFFERS_FALLTHROUGH(); // fall thru - default: { // Scalars and structs. - auto element_size = GetTypeSize(element_base_type); - if (elemobjectdef && elemobjectdef->is_struct()) - element_size = elemobjectdef->bytesize(); - fbb.StartVector(vec->size(), element_size); - fbb.PushBytes(vec->Data(), element_size * vec->size()); - offset = fbb.EndVector(vec->size()); - break; - } - } - break; - } - default: // Scalars. - break; - } - if (offset) { offsets.push_back(offset); } - } - // Now we can build the actual table from either offsets or scalar data. - auto start = objectdef.is_struct() ? fbb.StartStruct(objectdef.minalign()) - : fbb.StartTable(); - size_t offset_idx = 0; - for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) { - auto &fielddef = **it; - if (!table.CheckField(fielddef.offset())) continue; - auto base_type = fielddef.type()->base_type(); - switch (base_type) { - case reflection::Obj: { - auto &subobjectdef = *schema.objects()->Get(fielddef.type()->index()); - if (subobjectdef.is_struct()) { - CopyInline(fbb, fielddef, table, subobjectdef.minalign(), - subobjectdef.bytesize()); - break; - } - } - FLATBUFFERS_FALLTHROUGH(); // fall thru - case reflection::Union: - case reflection::String: - case reflection::Vector: - fbb.AddOffset(fielddef.offset(), Offset<void>(offsets[offset_idx++])); - break; - default: { // Scalars. - auto size = GetTypeSize(base_type); - CopyInline(fbb, fielddef, table, size, size); - break; - } - } - } - FLATBUFFERS_ASSERT(offset_idx == offsets.size()); - if (objectdef.is_struct()) { - fbb.ClearOffsets(); - return fbb.EndStruct(); - } else { - return fbb.EndTable(start); - } -} - -bool VerifyStruct(flatbuffers::Verifier &v, - const flatbuffers::Table &parent_table, - voffset_t field_offset, const reflection::Object &obj, - bool required) { - auto offset = parent_table.GetOptionalFieldOffset(field_offset); - if (required && !offset) { return false; } - - return !offset || v.Verify(reinterpret_cast<const uint8_t *>(&parent_table), - offset, obj.bytesize()); -} - -bool VerifyVectorOfStructs(flatbuffers::Verifier &v, - const flatbuffers::Table &parent_table, - voffset_t field_offset, - const reflection::Object &obj, bool required) { - auto p = parent_table.GetPointer<const uint8_t *>(field_offset); - if (required && !p) { return false; } - - return !p || v.VerifyVectorOrString(p, obj.bytesize()); -} - -// forward declare to resolve cyclic deps between VerifyObject and VerifyVector -bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema, - const reflection::Object &obj, - const flatbuffers::Table *table, bool required); - -bool VerifyUnion(flatbuffers::Verifier &v, const reflection::Schema &schema, - uint8_t utype, const uint8_t *elem, - const reflection::Field &union_field) { - if (!utype) return true; // Not present. - auto fb_enum = schema.enums()->Get(union_field.type()->index()); - if (utype >= fb_enum->values()->size()) return false; - auto elem_type = fb_enum->values()->Get(utype)->union_type(); - switch (elem_type->base_type()) { - case reflection::Obj: { - auto elem_obj = schema.objects()->Get(elem_type->index()); - if (elem_obj->is_struct()) { - return v.VerifyFromPointer(elem, elem_obj->bytesize()); - } else { - return VerifyObject(v, schema, *elem_obj, - reinterpret_cast<const flatbuffers::Table *>(elem), - true); - } - } - case reflection::String: - return v.VerifyString( - reinterpret_cast<const flatbuffers::String *>(elem)); - default: return false; - } -} - -bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema, - const flatbuffers::Table &table, - const reflection::Field &vec_field) { - FLATBUFFERS_ASSERT(vec_field.type()->base_type() == reflection::Vector); - if (!table.VerifyField<uoffset_t>(v, vec_field.offset())) return false; - - switch (vec_field.type()->element()) { - case reflection::UType: - return v.VerifyVector(flatbuffers::GetFieldV<uint8_t>(table, vec_field)); - case reflection::Bool: - case reflection::Byte: - case reflection::UByte: - return v.VerifyVector(flatbuffers::GetFieldV<int8_t>(table, vec_field)); - case reflection::Short: - case reflection::UShort: - return v.VerifyVector(flatbuffers::GetFieldV<int16_t>(table, vec_field)); - case reflection::Int: - case reflection::UInt: - return v.VerifyVector(flatbuffers::GetFieldV<int32_t>(table, vec_field)); - case reflection::Long: - case reflection::ULong: - return v.VerifyVector(flatbuffers::GetFieldV<int64_t>(table, vec_field)); - case reflection::Float: - return v.VerifyVector(flatbuffers::GetFieldV<float>(table, vec_field)); - case reflection::Double: - return v.VerifyVector(flatbuffers::GetFieldV<double>(table, vec_field)); - case reflection::String: { - auto vec_string = - flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::String>>( - table, vec_field); - if (v.VerifyVector(vec_string) && v.VerifyVectorOfStrings(vec_string)) { - return true; - } else { - return false; - } - } - case reflection::Obj: { - auto obj = schema.objects()->Get(vec_field.type()->index()); - if (obj->is_struct()) { - return VerifyVectorOfStructs(v, table, vec_field.offset(), *obj, - vec_field.required()); - } else { - auto vec = - flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::Table>>( - table, vec_field); - if (!v.VerifyVector(vec)) return false; - if (!vec) return true; - for (uoffset_t j = 0; j < vec->size(); j++) { - if (!VerifyObject(v, schema, *obj, vec->Get(j), true)) { - return false; - } - } - return true; - } - } - case reflection::Union: { - auto vec = flatbuffers::GetFieldV<flatbuffers::Offset<uint8_t>>( - table, vec_field); - if (!v.VerifyVector(vec)) return false; - if (!vec) return true; - auto type_vec = table.GetPointer<Vector<uint8_t> *>(vec_field.offset() - - sizeof(voffset_t)); - if (!v.VerifyVector(type_vec)) return false; - for (uoffset_t j = 0; j < vec->size(); j++) { - // get union type from the prev field - auto utype = type_vec->Get(j); - auto elem = vec->Get(j); - if (!VerifyUnion(v, schema, utype, elem, vec_field)) return false; - } - return true; - } - case reflection::Vector: - case reflection::None: - default: FLATBUFFERS_ASSERT(false); return false; - } -} - -bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema, - const reflection::Object &obj, - const flatbuffers::Table *table, bool required) { - if (!table) return !required; - if (!table->VerifyTableStart(v)) return false; - for (uoffset_t i = 0; i < obj.fields()->size(); i++) { - auto field_def = obj.fields()->Get(i); - switch (field_def->type()->base_type()) { - case reflection::None: FLATBUFFERS_ASSERT(false); break; - case reflection::UType: - if (!table->VerifyField<uint8_t>(v, field_def->offset())) return false; - break; - case reflection::Bool: - case reflection::Byte: - case reflection::UByte: - if (!table->VerifyField<int8_t>(v, field_def->offset())) return false; - break; - case reflection::Short: - case reflection::UShort: - if (!table->VerifyField<int16_t>(v, field_def->offset())) return false; - break; - case reflection::Int: - case reflection::UInt: - if (!table->VerifyField<int32_t>(v, field_def->offset())) return false; - break; - case reflection::Long: - case reflection::ULong: - if (!table->VerifyField<int64_t>(v, field_def->offset())) return false; - break; - case reflection::Float: - if (!table->VerifyField<float>(v, field_def->offset())) return false; - break; - case reflection::Double: - if (!table->VerifyField<double>(v, field_def->offset())) return false; - break; - case reflection::String: - if (!table->VerifyField<uoffset_t>(v, field_def->offset()) || - !v.VerifyString(flatbuffers::GetFieldS(*table, *field_def))) { - return false; - } - break; - case reflection::Vector: - if (!VerifyVector(v, schema, *table, *field_def)) return false; - break; - case reflection::Obj: { - auto child_obj = schema.objects()->Get(field_def->type()->index()); - if (child_obj->is_struct()) { - if (!VerifyStruct(v, *table, field_def->offset(), *child_obj, - field_def->required())) { - return false; - } - } else { - if (!VerifyObject(v, schema, *child_obj, - flatbuffers::GetFieldT(*table, *field_def), - field_def->required())) { - return false; - } - } - break; - } - case reflection::Union: { - // get union type from the prev field - voffset_t utype_offset = field_def->offset() - sizeof(voffset_t); - auto utype = table->GetField<uint8_t>(utype_offset, 0); - auto uval = reinterpret_cast<const uint8_t *>( - flatbuffers::GetFieldT(*table, *field_def)); - if (!VerifyUnion(v, schema, utype, uval, *field_def)) { return false; } - break; - } - default: FLATBUFFERS_ASSERT(false); break; - } - } - - if (!v.EndTable()) return false; - - return true; -} - -bool Verify(const reflection::Schema &schema, const reflection::Object &root, - const uint8_t *buf, size_t length, uoffset_t max_depth /*= 64*/, - uoffset_t max_tables /*= 1000000*/) { - Verifier v(buf, length, max_depth, max_tables); - return VerifyObject(v, schema, root, flatbuffers::GetAnyRoot(buf), true); -} - -} // namespace flatbuffers |