mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-27 09:02:17 +00:00
[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:
committed by
Wouter van Oortmerssen
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,
|
CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
||||||
uoffset_t *ovalue) {
|
uoffset_t *ovalue) {
|
||||||
EXPECT('{');
|
// 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;
|
size_t fieldn = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((!opts.strict_json || !fieldn) && Is('}')) { NEXT(); break; }
|
if ((!opts.strict_json || !fieldn) && Is(is_nested_list ? ']' : '}')) { NEXT(); break; }
|
||||||
std::string name = attribute_;
|
FieldDef *field = nullptr;
|
||||||
if (Is(kTokenStringConstant)) {
|
std::string name;
|
||||||
NEXT();
|
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 {
|
} else {
|
||||||
EXPECT(opts.strict_json ? kTokenStringConstant : kTokenIdentifier);
|
name = attribute_;
|
||||||
|
if (Is(kTokenStringConstant)) {
|
||||||
|
NEXT();
|
||||||
|
} else {
|
||||||
|
EXPECT(opts.strict_json ? kTokenStringConstant : kTokenIdentifier);
|
||||||
|
}
|
||||||
|
field = struct_def.fields.Lookup(name);
|
||||||
}
|
}
|
||||||
auto field = struct_def.fields.Lookup(name);
|
|
||||||
if (!field) {
|
if (!field) {
|
||||||
if (!opts.skip_unexpected_fields_in_json) {
|
if (!opts.skip_unexpected_fields_in_json) {
|
||||||
return Error("unknown field: " + name);
|
return Error("unknown field: " + name);
|
||||||
@@ -876,7 +893,9 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
|||||||
ECHECK(SkipAnyJsonValue());
|
ECHECK(SkipAnyJsonValue());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
EXPECT(':');
|
if (!is_nested_list) {
|
||||||
|
EXPECT(':');
|
||||||
|
}
|
||||||
if (Is(kTokenNull)) {
|
if (Is(kTokenNull)) {
|
||||||
NEXT(); // Ignore this field.
|
NEXT(); // Ignore this field.
|
||||||
} else {
|
} else {
|
||||||
@@ -897,9 +916,12 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
|||||||
fieldn++;
|
fieldn++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Is('}')) { NEXT(); break; }
|
if (Is(is_nested_list ? ']' : '}')) { NEXT(); break; }
|
||||||
EXPECT(',');
|
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.
|
// Check if all required fields are parsed.
|
||||||
for (auto field_it = struct_def.fields.vec.begin();
|
for (auto field_it = struct_def.fields.vec.begin();
|
||||||
|
|||||||
@@ -1106,6 +1106,13 @@ void ValueTest() {
|
|||||||
12335089644688340133ULL);
|
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() {
|
void EnumStringsTest() {
|
||||||
flatbuffers::Parser parser1;
|
flatbuffers::Parser parser1;
|
||||||
TEST_EQ(parser1.Parse("enum E:byte { A, B, C } table T { F:[E]; }"
|
TEST_EQ(parser1.Parse("enum E:byte { A, B, C } table T { F:[E]; }"
|
||||||
|
|||||||
Reference in New Issue
Block a user