From c9d6bd76c91abb36591f93a60dfe785bb355a242 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 25 Feb 2019 13:21:10 +0100 Subject: [PATCH] Added `JsonDocument::remove()` and `JsonVariant::remove()` --- CHANGELOG.md | 2 + src/ArduinoJson/Array/ElementProxy.hpp | 19 ++++++++ src/ArduinoJson/Document/JsonDocument.hpp | 19 ++++++++ src/ArduinoJson/Object/MemberProxy.hpp | 19 ++++++++ src/ArduinoJson/Variant/VariantData.hpp | 9 ++++ src/ArduinoJson/Variant/VariantRef.hpp | 21 ++++++++- test/ElementProxy/CMakeLists.txt | 1 + test/ElementProxy/remove.cpp | 56 +++++++++++++++++++++++ test/JsonDocument/CMakeLists.txt | 1 + test/JsonDocument/remove.cpp | 52 +++++++++++++++++++++ test/JsonVariant/CMakeLists.txt | 1 + test/JsonVariant/remove.cpp | 42 +++++++++++++++++ test/MemberProxy/CMakeLists.txt | 3 +- test/MemberProxy/remove.cpp | 55 ++++++++++++++++++++++ 14 files changed, 298 insertions(+), 2 deletions(-) create mode 100644 test/ElementProxy/remove.cpp create mode 100644 test/JsonDocument/remove.cpp create mode 100644 test/JsonVariant/remove.cpp create mode 100644 test/MemberProxy/remove.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b64515c..6b9c9a41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,9 @@ HEAD * Fixed segfault after `variant.set(serialized((char*)0))` * Detect `IncompleteInput` in `false`, `true`, and `null` * Added `JsonDocument::size()` +* Added `JsonDocument::remove()` * Added `JsonVariant::clear()` +* Added `JsonVariant::remove()` v6.8.0-beta (2019-01-30) ----------- diff --git a/src/ArduinoJson/Array/ElementProxy.hpp b/src/ArduinoJson/Array/ElementProxy.hpp index c6a2a718..e1c784ad 100644 --- a/src/ArduinoJson/Array/ElementProxy.hpp +++ b/src/ArduinoJson/Array/ElementProxy.hpp @@ -124,6 +124,25 @@ class ElementProxy : public VariantOperators >, return getUpstreamElement().getElement(index); } + FORCE_INLINE void remove(size_t index) const { + getUpstreamElement().remove(index); + } + // remove(char*) const + // remove(const char*) const + // remove(const __FlashStringHelper*) const + template + FORCE_INLINE typename enable_if::value>::type remove( + TChar* key) const { + getUpstreamElement().remove(key); + } + // remove(const std::string&) const + // remove(const String&) const + template + FORCE_INLINE typename enable_if::value>::type remove( + const TString& key) const { + getUpstreamElement().remove(key); + } + private: FORCE_INLINE VariantRef getUpstreamElement() const { return _array.getElement(_index); diff --git a/src/ArduinoJson/Document/JsonDocument.hpp b/src/ArduinoJson/Document/JsonDocument.hpp index faf77fa5..c8ad783a 100644 --- a/src/ArduinoJson/Document/JsonDocument.hpp +++ b/src/ArduinoJson/Document/JsonDocument.hpp @@ -223,6 +223,25 @@ class JsonDocument : public Visitable { return addElement().set(value); } + FORCE_INLINE void remove(size_t index) { + _data.remove(index); + } + // remove(char*) + // remove(const char*) + // remove(const __FlashStringHelper*) + template + FORCE_INLINE typename enable_if::value>::type remove( + TChar* key) { + _data.remove(adaptString(key)); + } + // remove(const std::string&) + // remove(const String&) + template + FORCE_INLINE typename enable_if::value>::type remove( + const TString& key) { + _data.remove(adaptString(key)); + } + protected: JsonDocument(MemoryPool pool) : _pool(pool) { _data.setNull(); diff --git a/src/ArduinoJson/Object/MemberProxy.hpp b/src/ArduinoJson/Object/MemberProxy.hpp index 047868b3..a2dbec69 100644 --- a/src/ArduinoJson/Object/MemberProxy.hpp +++ b/src/ArduinoJson/Object/MemberProxy.hpp @@ -71,6 +71,25 @@ class MemberProxy : public VariantOperators >, return getUpstreamMember().size(); } + FORCE_INLINE void remove(size_t index) const { + getUpstreamMember().remove(index); + } + // remove(char*) const + // remove(const char*) const + // remove(const __FlashStringHelper*) const + template + FORCE_INLINE typename enable_if::value>::type remove( + TChar *key) const { + getUpstreamMember().remove(key); + } + // remove(const std::string&) const + // remove(const String&) const + template + FORCE_INLINE typename enable_if::value>::type remove( + const TString &key) const { + getUpstreamMember().remove(key); + } + template FORCE_INLINE typename VariantTo::type to() { return getOrAddUpstreamMember().template to(); diff --git a/src/ArduinoJson/Variant/VariantData.hpp b/src/ArduinoJson/Variant/VariantData.hpp index da3c6ac8..6e3799aa 100644 --- a/src/ArduinoJson/Variant/VariantData.hpp +++ b/src/ArduinoJson/Variant/VariantData.hpp @@ -169,6 +169,15 @@ class VariantData { return type() == VALUE_IS_NULL; } + void remove(size_t index) { + if (isArray()) _content.asCollection.remove(index); + } + + template + void remove(TAdaptedString key) { + if (isObject()) _content.asCollection.remove(key); + } + void setBoolean(bool value) { setType(VALUE_IS_BOOLEAN); _content.asInteger = static_cast(value); diff --git a/src/ArduinoJson/Variant/VariantRef.hpp b/src/ArduinoJson/Variant/VariantRef.hpp index 27b723fa..9a655263 100644 --- a/src/ArduinoJson/Variant/VariantRef.hpp +++ b/src/ArduinoJson/Variant/VariantRef.hpp @@ -310,9 +310,28 @@ class VariantRef : public VariantRefBase, template FORCE_INLINE VariantRef getOrAddMember(const TString &) const; + FORCE_INLINE void remove(size_t index) const { + if (_data) _data->remove(index); + } + // remove(char*) const + // remove(const char*) const + // remove(const __FlashStringHelper*) const + template + FORCE_INLINE typename enable_if::value>::type remove( + TChar *key) const { + if (_data) _data->remove(adaptString(key)); + } + // remove(const std::string&) const + // remove(const String&) const + template + FORCE_INLINE typename enable_if::value>::type remove( + const TString &key) const { + if (_data) _data->remove(adaptString(key)); + } + private: MemoryPool *_pool; -}; +}; // namespace ARDUINOJSON_NAMESPACE class VariantConstRef : public VariantRefBase, public VariantOperators, diff --git a/test/ElementProxy/CMakeLists.txt b/test/ElementProxy/CMakeLists.txt index 4b0f28c2..ab419f48 100644 --- a/test/ElementProxy/CMakeLists.txt +++ b/test/ElementProxy/CMakeLists.txt @@ -5,6 +5,7 @@ add_executable(ElementProxyTests add.cpp clear.cpp + remove.cpp set.cpp size.cpp ) diff --git a/test/ElementProxy/remove.cpp b/test/ElementProxy/remove.cpp new file mode 100644 index 00000000..8a213849 --- /dev/null +++ b/test/ElementProxy/remove.cpp @@ -0,0 +1,56 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2019 +// MIT License + +#include +#include + +using namespace ARDUINOJSON_NAMESPACE; + +TEST_CASE("ElementProxy::remove()") { + DynamicJsonDocument doc(4096); + doc.addElement(); + ElementProxy ep = doc[0]; + + SECTION("remove(int)") { + ep.add(1); + ep.add(2); + ep.add(3); + + ep.remove(1); + + REQUIRE(ep.as() == "[1,3]"); + } + + SECTION("remove(const char *)") { + ep["a"] = 1; + ep["b"] = 2; + + ep.remove("a"); + + REQUIRE(ep.as() == "{\"b\":2}"); + } + + SECTION("remove(std::string)") { + ep["a"] = 1; + ep["b"] = 2; + + ep.remove(std::string("b")); + + REQUIRE(ep.as() == "{\"a\":1}"); + } + +#ifdef HAS_VARIABLE_LENGTH_ARRAY + SECTION("remove(vla)") { + ep["a"] = 1; + ep["b"] = 2; + + int i = 4; + char vla[i]; + strcpy(vla, "b"); + ep.remove(vla); + + REQUIRE(ep.as() == "{\"a\":1}"); + } +#endif +} diff --git a/test/JsonDocument/CMakeLists.txt b/test/JsonDocument/CMakeLists.txt index c9438201..04d7e227 100644 --- a/test/JsonDocument/CMakeLists.txt +++ b/test/JsonDocument/CMakeLists.txt @@ -8,6 +8,7 @@ add_executable(JsonDocumentTests DynamicJsonDocument.cpp isNull.cpp nesting.cpp + remove.cpp size.cpp StaticJsonDocument.cpp subscript.cpp diff --git a/test/JsonDocument/remove.cpp b/test/JsonDocument/remove.cpp new file mode 100644 index 00000000..0c9b9e14 --- /dev/null +++ b/test/JsonDocument/remove.cpp @@ -0,0 +1,52 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2019 +// MIT License + +#include +#include + +TEST_CASE("JsonDocument::remove()") { + DynamicJsonDocument doc(4096); + + SECTION("remove(int)") { + doc.add(1); + doc.add(2); + doc.add(3); + + doc.remove(1); + + REQUIRE(doc.as() == "[1,3]"); + } + + SECTION("remove(const char *)") { + doc["a"] = 1; + doc["b"] = 2; + + doc.remove("a"); + + REQUIRE(doc.as() == "{\"b\":2}"); + } + + SECTION("remove(std::string)") { + doc["a"] = 1; + doc["b"] = 2; + + doc.remove(std::string("b")); + + REQUIRE(doc.as() == "{\"a\":1}"); + } + +#ifdef HAS_VARIABLE_LENGTH_ARRAY + SECTION("remove(vla)") { + doc["a"] = 1; + doc["b"] = 2; + + int i = 4; + char vla[i]; + strcpy(vla, "b"); + doc.remove(vla); + + REQUIRE(doc.as() == "{\"a\":1}"); + } +#endif +} diff --git a/test/JsonVariant/CMakeLists.txt b/test/JsonVariant/CMakeLists.txt index a95f0453..bee1b6ed 100644 --- a/test/JsonVariant/CMakeLists.txt +++ b/test/JsonVariant/CMakeLists.txt @@ -15,6 +15,7 @@ add_executable(JsonVariantTests misc.cpp nesting.cpp or.cpp + remove.cpp set.cpp subscript.cpp types.cpp diff --git a/test/JsonVariant/remove.cpp b/test/JsonVariant/remove.cpp new file mode 100644 index 00000000..c91a6e65 --- /dev/null +++ b/test/JsonVariant/remove.cpp @@ -0,0 +1,42 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2019 +// MIT License + +#include +#include +#include + +static const char* null = 0; + +TEST_CASE("JsonVariant::remove()") { + DynamicJsonDocument doc(4096); + JsonVariant var = doc.to(); + + SECTION("remove(int)") { + var.add(1); + var.add(2); + var.add(3); + + var.remove(1); + + REQUIRE(var.as() == "[1,3]"); + } + + SECTION("remove(const char *)") { + var["a"] = 1; + var["b"] = 2; + + var.remove("a"); + + REQUIRE(var.as() == "{\"b\":2}"); + } + + SECTION("remove(std::string)") { + var["a"] = 1; + var["b"] = 2; + + var.remove(std::string("b")); + + REQUIRE(var.as() == "{\"a\":1}"); + } +} diff --git a/test/MemberProxy/CMakeLists.txt b/test/MemberProxy/CMakeLists.txt index a3165c9a..60c70c8c 100644 --- a/test/MemberProxy/CMakeLists.txt +++ b/test/MemberProxy/CMakeLists.txt @@ -5,9 +5,10 @@ add_executable(MemberProxyTests add.cpp clear.cpp - subscript.cpp + remove.cpp set.cpp size.cpp + subscript.cpp ) target_link_libraries(MemberProxyTests catch) diff --git a/test/MemberProxy/remove.cpp b/test/MemberProxy/remove.cpp new file mode 100644 index 00000000..10ffcd06 --- /dev/null +++ b/test/MemberProxy/remove.cpp @@ -0,0 +1,55 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2019 +// MIT License + +#include +#include + +using namespace ARDUINOJSON_NAMESPACE; + +TEST_CASE("MemberProxy::remove()") { + DynamicJsonDocument doc(4096); + MemberProxy mp = doc["hello"]; + + SECTION("remove(int)") { + mp.add(1); + mp.add(2); + mp.add(3); + + mp.remove(1); + + REQUIRE(mp.as() == "[1,3]"); + } + + SECTION("remove(const char *)") { + mp["a"] = 1; + mp["b"] = 2; + + mp.remove("a"); + + REQUIRE(mp.as() == "{\"b\":2}"); + } + + SECTION("remove(std::string)") { + mp["a"] = 1; + mp["b"] = 2; + + mp.remove(std::string("b")); + + REQUIRE(mp.as() == "{\"a\":1}"); + } + +#ifdef HAS_VARIABLE_LENGTH_ARRAY + SECTION("remove(vla)") { + mp["a"] = 1; + mp["b"] = 2; + + int i = 4; + char vla[i]; + strcpy(vla, "b"); + mp.remove(vla); + + REQUIRE(mp.as() == "{\"a\":1}"); + } +#endif +}