Clear the JsonObject or JsonArray in deserializeJson()

This commit is contained in:
Benoit Blanchon
2018-03-18 14:50:52 +01:00
parent cf149940ed
commit 0d1623edef
15 changed files with 126 additions and 9 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("deserializeJson(JsonArray&)") { TEST_CASE("deserializeJson(DynamicJsonArray&)") {
DynamicJsonArray arr; DynamicJsonArray arr;
SECTION("An empty array") { SECTION("An empty array") {
@ -350,4 +350,12 @@ TEST_CASE("deserializeJson(JsonArray&)") {
REQUIRE(0 == object3["e"].as<int>()); 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));
}
} }

View File

@ -5,7 +5,7 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("deserializeJson(JsonObject&)") { TEST_CASE("deserializeJson(DynamicJsonObject&)") {
DynamicJsonObject obj; DynamicJsonObject obj;
SECTION("An empty object") { SECTION("An empty object") {
@ -194,4 +194,11 @@ TEST_CASE("deserializeJson(JsonObject&)") {
REQUIRE(err == JsonError::Ok); 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));
}
} }

View File

@ -7,7 +7,7 @@
using namespace Catch::Matchers; using namespace Catch::Matchers;
TEST_CASE("deserializeJson(JsonVariant&)") { TEST_CASE("deserializeJson(DynamicJsonVariant&)") {
DynamicJsonVariant variant; DynamicJsonVariant variant;
SECTION("EmptyObject") { SECTION("EmptyObject") {
@ -87,4 +87,12 @@ TEST_CASE("deserializeJson(JsonVariant&)") {
REQUIRE(variant.is<char*>()); REQUIRE(variant.is<char*>());
REQUIRE_THAT(variant.as<char*>(), Equals("hello")); 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));
}
} }

View File

@ -76,4 +76,15 @@ TEST_CASE("deserializeJson(StaticJsonArray&)") {
// note: we use a string of 8 bytes to be sure that the StaticJsonBuffer // note: we use a string of 8 bytes to be sure that the StaticJsonBuffer
// will not insert bytes to enforce alignement // 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));
}
} }

View File

@ -66,4 +66,15 @@ TEST_CASE("deserializeJson(StaticJsonObject&)") {
REQUIRE(err != JsonError::Ok); 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));
}
} }

View File

@ -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));
}
}