mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-02 04:04:19 +00:00
Added support for parsing JSON null value.
These cause the field in question to be skipped. Bug: 16550393 Change-Id: Id05104e89818ee773b8a91fdcc86e18061b9a82f Tested: on Linux.
This commit is contained in:
@@ -166,6 +166,7 @@ root_type Monster;
|
||||
<li>It accepts field names with and without quotes, like many JSON parsers already do. It outputs them without quotes as well, though can be made to output them using the <code>strict_json</code> flag.</li>
|
||||
<li>If a field has an enum type, the parser will recognize symbolic enum values (with or without quotes) instead of numbers, e.g. <code>field: EnumVal</code>. If a field is of integral type, you can still use symbolic names, but values need to be prefixed with their type and need to be quoted, e.g. <code>field: "Enum.EnumVal"</code>. For enums representing flags, you may place multiple inside a string separated by spaces to OR them, e.g. <code>field: "EnumVal1 EnumVal2"</code> or <code>field: "Enum.EnumVal1 Enum.EnumVal2"</code>.</li>
|
||||
<li>Similarly, for unions, these need to specified with two fields much like you do when serializing from code. E.g. for a field <code>foo</code>, you must add a field <code>foo_type: FooOne</code> right before the <code>foo</code> field, where <code>FooOne</code> would be the table out of the union you want to use.</li>
|
||||
<li>A field that has the value <code>null</code> (e.g. <code>field: null</code>) is intended to have the default value for that field (thus has the same effect as if that field wasn't specified at all).</li>
|
||||
</ul>
|
||||
<p>When parsing JSON, it recognizes the following escape codes in strings:</p>
|
||||
<ul>
|
||||
|
||||
@@ -313,6 +313,9 @@ JSON:
|
||||
you do when serializing from code. E.g. for a field `foo`, you must
|
||||
add a field `foo_type: FooOne` right before the `foo` field, where
|
||||
`FooOne` would be the table out of the union you want to use.
|
||||
- A field that has the value `null` (e.g. `field: null`) is intended to
|
||||
have the default value for that field (thus has the same effect as if
|
||||
that field wasn't specified at all).
|
||||
|
||||
When parsing JSON, it recognizes the following escape codes in strings:
|
||||
|
||||
|
||||
@@ -151,7 +151,8 @@ std::string Namespace::GetFullyQualifiedName(const std::string &name,
|
||||
TD(FileIdentifier, 267, "file_identifier") \
|
||||
TD(FileExtension, 268, "file_extension") \
|
||||
TD(Include, 269, "include") \
|
||||
TD(Attribute, 270, "attribute")
|
||||
TD(Attribute, 270, "attribute") \
|
||||
TD(Null, 271, "null")
|
||||
#ifdef __GNUC__
|
||||
__extension__ // Stop GCC complaining about trailing comma with -Wpendantic.
|
||||
#endif
|
||||
@@ -343,6 +344,10 @@ CheckedError Parser::Next() {
|
||||
token_ = kTokenFileExtension;
|
||||
return NoError();
|
||||
}
|
||||
if (attribute_ == "null") {
|
||||
token_ = kTokenNull;
|
||||
return NoError();
|
||||
}
|
||||
// If not, it is a user-defined identifier:
|
||||
token_ = kTokenIdentifier;
|
||||
return NoError();
|
||||
@@ -688,19 +693,23 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
||||
}
|
||||
} else {
|
||||
EXPECT(':');
|
||||
Value val = field->value;
|
||||
ECHECK(ParseAnyValue(val, field, fieldn));
|
||||
size_t i = field_stack_.size();
|
||||
// Hardcoded insertion-sort with error-check.
|
||||
// If fields are specified in order, then this loop exits immediately.
|
||||
for (; i > field_stack_.size() - fieldn; i--) {
|
||||
auto existing_field = field_stack_[i - 1].second;
|
||||
if (existing_field == field)
|
||||
return Error("field set more than once: " + field->name);
|
||||
if (existing_field->value.offset < field->value.offset) break;
|
||||
if (Is(kTokenNull)) {
|
||||
NEXT(); // Ignore this field.
|
||||
} else {
|
||||
Value val = field->value;
|
||||
ECHECK(ParseAnyValue(val, field, fieldn));
|
||||
size_t i = field_stack_.size();
|
||||
// Hardcoded insertion-sort with error-check.
|
||||
// If fields are specified in order, then this loop exits immediately.
|
||||
for (; i > field_stack_.size() - fieldn; i--) {
|
||||
auto existing_field = field_stack_[i - 1].second;
|
||||
if (existing_field == field)
|
||||
return Error("field set more than once: " + field->name);
|
||||
if (existing_field->value.offset < field->value.offset) break;
|
||||
}
|
||||
field_stack_.insert(field_stack_.begin() + i, std::make_pair(val, field));
|
||||
fieldn++;
|
||||
}
|
||||
field_stack_.insert(field_stack_.begin() + i, std::make_pair(val, field));
|
||||
fieldn++;
|
||||
}
|
||||
if (Is('}')) { NEXT(); break; }
|
||||
EXPECT(',');
|
||||
@@ -1542,10 +1551,10 @@ CheckedError Parser::SkipJsonObject() {
|
||||
|
||||
CheckedError Parser::SkipJsonArray() {
|
||||
EXPECT('[');
|
||||
|
||||
|
||||
for (;;) {
|
||||
if (Is(']')) break;
|
||||
|
||||
|
||||
ECHECK(SkipAnyJsonValue());
|
||||
|
||||
if (Is(']')) break;
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
],
|
||||
test_type: Monster,
|
||||
test: {
|
||||
name: "Fred"
|
||||
name: "Fred",
|
||||
pos: null
|
||||
},
|
||||
test4: [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user