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) {