Просмотр исходного кода

Clear the JsonObject or JsonArray in deserializeJson()

Benoit Blanchon 8 лет назад
Родитель
Сommit
0d1623edef

+ 4 - 0
src/ArduinoJson/Data/List.hpp

@@ -89,6 +89,10 @@ class List {
   }
 
  protected:
+  void clear() {
+    _firstNode = 0;
+  }
+
   JsonBuffer *_buffer;
 
  private:

+ 5 - 0
src/ArduinoJson/DynamicJsonArray.hpp

@@ -16,6 +16,11 @@ class DynamicJsonArray : public JsonArray {
   DynamicJsonArray(size_t capacity)
       : JsonArray(&_buffer), _buffer(capacity - sizeof(JsonArray)) {}
 
+  void clear() {
+    Internals::List<JsonVariant>::clear();
+    _buffer.clear();
+  }
+
   size_t memoryUsage() const {
     return _buffer.size() + sizeof(JsonArray);
   }

+ 5 - 0
src/ArduinoJson/DynamicJsonObject.hpp

@@ -20,6 +20,11 @@ class DynamicJsonObject : public JsonObject {
     return _buffer;
   }
 
+  void clear() {
+    Internals::List<JsonPair>::clear();
+    _buffer.clear();
+  }
+
   size_t memoryUsage() const {
     return _buffer.size() + sizeof(JsonObject);
   }

+ 6 - 1
src/ArduinoJson/DynamicJsonVariant.hpp

@@ -14,6 +14,7 @@ class DynamicJsonVariant : public JsonVariant {
 
  public:
   DynamicJsonVariant() : JsonVariant() {}
+  DynamicJsonVariant(size_t capacity) : JsonVariant(), _buffer(capacity) {}
 
   template <typename T>
   DynamicJsonVariant& operator=(const T& value) {
@@ -33,8 +34,12 @@ class DynamicJsonVariant : public JsonVariant {
     return _buffer;
   }
 
+  void clear() {
+    _buffer.clear();
+  }
+
   size_t memoryUsage() const {
-    return _buffer.size() + sizeof(JsonVariant);
+    return _buffer.size();
   }
 };
 }  // namespace ArduinoJson

+ 5 - 0
src/ArduinoJson/StaticJsonArray.hpp

@@ -16,6 +16,11 @@ class StaticJsonArray : public JsonArray {
  public:
   StaticJsonArray() : JsonArray(&_buffer) {}
 
+  void clear() {
+    Internals::List<JsonVariant>::clear();
+    _buffer.clear();
+  }
+
   size_t memoryUsage() const {
     return _buffer.size() + sizeof(JsonArray);
   }

+ 5 - 0
src/ArduinoJson/StaticJsonObject.hpp

@@ -16,6 +16,11 @@ class StaticJsonObject : public JsonObject {
  public:
   StaticJsonObject() : JsonObject(&_buffer) {}
 
+  void clear() {
+    Internals::List<JsonPair>::clear();
+    _buffer.clear();
+  }
+
   size_t memoryUsage() const {
     return _buffer.size() + sizeof(JsonObject);
   }

+ 6 - 2
src/ArduinoJson/StaticJsonVariant.hpp

@@ -11,7 +11,7 @@ namespace ArduinoJson {
 
 template <size_t CAPACITY = sizeof(JsonVariant)>
 class StaticJsonVariant : public JsonVariant {
-  StaticJsonBuffer<CAPACITY - sizeof(JsonVariant)> _buffer;
+  StaticJsonBuffer<CAPACITY> _buffer;
 
  public:
   template <typename T>
@@ -32,8 +32,12 @@ class StaticJsonVariant : public JsonVariant {
     return _buffer;
   }
 
+  void clear() {
+    _buffer.clear();
+  }
+
   size_t memoryUsage() const {
-    return _buffer.size() + sizeof(JsonVariant);
+    return _buffer.size();
   }
 };
 }  // namespace ArduinoJson

+ 3 - 0
src/ArduinoJson/deserializeJson.hpp

@@ -15,6 +15,7 @@ typename Internals::EnableIf<!Internals::IsArray<TString>::value,
                              JsonError>::type
 deserializeJson(TDestination &destination, const TString &json,
                 uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
+  destination.clear();
   return Internals::makeParser(&destination.buffer(), json, nestingLimit)
       .parse(destination);
 }
@@ -26,6 +27,7 @@ template <typename TDestination, typename TString>
 JsonError deserializeJson(
     TDestination &destination, TString *json,
     uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
+  destination.clear();
   return Internals::makeParser(&destination.buffer(), json, nestingLimit)
       .parse(destination);
 }
@@ -37,6 +39,7 @@ template <typename TDestination, typename TString>
 JsonError deserializeJson(
     TDestination &destination, TString &json,
     uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
+  destination.clear();
   return Internals::makeParser(&destination.buffer(), json, nestingLimit)
       .parse(destination);
 }

+ 4 - 3
test/JsonParser/CMakeLists.txt

@@ -3,13 +3,14 @@
 # MIT License
 
 add_executable(JsonParserTests
-	JsonArray.cpp
+	DynamicJsonArray.cpp
+	DynamicJsonObject.cpp
+	DynamicJsonVariant.cpp
 	JsonError.cpp
-	JsonObject.cpp
-	JsonVariant.cpp
 	nestingLimit.cpp
 	StaticJsonArray.cpp
 	StaticJsonObject.cpp
+	StaticJsonVariant.cpp
 )
 
 target_link_libraries(JsonParserTests catch)

+ 9 - 1
test/JsonParser/JsonArray.cpp → test/JsonParser/DynamicJsonArray.cpp

@@ -5,7 +5,7 @@
 #include <ArduinoJson.h>
 #include <catch.hpp>
 
-TEST_CASE("deserializeJson(JsonArray&)") {
+TEST_CASE("deserializeJson(DynamicJsonArray&)") {
   DynamicJsonArray arr;
 
   SECTION("An empty array") {
@@ -350,4 +350,12 @@ TEST_CASE("deserializeJson(JsonArray&)") {
       REQUIRE(0 == object3["e"].as<int>());
     }
   }
+
+  SECTION("Should clear the JsonArray") {
+    deserializeJson(arr, "[1,2,3,4]");
+    deserializeJson(arr, "[]");
+
+    REQUIRE(arr.size() == 0);
+    REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0));
+  }
 }

+ 8 - 1
test/JsonParser/JsonObject.cpp → test/JsonParser/DynamicJsonObject.cpp

@@ -5,7 +5,7 @@
 #include <ArduinoJson.h>
 #include <catch.hpp>
 
-TEST_CASE("deserializeJson(JsonObject&)") {
+TEST_CASE("deserializeJson(DynamicJsonObject&)") {
   DynamicJsonObject obj;
 
   SECTION("An empty object") {
@@ -194,4 +194,11 @@ TEST_CASE("deserializeJson(JsonObject&)") {
       REQUIRE(err == JsonError::Ok);
     }
   }
+
+  SECTION("Should clear the JsonObject") {
+    deserializeJson(obj, "{\"hello\":\"world\"}");
+    deserializeJson(obj, "{}");
+    REQUIRE(obj.size() == 0);
+    REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(0));
+  }
 }

+ 9 - 1
test/JsonParser/JsonVariant.cpp → test/JsonParser/DynamicJsonVariant.cpp

@@ -7,7 +7,7 @@
 
 using namespace Catch::Matchers;
 
-TEST_CASE("deserializeJson(JsonVariant&)") {
+TEST_CASE("deserializeJson(DynamicJsonVariant&)") {
   DynamicJsonVariant variant;
 
   SECTION("EmptyObject") {
@@ -87,4 +87,12 @@ TEST_CASE("deserializeJson(JsonVariant&)") {
     REQUIRE(variant.is<char*>());
     REQUIRE_THAT(variant.as<char*>(), Equals("hello"));
   }
+
+  SECTION("Should clear the JsonVariant") {
+    deserializeJson(variant, "[1,2,3]");
+    deserializeJson(variant, "{}");
+
+    REQUIRE(variant.is<JsonObject>());
+    REQUIRE(variant.memoryUsage() == JSON_OBJECT_SIZE(0));
+  }
 }

+ 11 - 0
test/JsonParser/StaticJsonArray.cpp

@@ -76,4 +76,15 @@ TEST_CASE("deserializeJson(StaticJsonArray&)") {
     // note: we use a string of 8 bytes to be sure that the StaticJsonBuffer
     // will not insert bytes to enforce alignement
   }
+
+  SECTION("Should clear the JsonArray") {
+    StaticJsonArray<JSON_ARRAY_SIZE(4)> arr;
+    char input[] = "[1,2,3,4]";
+
+    deserializeJson(arr, input);
+    deserializeJson(arr, "[]");
+
+    REQUIRE(arr.size() == 0);
+    REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0));
+  }
 }

+ 11 - 0
test/JsonParser/StaticJsonObject.cpp

@@ -66,4 +66,15 @@ TEST_CASE("deserializeJson(StaticJsonObject&)") {
 
     REQUIRE(err != JsonError::Ok);
   }
+
+  SECTION("Should clear the JsonObject") {
+    StaticJsonObject<JSON_OBJECT_SIZE(1)> obj;
+    char input[] = "{\"hello\":\"world\"}";
+
+    deserializeJson(obj, input);
+    deserializeJson(obj, "{}");
+
+    REQUIRE(obj.size() == 0);
+    REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(0));
+  }
 }

