[cpp] Json parsing: adding support for parsing nested lists and top level lists (#4338)
* Extended json parsing capability: add support for parsing nested lists and top level lists * Stylistic conformance with surrounding code + generalized comments * More code tidy-up for stylistic conformance with surrounding code * Blank lines * Reverted changes related to top-level list parsing * Styling: newline before else * Taking out ProcessTableFields which is no longer needed as the top level list change was reverted.
This commit is contained in:
parent
86b505e412
commit
b1740688bf
|
@ -857,17 +857,34 @@ void Parser::SerializeStruct(const StructDef &struct_def, const Value &val) {
|
|||
|
||||
CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
||||
uoffset_t *ovalue) {
|
||||
// We allow tables both as JSON object{ .. } with field names
|
||||
// or vector[..] with all fields in order
|
||||
const bool is_nested_list = Is('[');
|
||||
if (is_nested_list) {
|
||||
NEXT();
|
||||
} else {
|
||||
EXPECT('{');
|
||||
}
|
||||
size_t fieldn = 0;
|
||||
for (;;) {
|
||||
if ((!opts.strict_json || !fieldn) && Is('}')) { NEXT(); break; }
|
||||
std::string name = attribute_;
|
||||
if ((!opts.strict_json || !fieldn) && Is(is_nested_list ? ']' : '}')) { NEXT(); break; }
|
||||
FieldDef *field = nullptr;
|
||||
std::string name;
|
||||
if (is_nested_list) {
|
||||
if (fieldn > struct_def.fields.vec.size()) {
|
||||
return Error("too many unnamed fields in nested array");
|
||||
}
|
||||
field = struct_def.fields.vec[fieldn];
|
||||
name = field->name;
|
||||
} else {
|
||||
name = attribute_;
|
||||
if (Is(kTokenStringConstant)) {
|
||||
NEXT();
|
||||
} else {
|
||||
EXPECT(opts.strict_json ? kTokenStringConstant : kTokenIdentifier);
|
||||
}
|
||||
auto field = struct_def.fields.Lookup(name);
|
||||
field = struct_def.fields.Lookup(name);
|
||||
}
|
||||
if (!field) {
|
||||
if (!opts.skip_unexpected_fields_in_json) {
|
||||
return Error("unknown field: " + name);
|
||||
|
@ -876,7 +893,9 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
|||
ECHECK(SkipAnyJsonValue());
|
||||
}
|
||||
} else {
|
||||
if (!is_nested_list) {
|
||||
EXPECT(':');
|
||||
}
|
||||
if (Is(kTokenNull)) {
|
||||
NEXT(); // Ignore this field.
|
||||
} else {
|
||||
|
@ -897,9 +916,12 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
|||
fieldn++;
|
||||
}
|
||||
}
|
||||
if (Is('}')) { NEXT(); break; }
|
||||
if (Is(is_nested_list ? ']' : '}')) { NEXT(); break; }
|
||||
EXPECT(',');
|
||||
}
|
||||
if (is_nested_list && fieldn != struct_def.fields.vec.size()) {
|
||||
return Error("wrong number of unnamed fields in table vector");
|
||||
}
|
||||
|
||||
// Check if all required fields are parsed.
|
||||
for (auto field_it = struct_def.fields.vec.begin();
|
||||
|
|
|
@ -1106,6 +1106,13 @@ void ValueTest() {
|
|||
12335089644688340133ULL);
|
||||
}
|
||||
|
||||
void NestedListTest() {
|
||||
flatbuffers::Parser parser1;
|
||||
TEST_EQ(parser1.Parse("struct Test { a:short; b:byte; } table T { F:[Test]; }"
|
||||
"root_type T;"
|
||||
"{ F:[ [10,20], [30,40]] }"), true);
|
||||
}
|
||||
|
||||
void EnumStringsTest() {
|
||||
flatbuffers::Parser parser1;
|
||||
TEST_EQ(parser1.Parse("enum E:byte { A, B, C } table T { F:[E]; }"
|
||||
|
|
Loading…
Reference in New Issue