Added JsonDocument::remove() and JsonVariant::remove()

This commit is contained in:
Benoit Blanchon
2019-02-25 13:21:10 +01:00
parent bc2ce178ea
commit c9d6bd76c9
14 changed files with 298 additions and 2 deletions

View File

@ -17,7 +17,9 @@ HEAD
* Fixed segfault after `variant.set(serialized((char*)0))` * Fixed segfault after `variant.set(serialized((char*)0))`
* Detect `IncompleteInput` in `false`, `true`, and `null` * Detect `IncompleteInput` in `false`, `true`, and `null`
* Added `JsonDocument::size()` * Added `JsonDocument::size()`
* Added `JsonDocument::remove()`
* Added `JsonVariant::clear()` * Added `JsonVariant::clear()`
* Added `JsonVariant::remove()`
v6.8.0-beta (2019-01-30) v6.8.0-beta (2019-01-30)
----------- -----------

View File

@ -124,6 +124,25 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
return getUpstreamElement().getElement(index); 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 <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
TChar* key) const {
getUpstreamElement().remove(key);
}
// remove(const std::string&) const
// remove(const String&) const
template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
const TString& key) const {
getUpstreamElement().remove(key);
}
private: private:
FORCE_INLINE VariantRef getUpstreamElement() const { FORCE_INLINE VariantRef getUpstreamElement() const {
return _array.getElement(_index); return _array.getElement(_index);

View File

@ -223,6 +223,25 @@ class JsonDocument : public Visitable {
return addElement().set(value); return addElement().set(value);
} }
FORCE_INLINE void remove(size_t index) {
_data.remove(index);
}
// remove(char*)
// remove(const char*)
// remove(const __FlashStringHelper*)
template <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
TChar* key) {
_data.remove(adaptString(key));
}
// remove(const std::string&)
// remove(const String&)
template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
const TString& key) {
_data.remove(adaptString(key));
}
protected: protected:
JsonDocument(MemoryPool pool) : _pool(pool) { JsonDocument(MemoryPool pool) : _pool(pool) {
_data.setNull(); _data.setNull();

View File

@ -71,6 +71,25 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
return getUpstreamMember().size(); 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 <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar *>::value>::type remove(
TChar *key) const {
getUpstreamMember().remove(key);
}
// remove(const std::string&) const
// remove(const String&) const
template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
const TString &key) const {
getUpstreamMember().remove(key);
}
template <typename TValue> template <typename TValue>
FORCE_INLINE typename VariantTo<TValue>::type to() { FORCE_INLINE typename VariantTo<TValue>::type to() {
return getOrAddUpstreamMember().template to<TValue>(); return getOrAddUpstreamMember().template to<TValue>();

View File

@ -169,6 +169,15 @@ class VariantData {
return type() == VALUE_IS_NULL; return type() == VALUE_IS_NULL;
} }
void remove(size_t index) {
if (isArray()) _content.asCollection.remove(index);
}
template <typename TAdaptedString>
void remove(TAdaptedString key) {
if (isObject()) _content.asCollection.remove(key);
}
void setBoolean(bool value) { void setBoolean(bool value) {
setType(VALUE_IS_BOOLEAN); setType(VALUE_IS_BOOLEAN);
_content.asInteger = static_cast<UInt>(value); _content.asInteger = static_cast<UInt>(value);

View File

@ -310,9 +310,28 @@ class VariantRef : public VariantRefBase<VariantData>,
template <typename TString> template <typename TString>
FORCE_INLINE VariantRef getOrAddMember(const TString &) const; 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 <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar *>::value>::type remove(
TChar *key) const {
if (_data) _data->remove(adaptString(key));
}
// remove(const std::string&) const
// remove(const String&) const
template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
const TString &key) const {
if (_data) _data->remove(adaptString(key));
}
private: private:
MemoryPool *_pool; MemoryPool *_pool;
}; }; // namespace ARDUINOJSON_NAMESPACE
class VariantConstRef : public VariantRefBase<const VariantData>, class VariantConstRef : public VariantRefBase<const VariantData>,
public VariantOperators<VariantConstRef>, public VariantOperators<VariantConstRef>,

View File

@ -5,6 +5,7 @@
add_executable(ElementProxyTests add_executable(ElementProxyTests
add.cpp add.cpp
clear.cpp clear.cpp
remove.cpp
set.cpp set.cpp
size.cpp size.cpp
) )

View File

@ -0,0 +1,56 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace ARDUINOJSON_NAMESPACE;
TEST_CASE("ElementProxy::remove()") {
DynamicJsonDocument doc(4096);
doc.addElement();
ElementProxy<JsonDocument&> ep = doc[0];
SECTION("remove(int)") {
ep.add(1);
ep.add(2);
ep.add(3);
ep.remove(1);
REQUIRE(ep.as<std::string>() == "[1,3]");
}
SECTION("remove(const char *)") {
ep["a"] = 1;
ep["b"] = 2;
ep.remove("a");
REQUIRE(ep.as<std::string>() == "{\"b\":2}");
}
SECTION("remove(std::string)") {
ep["a"] = 1;
ep["b"] = 2;
ep.remove(std::string("b"));
REQUIRE(ep.as<std::string>() == "{\"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<std::string>() == "{\"a\":1}");
}
#endif
}

View File

@ -8,6 +8,7 @@ add_executable(JsonDocumentTests
DynamicJsonDocument.cpp DynamicJsonDocument.cpp
isNull.cpp isNull.cpp
nesting.cpp nesting.cpp
remove.cpp
size.cpp size.cpp
StaticJsonDocument.cpp StaticJsonDocument.cpp
subscript.cpp subscript.cpp

View File

@ -0,0 +1,52 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
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<std::string>() == "[1,3]");
}
SECTION("remove(const char *)") {
doc["a"] = 1;
doc["b"] = 2;
doc.remove("a");
REQUIRE(doc.as<std::string>() == "{\"b\":2}");
}
SECTION("remove(std::string)") {
doc["a"] = 1;
doc["b"] = 2;
doc.remove(std::string("b"));
REQUIRE(doc.as<std::string>() == "{\"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<std::string>() == "{\"a\":1}");
}
#endif
}

View File

@ -15,6 +15,7 @@ add_executable(JsonVariantTests
misc.cpp misc.cpp
nesting.cpp nesting.cpp
or.cpp or.cpp
remove.cpp
set.cpp set.cpp
subscript.cpp subscript.cpp
types.cpp types.cpp

View File

@ -0,0 +1,42 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
static const char* null = 0;
TEST_CASE("JsonVariant::remove()") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
SECTION("remove(int)") {
var.add(1);
var.add(2);
var.add(3);
var.remove(1);
REQUIRE(var.as<std::string>() == "[1,3]");
}
SECTION("remove(const char *)") {
var["a"] = 1;
var["b"] = 2;
var.remove("a");
REQUIRE(var.as<std::string>() == "{\"b\":2}");
}
SECTION("remove(std::string)") {
var["a"] = 1;
var["b"] = 2;
var.remove(std::string("b"));
REQUIRE(var.as<std::string>() == "{\"a\":1}");
}
}

View File

@ -5,9 +5,10 @@
add_executable(MemberProxyTests add_executable(MemberProxyTests
add.cpp add.cpp
clear.cpp clear.cpp
subscript.cpp remove.cpp
set.cpp set.cpp
size.cpp size.cpp
subscript.cpp
) )
target_link_libraries(MemberProxyTests catch) target_link_libraries(MemberProxyTests catch)

View File

@ -0,0 +1,55 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace ARDUINOJSON_NAMESPACE;
TEST_CASE("MemberProxy::remove()") {
DynamicJsonDocument doc(4096);
MemberProxy<JsonDocument&, const char*> mp = doc["hello"];
SECTION("remove(int)") {
mp.add(1);
mp.add(2);
mp.add(3);
mp.remove(1);
REQUIRE(mp.as<std::string>() == "[1,3]");
}
SECTION("remove(const char *)") {
mp["a"] = 1;
mp["b"] = 2;
mp.remove("a");
REQUIRE(mp.as<std::string>() == "{\"b\":2}");
}
SECTION("remove(std::string)") {
mp["a"] = 1;
mp["b"] = 2;
mp.remove(std::string("b"));
REQUIRE(mp.as<std::string>() == "{\"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<std::string>() == "{\"a\":1}");
}
#endif
}