mirror of
https://github.com/google/flatbuffers.git
synced 2026-07-04 14:21:12 +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>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>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>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>
|
</ul>
|
||||||
<p>When parsing JSON, it recognizes the following escape codes in strings:</p>
|
<p>When parsing JSON, it recognizes the following escape codes in strings:</p>
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
@@ -313,6 +313,9 @@ JSON:
|
|||||||
you do when serializing from code. E.g. for a field `foo`, you must
|
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
|
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.
|
`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:
|
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(FileIdentifier, 267, "file_identifier") \
|
||||||
TD(FileExtension, 268, "file_extension") \
|
TD(FileExtension, 268, "file_extension") \
|
||||||
TD(Include, 269, "include") \
|
TD(Include, 269, "include") \
|
||||||
TD(Attribute, 270, "attribute")
|
TD(Attribute, 270, "attribute") \
|
||||||
|
TD(Null, 271, "null")
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__extension__ // Stop GCC complaining about trailing comma with -Wpendantic.
|
__extension__ // Stop GCC complaining about trailing comma with -Wpendantic.
|
||||||
#endif
|
#endif
|
||||||
@@ -343,6 +344,10 @@ CheckedError Parser::Next() {
|
|||||||
token_ = kTokenFileExtension;
|
token_ = kTokenFileExtension;
|
||||||
return NoError();
|
return NoError();
|
||||||
}
|
}
|
||||||
|
if (attribute_ == "null") {
|
||||||
|
token_ = kTokenNull;
|
||||||
|
return NoError();
|
||||||
|
}
|
||||||
// If not, it is a user-defined identifier:
|
// If not, it is a user-defined identifier:
|
||||||
token_ = kTokenIdentifier;
|
token_ = kTokenIdentifier;
|
||||||
return NoError();
|
return NoError();
|
||||||
@@ -688,19 +693,23 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
EXPECT(':');
|
EXPECT(':');
|
||||||
Value val = field->value;
|
if (Is(kTokenNull)) {
|
||||||
ECHECK(ParseAnyValue(val, field, fieldn));
|
NEXT(); // Ignore this field.
|
||||||
size_t i = field_stack_.size();
|
} else {
|
||||||
// Hardcoded insertion-sort with error-check.
|
Value val = field->value;
|
||||||
// If fields are specified in order, then this loop exits immediately.
|
ECHECK(ParseAnyValue(val, field, fieldn));
|
||||||
for (; i > field_stack_.size() - fieldn; i--) {
|
size_t i = field_stack_.size();
|
||||||
auto existing_field = field_stack_[i - 1].second;
|
// Hardcoded insertion-sort with error-check.
|
||||||
if (existing_field == field)
|
// If fields are specified in order, then this loop exits immediately.
|
||||||
return Error("field set more than once: " + field->name);
|
for (; i > field_stack_.size() - fieldn; i--) {
|
||||||
if (existing_field->value.offset < field->value.offset) break;
|
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; }
|
if (Is('}')) { NEXT(); break; }
|
||||||
EXPECT(',');
|
EXPECT(',');
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
],
|
],
|
||||||
test_type: Monster,
|
test_type: Monster,
|
||||||
test: {
|
test: {
|
||||||
name: "Fred"
|
name: "Fred",
|
||||||
|
pos: null
|
||||||
},
|
},
|
||||||
test4: [
|
test4: [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user