Made "field set more than once" check in JSON parser faster.

Change-Id: I3ecc1aa610526c270faa56cc5266f14cd81db247
Tested: on Linux.
This commit is contained in:
Wouter van Oortmerssen 2014-09-04 11:57:09 -07:00
parent ea57dfe897
commit 11f2538610
3 changed files with 14 additions and 7 deletions

View File

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

View File

@ -457,10 +457,6 @@ uoffset_t Parser::ParseTable(const StructDef &struct_def) {
|| struct_def.fields.vec[fieldn] != field)) {
Error("struct field appearing out of order: " + name);
}
for (auto it = field_stack_.rbegin();
it != field_stack_.rbegin() + fieldn; ++it) {
if (it->second == field) Error("field already set: " + name);
}
Expect(':');
Value val = field->value;
ParseAnyValue(val, field);
@ -469,6 +465,16 @@ uoffset_t Parser::ParseTable(const StructDef &struct_def) {
if (IsNext('}')) break;
Expect(',');
}
for (auto it = field_stack_.rbegin();
it != field_stack_.rbegin() + fieldn; ++it) {
if (it->second->used)
Error("field set more than once: " + it->second->name);
it->second->used = true;
}
for (auto it = field_stack_.rbegin();
it != field_stack_.rbegin() + fieldn; ++it) {
it->second->used = false;
}
if (struct_def.fixed && fieldn != struct_def.fields.vec.size())
Error("incomplete struct initialization: " + struct_def.name);
auto start = struct_def.fixed

View File

@ -490,7 +490,7 @@ void ErrorTest() {
TestError("union Z { X } struct X { Y:int; }", "only tables");
TestError("table X { Y:[int]; YLength:int; }", "clash");
TestError("table X { Y:string = 1; }", "scalar");
TestError("table X { Y:byte; } root_type X; { Y:1, Y:2 }", "already set");
TestError("table X { Y:byte; } root_type X; { Y:1, Y:2 }", "more than once");
}
// Additional parser testing not covered elsewhere.