Support for required fields.

Change-Id: I560c7ca11b3d665eecafb528f3737b7e139ca9b0
Tested: on Linux and Windows.
This commit is contained in:
Wouter van Oortmerssen
2014-09-19 16:51:36 -07:00
parent 3f8700b296
commit 517c964fe2
21 changed files with 137 additions and 45 deletions

View File

@@ -540,6 +540,17 @@ class FlatBufferBuilder {
return vtableoffsetloc;
}
// This checks a required field has been set in a given table that has
// just been constructed.
template<typename T> void Required(Offset<T> table, voffset_t field) {
auto table_ptr = buf_.data_at(table.o);
auto vtable_ptr = table_ptr - ReadScalar<uoffset_t>(table_ptr);
bool ok = ReadScalar<voffset_t>(vtable_ptr + field) != 0;
// If this fails, the caller will show what field needs to be set.
assert(ok);
(void)ok;
}
uoffset_t StartStruct(size_t alignment) {
Align(alignment);
return GetSize();
@@ -678,15 +689,19 @@ class Verifier {
num_tables_(0), max_tables_(_max_tables)
{}
// Verify any range within the buffer.
bool Verify(const void *elem, size_t elem_len) const {
bool ok = elem >= buf_ && elem <= end_ - elem_len;
// Central location where any verification failures register.
bool Check(bool ok) const {
#ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE
assert(ok);
#endif
return ok;
}
// Verify any range within the buffer.
bool Verify(const void *elem, size_t elem_len) const {
return Check(elem >= buf_ && elem <= end_ - elem_len);
}
// Verify a range indicated by sizeof(T).
template<typename T> bool Verify(const void *elem) const {
return Verify(elem, sizeof(T));
@@ -710,8 +725,8 @@ class Verifier {
const uint8_t *end;
return !str ||
(VerifyVector(reinterpret_cast<const uint8_t *>(str), 1, &end) &&
Verify(end, 1) && // Must have terminator
*end == '\0'); // Terminating byte must be 0.
Verify(end, 1) && // Must have terminator
Check(*end == '\0')); // Terminating byte must be 0.
}
// Common code between vectors and strings.
@@ -762,11 +777,7 @@ class Verifier {
bool VerifyComplexity() {
depth_++;
num_tables_++;
bool too_complex = depth_ > max_depth_ || num_tables_ > max_tables_;
#ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE
assert(!too_complex);
#endif
return !too_complex;
return Check(depth_ <= max_depth_ && num_tables_ <= max_tables_);
}
// Called at the end of a table to pop the depth count.
@@ -876,6 +887,14 @@ class Table {
return !field_offset || verifier.Verify<T>(data_ + field_offset);
}
// VerifyField for required fields.
template<typename T> bool VerifyFieldRequired(const Verifier &verifier,
voffset_t field) const {
auto field_offset = GetOptionalFieldOffset(field);
return verifier.Check(field_offset != 0) &&
verifier.Verify<T>(data_ + field_offset);
}
private:
// private constructor & copy constructor: you obtain instances of this
// class by pointing to existing data only

View File

@@ -184,10 +184,11 @@ struct Definition {
};
struct FieldDef : public Definition {
FieldDef() : deprecated(false), padding(0), used(false) {}
FieldDef() : deprecated(false), required(false), padding(0), used(false) {}
Value value;
bool deprecated;
bool required;
size_t padding; // Bytes to always pad after this field.
bool used; // Used during JSON parsing to check for repeated fields.
};