+ 35 - 0
test/JsonParser/StaticJsonVariant.cpp

@@ -0,0 +1,35 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2018
+// MIT License
+
+#include <ArduinoJson.h>
+#include <catch.hpp>
+
+using namespace Catch::Matchers;
+
+TEST_CASE("deserializeJson(StaticJsonVariant&)") {
+  SECTION("Array") {
+    StaticJsonVariant<JSON_ARRAY_SIZE(2)> variant;
+
+    char input[] = "[1,2]";
+    JsonError err = deserializeJson(variant, input);
+
+    REQUIRE(err == JsonError::Ok);
+    REQUIRE(variant.is<JsonArray>());
+    REQUIRE(variant[0] == 1);
+    REQUIRE(variant[1] == 2);
+    REQUIRE(variant.memoryUsage() == JSON_ARRAY_SIZE(2));
+  }
+
+  SECTION("Should clear the JsonVariant") {
+    StaticJsonVariant<JSON_ARRAY_SIZE(2)> variant;
+    char input[] = "[1,2]";
+    deserializeJson(variant, input);
+
+    JsonError err = deserializeJson(variant, "{}");
+
+    REQUIRE(err == JsonError::Ok);
+    REQUIRE(variant.is<JsonObject>());
+    REQUIRE(variant.memoryUsage() == JSON_OBJECT_SIZE(0));
+  }
+}