Support nan in the json tokenizer
flatbuffers renders nan as a literal nan in the json file.
Change-Id: Ife76397f8af12a03d382ca364870d8e7cb332fc1
diff --git a/aos/json_to_flatbuffer_test.cc b/aos/json_to_flatbuffer_test.cc
index 84ac0ed..6c76b02 100644
--- a/aos/json_to_flatbuffer_test.cc
+++ b/aos/json_to_flatbuffer_test.cc
@@ -66,6 +66,12 @@
EXPECT_TRUE(JsonAndBack("{ \"foo_string\": \"baz\" }"));
}
+// Tests that NaN is handled correctly
+TEST_F(JsonToFlatbufferTest, Nan) {
+ EXPECT_TRUE(JsonAndBack("{ \"foo_float\": nan }"));
+ EXPECT_TRUE(JsonAndBack("{ \"foo_float\": -nan }"));
+}
+
// Tests that we can handle decimal points.
TEST_F(JsonToFlatbufferTest, DecimalPoint) {
EXPECT_TRUE(JsonAndBack("{ \"foo_float\": 5.1 }"));
diff --git a/aos/json_tokenizer.cc b/aos/json_tokenizer.cc
index aa92762..e2e8f37 100644
--- a/aos/json_tokenizer.cc
+++ b/aos/json_tokenizer.cc
@@ -139,6 +139,13 @@
// Consume the leading - unconditionally.
Consume("-");
+ // See if we find nan. This isn't standards compliant, but is what
+ // flatbuffers prints out, so we need to parse it.
+ if (Consume("nan")) {
+ *s = ::std::string(original.substr(0, original.size() - data_.size()));
+ return true;
+ }
+
// Then, we either get a 0, or we get a nonzero. Only nonzero can be followed
// by a second number.
if (!Consume("0")) {
@@ -429,6 +436,14 @@
bool Tokenizer::FieldAsDouble(double *value) {
const char *pos = field_value().c_str();
errno = 0;
+ if (field_value() == "nan") {
+ *value = std::numeric_limits<double>::quiet_NaN();
+ return true;
+ } else if (field_value() == "-nan") {
+ *value = -std::numeric_limits<double>::quiet_NaN();
+ return true;
+ }
+
*value = strtod(field_value().c_str(), const_cast<char **>(&pos));
if (pos != field_value().c_str() + field_value().size() || errno != 0) {