diff --git a/CHANGELOG.md b/CHANGELOG.md index 153621a7..16657bd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ HEAD * Added a build failure when nullptr is defined as a macro (issue #1355) * Added `JsonDocument::overflowed()` which tells if the memory pool was too small (issue #1358) * Added `DeserializationError::EmptyInput` which tells if the input was empty +* Added `DeserializationError::f_str()` which returns a `const __FlashStringHelper*` (issue #846) * Fixed `JsonVariant::set((char*)0)` which returned false instead of true (issue #1368) v6.16.1 (2020-08-04) diff --git a/examples/JsonHttpClient/JsonHttpClient.ino b/examples/JsonHttpClient/JsonHttpClient.ino index 5c894c44..b4ade88c 100644 --- a/examples/JsonHttpClient/JsonHttpClient.ino +++ b/examples/JsonHttpClient/JsonHttpClient.ino @@ -82,7 +82,7 @@ void setup() { DeserializationError error = deserializeJson(doc, client); if (error) { Serial.print(F("deserializeJson() failed: ")); - Serial.println(error.c_str()); + Serial.println(error.f_str()); return; } diff --git a/examples/JsonParserExample/JsonParserExample.ino b/examples/JsonParserExample/JsonParserExample.ino index 62ff8782..4e9f61e6 100644 --- a/examples/JsonParserExample/JsonParserExample.ino +++ b/examples/JsonParserExample/JsonParserExample.ino @@ -42,7 +42,7 @@ void setup() { // Test if parsing succeeds. if (error) { Serial.print(F("deserializeJson() failed: ")); - Serial.println(error.c_str()); + Serial.println(error.f_str()); return; } diff --git a/examples/MsgPackParser/MsgPackParser.ino b/examples/MsgPackParser/MsgPackParser.ino index 2596cc5e..dd262ed4 100644 --- a/examples/MsgPackParser/MsgPackParser.ino +++ b/examples/MsgPackParser/MsgPackParser.ino @@ -50,7 +50,7 @@ void setup() { // Test if parsing succeeded. if (error) { Serial.print("deserializeMsgPack() failed: "); - Serial.println(error.c_str()); + Serial.println(error.f_str()); return; } diff --git a/extras/tests/Helpers/progmem_emulation.hpp b/extras/tests/Helpers/progmem_emulation.hpp index 4a7f1799..ef309d10 100644 --- a/extras/tests/Helpers/progmem_emulation.hpp +++ b/extras/tests/Helpers/progmem_emulation.hpp @@ -5,6 +5,8 @@ #include // uint8_t #include // strcmp, strlen... +#define PROGMEM + class __FlashStringHelper; inline const void* convertPtrToFlash(const void* s) { @@ -15,9 +17,13 @@ inline const void* convertFlashToPtr(const void* s) { return reinterpret_cast(s) - 42; } -#define F(X) reinterpret_cast(convertPtrToFlash(X)) -#define FC(X) reinterpret_cast(convertPtrToFlash(X)) +#define PSTR(X) reinterpret_cast(convertPtrToFlash(X)) +#define F(X) reinterpret_cast(PSTR(X)) inline uint8_t pgm_read_byte(const void* p) { return *reinterpret_cast(convertFlashToPtr(p)); } + +inline const void* pgm_read_ptr(const void* p) { + return *reinterpret_cast(convertFlashToPtr(p)); +} diff --git a/extras/tests/MixedConfiguration/enable_progmem_1.cpp b/extras/tests/MixedConfiguration/enable_progmem_1.cpp index 5f30b58b..b862b419 100644 --- a/extras/tests/MixedConfiguration/enable_progmem_1.cpp +++ b/extras/tests/MixedConfiguration/enable_progmem_1.cpp @@ -53,33 +53,33 @@ TEST_CASE("Flash strings") { } TEST_CASE("strlen_P") { - CHECK(strlen_P(FC("")) == 0); - CHECK(strlen_P(FC("a")) == 1); - CHECK(strlen_P(FC("ac")) == 2); + CHECK(strlen_P(PSTR("")) == 0); + CHECK(strlen_P(PSTR("a")) == 1); + CHECK(strlen_P(PSTR("ac")) == 2); } TEST_CASE("strncmp_P") { - CHECK(strncmp_P("a", FC("b"), 0) == 0); - CHECK(strncmp_P("a", FC("b"), 1) == -1); - CHECK(strncmp_P("b", FC("a"), 1) == 1); - CHECK(strncmp_P("a", FC("a"), 0) == 0); - CHECK(strncmp_P("a", FC("b"), 2) == -1); - CHECK(strncmp_P("b", FC("a"), 2) == 1); - CHECK(strncmp_P("a", FC("a"), 2) == 0); + CHECK(strncmp_P("a", PSTR("b"), 0) == 0); + CHECK(strncmp_P("a", PSTR("b"), 1) == -1); + CHECK(strncmp_P("b", PSTR("a"), 1) == 1); + CHECK(strncmp_P("a", PSTR("a"), 0) == 0); + CHECK(strncmp_P("a", PSTR("b"), 2) == -1); + CHECK(strncmp_P("b", PSTR("a"), 2) == 1); + CHECK(strncmp_P("a", PSTR("a"), 2) == 0); } TEST_CASE("strcmp_P") { - CHECK(strcmp_P("a", FC("b")) == -1); - CHECK(strcmp_P("b", FC("a")) == 1); - CHECK(strcmp_P("a", FC("a")) == 0); - CHECK(strcmp_P("aa", FC("ab")) == -1); - CHECK(strcmp_P("ab", FC("aa")) == 1); - CHECK(strcmp_P("aa", FC("aa")) == 0); + CHECK(strcmp_P("a", PSTR("b")) == -1); + CHECK(strcmp_P("b", PSTR("a")) == 1); + CHECK(strcmp_P("a", PSTR("a")) == 0); + CHECK(strcmp_P("aa", PSTR("ab")) == -1); + CHECK(strcmp_P("ab", PSTR("aa")) == 1); + CHECK(strcmp_P("aa", PSTR("aa")) == 0); } TEST_CASE("memcpy_P") { char dst[4]; - CHECK(memcpy_P(dst, FC("ABC"), 4) == dst); + CHECK(memcpy_P(dst, PSTR("ABC"), 4) == dst); CHECK(dst[0] == 'A'); CHECK(dst[1] == 'B'); CHECK(dst[2] == 'C'); diff --git a/src/ArduinoJson/Deserialization/DeserializationError.hpp b/src/ArduinoJson/Deserialization/DeserializationError.hpp index 33cce207..f3f8a229 100644 --- a/src/ArduinoJson/Deserialization/DeserializationError.hpp +++ b/src/ArduinoJson/Deserialization/DeserializationError.hpp @@ -86,6 +86,23 @@ class DeserializationError { return messages[_code]; } +#if ARDUINOJSON_ENABLE_PROGMEM + const __FlashStringHelper* f_str() const { + static const char s0[] PROGMEM = "Ok"; + static const char s1[] PROGMEM = "EmptyInput"; + static const char s2[] PROGMEM = "IncompleteInput"; + static const char s3[] PROGMEM = "InvalidInput"; + static const char s4[] PROGMEM = "NoMemory"; + static const char s5[] PROGMEM = "NotSupported"; + static const char s6[] PROGMEM = "TooDeep"; + static const char* const messages[] PROGMEM = {s0, s1, s2, s3, s4, s5, s6}; + ARDUINOJSON_ASSERT(static_cast(_code) < + sizeof(messages) / sizeof(messages[0])); + return reinterpret_cast( + pgm_read_ptr(messages + _code)); + } +#endif + private: Code _code; };