Skip to content

Commit

Permalink
Added JsonVariant::containsKey()
Browse files Browse the repository at this point in the history
  • Loading branch information
bblanchon committed Mar 22, 2019
1 parent c8e49a7 commit 6ec5ba5
Show file tree
Hide file tree
Showing 13 changed files with 142 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ HEAD
- `is<T>()` returns `false` if the integer `T` overflows
* Added `BasicJsonDocument` to support custom allocator (issue #876)
* Added `JsonDocument::containsKey()` (issue #938)
* Added `JsonVariant::containsKey()`

v6.9.1 (2019-03-01)
------
Expand Down
4 changes: 4 additions & 0 deletions src/ArduinoJson/Array/ArrayRef.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ class ArrayConstRef : public ArrayRefBase<const CollectionData>,
}

FORCE_INLINE VariantConstRef operator[](size_t index) const {
return getElement(index);
}

FORCE_INLINE VariantConstRef getElement(size_t index) const {
return VariantConstRef(_data ? _data->get(index) : 0);
}
};
Expand Down
41 changes: 31 additions & 10 deletions src/ArduinoJson/Document/JsonDocument.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,14 @@ class JsonDocument : public Visitable {
// containsKey(const __FlashStringHelper*) const
template <typename TChar>
bool containsKey(TChar* key) const {
return as<ObjectRef>().containsKey(key);
return !getMember(key).isUndefined();
}

// containsKey(const std::string&) const
// containsKey(const String&) const
template <typename TString>
bool containsKey(const TString& key) const {
return as<ObjectRef>().containsKey(key);
return !getMember(key).isUndefined();
}

// operator[](const std::string&)
Expand Down Expand Up @@ -165,7 +165,7 @@ class JsonDocument : public Visitable {
FORCE_INLINE
typename enable_if<IsString<TString>::value, VariantConstRef>::type
operator[](const TString& key) const {
return getVariant()[key];
return getMember(key);
}

// operator[](char*) const
Expand All @@ -175,31 +175,52 @@ class JsonDocument : public Visitable {
FORCE_INLINE
typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
operator[](TChar* key) const {
return getVariant()[key];
return getMember(key);
}

FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) {
return ElementProxy<JsonDocument&>(*this, index);
}

FORCE_INLINE VariantConstRef operator[](size_t index) const {
return VariantConstRef(_data.getElement(index));
return getElement(index);
}

FORCE_INLINE VariantRef getElement(size_t index) {
return VariantRef(&_pool, _data.getElement(index));
}

// getMember(char*) const
// getMember(const char*) const
// getMember(const __FlashStringHelper*) const
FORCE_INLINE VariantConstRef getElement(size_t index) const {
return VariantConstRef(_data.getElement(index));
}

// JsonVariantConst getMember(char*) const
// JsonVariantConst getMember(const char*) const
// JsonVariantConst getMember(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE VariantConstRef getMember(TChar* key) const {
return VariantConstRef(_data.getMember(adaptString(key)));
}

// JsonVariantConst getMember(const std::string&) const
// JsonVariantConst getMember(const String&) const
template <typename TString>
FORCE_INLINE
typename enable_if<IsString<TString>::value, VariantConstRef>::type
getMember(const TString& key) const {
return VariantConstRef(_data.getMember(adaptString(key)));
}

// JsonVariant getMember(char*)
// JsonVariant getMember(const char*)
// JsonVariant getMember(const __FlashStringHelper*)
template <typename TChar>
FORCE_INLINE VariantRef getMember(TChar* key) {
return VariantRef(&_pool, _data.getMember(adaptString(key)));
}

// getMember(const std::string&) const
// getMember(const String&) const
// JsonVariant getMember(const std::string&)
// JsonVariant getMember(const String&)
template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type
getMember(const TString& key) {
Expand Down
6 changes: 3 additions & 3 deletions src/ArduinoJson/Object/MemberProxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
return *this;
}

// operator=(char*) const
// operator=(const char*) const
// operator=(const __FlashStringHelper*) const
// operator=(char*)
// operator=(const char*)
// operator=(const __FlashStringHelper*)
template <typename TChar>
FORCE_INLINE this_type &operator=(TChar *src) {
getOrAddUpstreamMember().set(src);
Expand Down
5 changes: 0 additions & 5 deletions src/ArduinoJson/Object/ObjectFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ void objectAccept(const CollectionData *obj, Visitor &visitor) {
visitor.visitNull();
}

template <typename TAdaptedString>
inline bool objectContainsKey(const CollectionData *obj, TAdaptedString key) {
return obj && obj->containsKey(key);
}

inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) {
if (lhs == rhs) return true;
if (!lhs || !rhs) return false;
Expand Down
14 changes: 14 additions & 0 deletions src/ArduinoJson/Object/ObjectImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,18 @@ inline ObjectRef ObjectShortcuts<TObject>::createNestedObject(
TChar* key) const {
return impl()->getOrAddMember(key).template to<ObjectRef>();
}

template <typename TObject>
template <typename TString>
inline typename enable_if<IsString<TString>::value, bool>::type
ObjectShortcuts<TObject>::containsKey(const TString& key) const {
return !impl()->getMember(key).isUndefined();
}

template <typename TObject>
template <typename TChar>
inline typename enable_if<IsString<TChar*>::value, bool>::type
ObjectShortcuts<TObject>::containsKey(TChar* key) const {
return !impl()->getMember(key).isUndefined();
}
} // namespace ARDUINOJSON_NAMESPACE
30 changes: 15 additions & 15 deletions src/ArduinoJson/Object/ObjectRef.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,6 @@ class ObjectRefBase {
objectAccept(_data, visitor);
}

// containsKey(const std::string&) const
// containsKey(const String&) const
template <typename TString>
FORCE_INLINE bool containsKey(const TString& key) const {
return objectContainsKey(_data, adaptString(key));
}

// containsKey(char*) const
// containsKey(const char*) const
// containsKey(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE bool containsKey(TChar* key) const {
return objectContainsKey(_data, adaptString(key));
}

