Added ARDUINOJSON_ENABLE_NAN to enable NaN in JSON (closes #973)

This commit is contained in:
Benoit Blanchon
2019-05-18 12:15:36 +02:00
parent 90c1d549a8
commit 7427888e05
8 changed files with 72 additions and 4 deletions

View File

@ -7,6 +7,7 @@ HEAD
* Fixed `deserializeJson()` silently accepting a `Stream*` (issue #978)
* Fixed invalid result from `operator|` (issue #981)
* Made `deserializeJson()` more picky about trailing characters (issue #980)
* Added `ARDUINOJSON_ENABLE_NAN` to enable NaN in JSON (issue #973)
> ### BREAKING CHANGE
>

View File

@ -135,6 +135,11 @@
#define ARDUINOJSON_DECODE_UNICODE 0
#endif
// Support NaN in JSON
#ifndef ARDUINOJSON_ENABLE_NAN
#define ARDUINOJSON_ENABLE_NAN 1
#endif
// Control the exponentiation threshold for big numbers
// CAUTION: cannot be more that 1e9 !!!!
#ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD

View File

@ -52,7 +52,7 @@ class TextFormatter {
template <typename T>
void writeFloat(T value) {
if (isnan(value)) return writeRaw("NaN");
if (isnan(value)) return writeRaw(ARDUINOJSON_ENABLE_NAN ? "NaN" : "null");
if (value < 0.0) {
writeRaw('-');

View File

@ -15,9 +15,12 @@
#define ARDUINOJSON_CONCAT8(A, B, C, D, E, F, G, H) \
ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT4(A, B, C, D), \
ARDUINOJSON_CONCAT4(E, F, G, H))
#define ARDUINOJSON_CONCAT9(A, B, C, D, E, F, G, H, I) \
ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT4(A, B, C, D), \
ARDUINOJSON_CONCAT4(E, F, G, ARDUINOJSON_CONCAT2(H, I)))
#define ARDUINOJSON_NAMESPACE \
ARDUINOJSON_CONCAT8(ArduinoJson, ARDUINOJSON_VERSION_MAJOR, \
ARDUINOJSON_CONCAT9(ArduinoJson, ARDUINOJSON_VERSION_MAJOR, \
ARDUINOJSON_VERSION_MINOR, ARDUINOJSON_VERSION_REVISION, \
_, ARDUINOJSON_USE_LONG_LONG, ARDUINOJSON_USE_DOUBLE, \
ARDUINOJSON_DECODE_UNICODE)
ARDUINOJSON_DECODE_UNICODE, ARDUINOJSON_ENABLE_NAN)

View File

@ -71,8 +71,9 @@ inline ParsedNumber<TFloat, TUInt> parseNumber(const char *s) {
s++;
break;
}
#if ARDUINOJSON_ENABLE_NAN
if (*s == 'n' || *s == 'N') return traits::nan();
#endif
if (*s == 'i' || *s == 'I')
return is_negative ? -traits::inf() : traits::inf();
if (!isdigit(*s) && *s != '.') return return_type();

View File

@ -12,6 +12,8 @@ add_executable(MixedConfigurationTests
use_double_1.cpp
use_long_long_0.cpp
use_long_long_1.cpp
enable_nan_0.cpp
enable_nan_1.cpp
)
target_link_libraries(MixedConfigurationTests catch)

View File

@ -0,0 +1,25 @@
#define ARDUINOJSON_ENABLE_NAN 0
#include <ArduinoJson.h>
#include <catch.hpp>
#include <limits>
TEST_CASE("ARDUINOJSON_ENABLE_NAN == 0") {
DynamicJsonDocument doc(4096);
JsonObject root = doc.to<JsonObject>();
SECTION("serializeJson()") {
root["X"] = std::numeric_limits<double>::signaling_NaN();
std::string json;
serializeJson(doc, json);
REQUIRE(json == "{\"X\":null}");
}
SECTION("deserializeJson()") {
auto err = deserializeJson(doc, "{\"X\":NaN}");
REQUIRE(err == DeserializationError::InvalidInput);
}
}

View File

@ -0,0 +1,31 @@
#define ARDUINOJSON_ENABLE_NAN 1
#include <ArduinoJson.h>
#include <catch.hpp>
#include <limits>
namespace my {
using ARDUINOJSON_NAMESPACE::isnan;
} // namespace my
TEST_CASE("ARDUINOJSON_ENABLE_NAN == 1") {
DynamicJsonDocument doc(4096);
JsonObject root = doc.to<JsonObject>();
SECTION("serializeJson()") {
root["X"] = std::numeric_limits<double>::signaling_NaN();
std::string json;
serializeJson(doc, json);
REQUIRE(json == "{\"X\":NaN}");
}
SECTION("deserializeJson()") {
auto err = deserializeJson(doc, "{\"X\":NaN}");
float x = doc["X"];
REQUIRE(err == DeserializationError::Ok);
REQUIRE(my::isnan(x));
}
}