Allow JSON numeric fields to be specified by a numeric data in a string.

Change-Id: I6a3fae1e71434a7384edc39b8602bd84a0432edb
Tested: on Linux.
Bug: 24140897
parent 709e7208
...@@ -470,7 +470,7 @@ private: ...@@ -470,7 +470,7 @@ private:
BaseType req, bool *destmatch); BaseType req, bool *destmatch);
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field); FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field);
FLATBUFFERS_CHECKED_ERROR ParseSingleValue(Value &e); FLATBUFFERS_CHECKED_ERROR ParseSingleValue(Value &e);
FLATBUFFERS_CHECKED_ERROR ParseIntegerFromString(Type &type, int64_t *result); FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(Type &type, int64_t *result);
StructDef *LookupCreateStruct(const std::string &name, StructDef *LookupCreateStruct(const std::string &name,
bool create_if_new = true, bool create_if_new = true,
bool definition = false); bool definition = false);
......
...@@ -209,6 +209,10 @@ CheckedError Parser::SkipByteOrderMark() { ...@@ -209,6 +209,10 @@ CheckedError Parser::SkipByteOrderMark() {
return NoError(); return NoError();
} }
bool IsIdentifierStart(char c) {
return isalpha(static_cast<unsigned char>(c)) || c == '_';
}
CheckedError Parser::Next() { CheckedError Parser::Next() {
doc_comment_.clear(); doc_comment_.clear();
bool seen_newline = false; bool seen_newline = false;
...@@ -288,7 +292,7 @@ CheckedError Parser::Next() { ...@@ -288,7 +292,7 @@ CheckedError Parser::Next() {
} }
// fall thru // fall thru
default: default:
if (isalpha(static_cast<unsigned char>(c)) || c == '_') { if (IsIdentifierStart(c)) {
// Collect all chars of an identifier: // Collect all chars of an identifier:
const char *start = cursor_ - 1; const char *start = cursor_ - 1;
while (isalnum(static_cast<unsigned char>(*cursor_)) || while (isalnum(static_cast<unsigned char>(*cursor_)) ||
...@@ -880,7 +884,7 @@ CheckedError Parser::TryTypedValue(int dtoken, bool check, Value &e, ...@@ -880,7 +884,7 @@ CheckedError Parser::TryTypedValue(int dtoken, bool check, Value &e,
return NoError(); return NoError();
} }
CheckedError Parser::ParseIntegerFromString(Type &type, int64_t *result) { CheckedError Parser::ParseEnumFromString(Type &type, int64_t *result) {
*result = 0; *result = 0;
// Parse one or more enum identifiers, separated by spaces. // Parse one or more enum identifiers, separated by spaces.
const char *next = attribute_.c_str(); const char *next = attribute_.c_str();
...@@ -950,10 +954,22 @@ CheckedError Parser::ParseSingleValue(Value &e) { ...@@ -950,10 +954,22 @@ CheckedError Parser::ParseSingleValue(Value &e) {
if (e.type.base_type != BASE_TYPE_STRING && if (e.type.base_type != BASE_TYPE_STRING &&
e.type.base_type != BASE_TYPE_NONE && e.type.base_type != BASE_TYPE_NONE &&
(token_ == kTokenIdentifier || token_ == kTokenStringConstant)) { (token_ == kTokenIdentifier || token_ == kTokenStringConstant)) {
if (IsIdentifierStart(attribute_[0])) { // Enum value.
int64_t val; int64_t val;
ECHECK(ParseIntegerFromString(e.type, &val)); ECHECK(ParseEnumFromString(e.type, &val));
e.constant = NumToString(val); e.constant = NumToString(val);
NEXT(); NEXT();
} else { // Numeric constant in string.
if (IsInteger(e.type.base_type)) {
// TODO(wvo): do we want to check for garbage after the number?
e.constant = NumToString(StringToInt(attribute_.c_str()));
} else if (IsFloat(e.type.base_type)) {
e.constant = NumToString(strtod(attribute_.c_str(), nullptr));
} else {
assert(0); // Shouldn't happen, we covered all types.
e.constant = "0";
}
}
} else { } else {
bool match = false; bool match = false;
ECHECK(TryTypedValue(kTokenIntegerConstant, ECHECK(TryTypedValue(kTokenIntegerConstant,
......
{ {
pos: { pos: {
x: 1, x: 1,
y: 2, y: "2",
z: 3, z: 3,
test1: 3, test1: 3,
test2: Green, test2: Green,
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
b: 20 b: 20
}, },
{ {
b: 40, b: "40",
a: 30 a: 30
} }
], ],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment