diff --git a/src/ArduinoJson/Data/List.hpp b/src/ArduinoJson/Data/List.hpp index 14215966..185a6223 100644 --- a/src/ArduinoJson/Data/List.hpp +++ b/src/ArduinoJson/Data/List.hpp @@ -89,6 +89,10 @@ class List { } protected: + void clear() { + _firstNode = 0; + } + JsonBuffer *_buffer; private: diff --git a/src/ArduinoJson/DynamicJsonArray.hpp b/src/ArduinoJson/DynamicJsonArray.hpp index 0ec0d80e..6b82c6e2 100644 --- a/src/ArduinoJson/DynamicJsonArray.hpp +++ b/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::clear(); + _buffer.clear(); + } + size_t memoryUsage() const { return _buffer.size() + sizeof(JsonArray); } diff --git a/src/ArduinoJson/DynamicJsonObject.hpp b/src/ArduinoJson/DynamicJsonObject.hpp index 5e40ba40..c442377c 100644 --- a/src/ArduinoJson/DynamicJsonObject.hpp +++ b/src/ArduinoJson/DynamicJsonObject.hpp @@ -20,6 +20,11 @@ class DynamicJsonObject : public JsonObject { return _buffer; } + void clear() { + Internals::List::clear(); + _buffer.clear(); + } + size_t memoryUsage() const { return _buffer.size() + sizeof(JsonObject); } diff --git a/src/ArduinoJson/DynamicJsonVariant.hpp b/src/ArduinoJson/DynamicJsonVariant.hpp index ccc11042..3f67ec42 100644 --- a/src/ArduinoJson/DynamicJsonVariant.hpp +++ b/src/ArduinoJson/DynamicJsonVariant.hpp @@ -14,6 +14,7 @@ class DynamicJsonVariant : public JsonVariant { public: DynamicJsonVariant() : JsonVariant() {} + DynamicJsonVariant(size_t capacity) : JsonVariant(), _buffer(capacity) {} template 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 diff --git a/src/ArduinoJson/StaticJsonArray.hpp b/src/ArduinoJson/StaticJsonArray.hpp index 25bd8b60..21b3a220 100644 --- a/src/ArduinoJson/StaticJsonArray.hpp +++ b/src/ArduinoJson/StaticJsonArray.hpp @@ -16,6 +16,11 @@ class StaticJsonArray : public JsonArray { public: StaticJsonArray() : JsonArray(&_buffer) {} + void clear() { + Internals::List::clear(); + _buffer.clear(); + } + size_t memoryUsage() const { return _buffer.size() + sizeof(JsonArray); } diff --git a/src/ArduinoJson/StaticJsonObject.hpp b/src/ArduinoJson/StaticJsonObject.hpp index ae5538f3..0b5912a8 100644 --- a/src/ArduinoJson/StaticJsonObject.hpp +++ b/src/ArduinoJson/StaticJsonObject.hpp @@ -16,6 +16,11 @@ class StaticJsonObject : public JsonObject { public: StaticJsonObject() : JsonObject(&_buffer) {} + void clear() { + Internals::List::clear(); + _buffer.clear(); + } + size_t memoryUsage() const { return _buffer.size() + sizeof(JsonObject); } diff --git a/src/ArduinoJson/StaticJsonVariant.hpp b/src/ArduinoJson/StaticJsonVariant.hpp index 4d9a7486..250e1754 100644 --- a/src/ArduinoJson/StaticJsonVariant.hpp +++ b/src/ArduinoJson/StaticJsonVariant.hpp @@ -11,7 +11,7 @@ namespace ArduinoJson { template class StaticJsonVariant : public JsonVariant { - StaticJsonBuffer _buffer; + StaticJsonBuffer _buffer; public: template @@ -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 diff --git a/src/ArduinoJson/deserializeJson.hpp b/src/ArduinoJson/deserializeJson.hpp index 4593529f..b6e4659f 100644 --- a/src/ArduinoJson/deserializeJson.hpp +++ b/src/ArduinoJson/deserializeJson.hpp @@ -15,6 +15,7 @@ typename Internals::EnableIf::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 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 JsonError deserializeJson( TDestination &destination, TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { + destination.clear(); return Internals::makeParser(&destination.buffer(), json, nestingLimit) .parse(destination); } diff --git a/test/JsonParser/CMakeLists.txt b/test/JsonParser/CMakeLists.txt index 19381c40..35f8e57c 100644 --- a/test/JsonParser/CMakeLists.txt +++ b/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) diff --git a/test/JsonParser/JsonArray.cpp b/test/JsonParser/DynamicJsonArray.cpp similarity index 97% rename from test/JsonParser/JsonArray.cpp rename to test/JsonParser/DynamicJsonArray.cpp index 5a9a6b14..cfb498f7 100644 --- a/test/JsonParser/JsonArray.cpp +++ b/test/JsonParser/DynamicJsonArray.cpp @@ -5,7 +5,7 @@ #include #include -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()); } } + + SECTION("Should clear the JsonArray") { + deserializeJson(arr, "[1,2,3,4]"); + deserializeJson(arr, "[]"); + + REQUIRE(arr.size() == 0); + REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0)); + } } diff --git a/test/JsonParser/JsonObject.cpp b/test/JsonParser/DynamicJsonObject.cpp similarity index 95% rename from test/JsonParser/JsonObject.cpp rename to test/JsonParser/DynamicJsonObject.cpp index 87200bf7..72e6d2c5 100644 --- a/test/JsonParser/JsonObject.cpp +++ b/test/JsonParser/DynamicJsonObject.cpp @@ -5,7 +5,7 @@ #include #include -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)); + } } diff --git a/test/JsonParser/JsonVariant.cpp b/test/JsonParser/DynamicJsonVariant.cpp similarity index 88% rename from test/JsonParser/JsonVariant.cpp rename to test/JsonParser/DynamicJsonVariant.cpp index f1b5c38a..50449d9a 100644 --- a/test/JsonParser/JsonVariant.cpp +++ b/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()); REQUIRE_THAT(variant.as(), Equals("hello")); } + + SECTION("Should clear the JsonVariant") { + deserializeJson(variant, "[1,2,3]"); + deserializeJson(variant, "{}"); + + REQUIRE(variant.is()); + REQUIRE(variant.memoryUsage() == JSON_OBJECT_SIZE(0)); + } } diff --git a/test/JsonParser/StaticJsonArray.cpp b/test/JsonParser/StaticJsonArray.cpp index 6cc5208d..3a79749b 100644 --- a/test/JsonParser/StaticJsonArray.cpp +++ b/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 arr; + char input[] = "[1,2,3,4]"; + + deserializeJson(arr, input); + deserializeJson(arr, "[]"); + + REQUIRE(arr.size() == 0); + REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0)); + } } diff --git a/test/JsonParser/StaticJsonObject.cpp b/test/JsonParser/StaticJsonObject.cpp index ffed607f..525f5184 100644 --- a/test/JsonParser/StaticJsonObject.cpp +++ b/test/JsonParser/StaticJsonObject.cpp @@ -66,4 +66,15 @@ TEST_CASE("deserializeJson(StaticJsonObject&)") { REQUIRE(err != JsonError::Ok); } + + SECTION("Should clear the JsonObject") { + StaticJsonObject obj; + char input[] = "{\"hello\":\"world\"}"; + + deserializeJson(obj, input); + deserializeJson(obj, "{}"); + + REQUIRE(obj.size() == 0); + REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(0)); + } } diff --git a/test/JsonParser/StaticJsonVariant.cpp b/test/JsonParser/StaticJsonVariant.cpp new file mode 100644 index 00000000..a3fba6e1 --- /dev/null +++ b/test/JsonParser/StaticJsonVariant.cpp @@ -0,0 +1,35 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +using namespace Catch::Matchers; + +TEST_CASE("deserializeJson(StaticJsonVariant&)") { + SECTION("Array") { + StaticJsonVariant variant; + + char input[] = "[1,2]"; + JsonError err = deserializeJson(variant, input); + + REQUIRE(err == JsonError::Ok); + REQUIRE(variant.is()); + REQUIRE(variant[0] == 1); + REQUIRE(variant[1] == 2); + REQUIRE(variant.memoryUsage() == JSON_ARRAY_SIZE(2)); + } + + SECTION("Should clear the JsonVariant") { + StaticJsonVariant variant; + char input[] = "[1,2]"; + deserializeJson(variant, input); + + JsonError err = deserializeJson(variant, "{}"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(variant.is()); + REQUIRE(variant.memoryUsage() == JSON_OBJECT_SIZE(0)); + } +}