FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent();
FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type);
FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue();
+ FLATBUFFERS_CHECKED_ERROR ParseFlexBufferNumericConstant(
+ flexbuffers::Builder *builder);
FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder);
FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
const char *source_filename);
return NoError();
}
+CheckedError Parser::ParseFlexBufferNumericConstant(
+ flexbuffers::Builder *builder) {
+ double d;
+ if (!StringToNumber(attribute_.c_str(), &d))
+ return Error("unexpected floating-point constant: " + attribute_);
+ builder->Double(d);
+ return NoError();
+}
+
CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
ParseDepthGuard depth_guard(this);
ECHECK(depth_guard.Check());
EXPECT(kTokenFloatConstant);
break;
}
+ case '-':
+ case '+': {
+ // `[-+]?(nan|inf|infinity)`, see ParseSingleValue().
+ const auto sign = static_cast<char>(token_);
+ NEXT();
+ if (token_ != kTokenIdentifier)
+ return Error("floating-point constant expected");
+ attribute_.insert(0, 1, sign);
+ ECHECK(ParseFlexBufferNumericConstant(builder));
+ NEXT();
+ break;
+ }
default:
if (IsIdent("true")) {
builder->Bool(true);
} else if (IsIdent("null")) {
builder->Null();
NEXT();
+ } else if (IsIdent("inf") || IsIdent("infinity") || IsIdent("nan")) {
+ ECHECK(ParseFlexBufferNumericConstant(builder));
+ NEXT();
} else
return TokenError();
}
TEST_EQ(slb.GetSize(), 664);
}
+void FlexBuffersFloatingPointTest() {
+#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
+ flexbuffers::Builder slb(512,
+ flexbuffers::BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
+ // Parse floating-point values from JSON:
+ flatbuffers::Parser parser;
+ slb.Clear();
+ auto jsontest =
+ "{ a: [1.0, nan, inf, infinity, -inf, +inf, -infinity, 8.0] }";
+ TEST_EQ(parser.ParseFlexBuffer(jsontest, nullptr, &slb), true);
+ auto jroot = flexbuffers::GetRoot(slb.GetBuffer());
+ auto jmap = jroot.AsMap();
+ auto jvec = jmap["a"].AsVector();
+ TEST_EQ(8, jvec.size());
+ TEST_EQ(1.0, jvec[0].AsDouble());
+ TEST_ASSERT(is_quiet_nan(jvec[1].AsDouble()));
+ TEST_EQ(infinity_d, jvec[2].AsDouble());
+ TEST_EQ(infinity_d, jvec[3].AsDouble());
+ TEST_EQ(-infinity_d, jvec[4].AsDouble());
+ TEST_EQ(+infinity_d, jvec[5].AsDouble());
+ TEST_EQ(-infinity_d, jvec[6].AsDouble());
+ TEST_EQ(8.0, jvec[7].AsDouble());
+#endif
+}
+
void FlexBuffersDeprecatedTest() {
// FlexBuffers as originally designed had a flaw involving the
// FBT_VECTOR_STRING datatype, and this test documents/tests the fix for it.
FieldIdentifierTest();
StringVectorDefaultsTest();
ParseIncorrectMonsterJsonTest();
+ FlexBuffersFloatingPointTest();
return 0;
}