FORCE_INLINE bool isNull() const {
return _data == 0;
}
Expand Down Expand Up @@ -83,6 +68,21 @@ class ObjectConstRef : public ObjectRefBase<const CollectionData>,
return iterator();
}

// containsKey(const std::string&) const
// containsKey(const String&) const
template <typename TString>
FORCE_INLINE bool containsKey(const TString& key) const {
return !getMember(key).isUndefined();
}

// containsKey(char*) const
// containsKey(const char*) const
// containsKey(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE bool containsKey(TChar* key) const {
return !getMember(key).isUndefined();
}

// getMember(const std::string&) const
// getMember(const String&) const
template <typename TString>
Expand Down
13 changes: 13 additions & 0 deletions src/ArduinoJson/Object/ObjectShortcuts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ class MemberProxy;
template <typename TObject>
class ObjectShortcuts {
public:
// containsKey(const std::string&) const
// containsKey(const String&) const
template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value, bool>::type
containsKey(const TString &key) const;

// containsKey(char*) const
// containsKey(const char*) const
// containsKey(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar *>::value, bool>::type
containsKey(TChar *key) const;

// operator[](const std::string&) const
// operator[](const String&) const
template <typename TString>
Expand Down
4 changes: 4 additions & 0 deletions src/ArduinoJson/Variant/VariantRef.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ class VariantRefBase {
return variantIsNull(_data);
}

FORCE_INLINE bool isUndefined() const {
return !_data;
}

FORCE_INLINE size_t memoryUsage() const {
return _data ? _data->memoryUsage() : 0;
}
Expand Down
1 change: 1 addition & 0 deletions test/JsonVariant/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ add_executable(JsonVariantTests
as.cpp
clear.cpp
compare.cpp
containsKey.cpp
copy.cpp
createNested.cpp
is.cpp
Expand Down
28 changes: 28 additions & 0 deletions test/JsonVariant/containsKey.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// 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::containsKey()") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();

SECTION("containsKey(const char*) returns true") {
var["hello"] = "world";

REQUIRE(var.containsKey("hello") == true);
REQUIRE(var.containsKey("world") == false);
}

SECTION("containsKey(std::string) returns true") {
var["hello"] = "world";

REQUIRE(var.containsKey(std::string("hello")) == true);
REQUIRE(var.containsKey(std::string("world")) == false);
}
}
1 change: 1 addition & 0 deletions test/MemberProxy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
add_executable(MemberProxyTests
add.cpp
clear.cpp
containsKey.cpp
remove.cpp
set.cpp
size.cpp
Expand Down
27 changes: 27 additions & 0 deletions test/MemberProxy/containsKey.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License

#include <ArduinoJson.h>
#include <catch.hpp>

using namespace ARDUINOJSON_NAMESPACE;

TEST_CASE("MemberProxy::containsKey()") {
DynamicJsonDocument doc(4096);
MemberProxy<JsonDocument&, const char*> mp = doc["hello"];

SECTION("containsKey(const char*)") {
mp["key"] = "value";

REQUIRE(mp.containsKey("key") == true);
REQUIRE(mp.containsKey("key") == true);
}

SECTION("containsKey(std::string)") {
mp["key"] = "value";

REQUIRE(mp.containsKey(std::string("key")) == true);
REQUIRE(mp.containsKey(std::string("key")) == true);
}
}

0 comments on commit 6ec5ba5

Please sign in to comment.