Parcourir la source

Added `DeserializationError::f_str()` (issue #846)

Benoit Blanchon il y a 5 ans
Parent
commit
c4ec2ba88f

+ 1 - 0
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)

+ 1 - 1
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;
   }
 

+ 1 - 1
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;
   }
 

+ 1 - 1
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;
   }
 

+ 8 - 2
extras/tests/Helpers/progmem_emulation.hpp

@@ -5,6 +5,8 @@
 #include <stdint.h>  // uint8_t
 #include <string.h>  // 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<const char*>(s) - 42;
 }
 
-#define F(X) reinterpret_cast<const __FlashStringHelper*>(convertPtrToFlash(X))
-#define FC(X) reinterpret_cast<const char*>(convertPtrToFlash(X))
+#define PSTR(X) reinterpret_cast<const char*>(convertPtrToFlash(X))
+#define F(X) reinterpret_cast<const __FlashStringHelper*>(PSTR(X))
 
 inline uint8_t pgm_read_byte(const void* p) {
   return *reinterpret_cast<const uint8_t*>(convertFlashToPtr(p));
 }
+
+inline const void* pgm_read_ptr(const void* p) {
+  return *reinterpret_cast<const void* const*>(convertFlashToPtr(p));
+}

+ 17 - 17
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');

+ 17 - 0
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<size_t>(_code) <
+                       sizeof(messages) / sizeof(messages[0]));
+    return reinterpret_cast<const __FlashStringHelper*>(
+        pgm_read_ptr(messages + _code));
+  }
+#endif
+
  private:
   Code _code;
 };