forked from bblanchon/ArduinoJson
Changed the array subscript to automatically add missing elements
This commit is contained in:
@ -6,6 +6,7 @@ HEAD
|
||||
|
||||
* Added `DeserializationOption::Filter` (issue #959)
|
||||
* Added example `JsonFilterExample.ino`
|
||||
* Changed the array subscript operator to automatically add missing elements
|
||||
* Fixed "deprecated-copy" warning on GCC 9 (fixes #1184)
|
||||
|
||||
v6.14.1 (2020-01-27)
|
||||
|
@ -33,12 +33,9 @@ void setup() {
|
||||
"1000000,\"timezone\":0,\"sunrise\":1581492085,\"sunset\":1581527294}}");
|
||||
|
||||
// The filter: it contains "true" for each value we want to keep
|
||||
const __FlashStringHelper* filter_json =
|
||||
F("{\"list\":[{\"dt\":true,\"main\":{\"temp\":true}]}");
|
||||
|
||||
// Create the filter document
|
||||
StaticJsonDocument<200> filter;
|
||||
deserializeJson(filter, filter_json);
|
||||
filter["list"][0]["dt"] = true;
|
||||
filter["list"][0]["main"]["temp"] = true;
|
||||
|
||||
// Deserialize the document
|
||||
StaticJsonDocument<400> doc;
|
||||
|
@ -9,7 +9,6 @@ using namespace ARDUINOJSON_NAMESPACE;
|
||||
|
||||
TEST_CASE("ElementProxy::set()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.addElement();
|
||||
ElementProxy<JsonDocument&> ep = doc[0];
|
||||
|
||||
SECTION("set(int)") {
|
||||
|
25
extras/tests/ElementProxy/subscript.cpp
Normal file
25
extras/tests/ElementProxy/subscript.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
using namespace ARDUINOJSON_NAMESPACE;
|
||||
|
||||
TEST_CASE("MemberProxy::operator[]") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
ElementProxy<JsonDocument&> ep = doc[1];
|
||||
|
||||
SECTION("set member") {
|
||||
ep["world"] = 42;
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[null,{\"world\":42}]");
|
||||
}
|
||||
|
||||
SECTION("set element") {
|
||||
ep[2] = 42;
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[null,[null,null,42]]");
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -9,7 +9,20 @@
|
||||
TEST_CASE("JsonArray::operator[]") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
array.add(0);
|
||||
|
||||
SECTION("Pad with null") {
|
||||
array[2] = 2;
|
||||
array[5] = 5;
|
||||
REQUIRE(array.size() == 6);
|
||||
REQUIRE(array[0].isNull() == true);
|
||||
REQUIRE(array[1].isNull() == true);
|
||||
REQUIRE(array[2].isNull() == false);
|
||||
REQUIRE(array[3].isNull() == true);
|
||||
REQUIRE(array[4].isNull() == true);
|
||||
REQUIRE(array[5].isNull() == false);
|
||||
REQUIRE(array[2] == 2);
|
||||
REQUIRE(array[5] == 5);
|
||||
}
|
||||
|
||||
SECTION("int") {
|
||||
array[0] = 123;
|
||||
|
@ -43,3 +43,11 @@ TEST_CASE("JsonDocument automatically promotes to object") {
|
||||
|
||||
REQUIRE(doc["one"]["two"]["three"] == 4);
|
||||
}
|
||||
|
||||
TEST_CASE("JsonDocument automatically promotes to array") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
doc[2] = 2;
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[null,null,2]");
|
||||
}
|
||||
|
@ -43,10 +43,10 @@ TEST_CASE("JsonVariant::operator[]") {
|
||||
SECTION("set value") {
|
||||
array.add("hello");
|
||||
|
||||
var[0] = "world";
|
||||
var[1] = "world";
|
||||
|
||||
REQUIRE(1 == var.size());
|
||||
REQUIRE(std::string("world") == var[0]);
|
||||
REQUIRE(var.size() == 2);
|
||||
REQUIRE(std::string("world") == var[1]);
|
||||
}
|
||||
|
||||
SECTION("set value in a nested object") {
|
||||
|
@ -11,9 +11,15 @@ TEST_CASE("MemberProxy::operator[]") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy<JsonDocument&, const char*> mp = doc["hello"];
|
||||
|
||||
SECTION("set integer") {
|
||||
SECTION("set member") {
|
||||
mp["world"] = 42;
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"hello\":{\"world\":42}}");
|
||||
}
|
||||
|
||||
SECTION("set element") {
|
||||
mp[2] = 42;
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"hello\":[null,null,42]}");
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline VariantData *arrayAdd(CollectionData *arr, MemoryPool *pool) {
|
||||
return arr ? arr->add(pool) : 0;
|
||||
return arr ? arr->addElement(pool) : 0;
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
|
@ -87,7 +87,7 @@ class ArrayConstRef : public ArrayRefBase<const CollectionData>,
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef getElement(size_t index) const {
|
||||
return VariantConstRef(_data ? _data->get(index) : 0);
|
||||
return VariantConstRef(_data ? _data->getElement(index) : 0);
|
||||
}
|
||||
};
|
||||
|
||||
@ -137,23 +137,28 @@ class ArrayRef : public ArrayRefBase<CollectionData>,
|
||||
return arrayEquals(_data, rhs._data);
|
||||
}
|
||||
|
||||
// Internal use
|
||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
|
||||
return VariantRef(_pool, _data ? _data->getOrAddElement(index, _pool) : 0);
|
||||
}
|
||||
|
||||
// Gets the value at the specified index.
|
||||
FORCE_INLINE VariantRef getElement(size_t index) const {
|
||||
return VariantRef(_pool, _data ? _data->get(index) : 0);
|
||||
return VariantRef(_pool, _data ? _data->getElement(index) : 0);
|
||||
}
|
||||
|
||||
// Removes element at specified position.
|
||||
FORCE_INLINE void remove(iterator it) const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->remove(it.internal());
|
||||
_data->removeSlot(it.internal());
|
||||
}
|
||||
|
||||
// Removes element at specified index.
|
||||
FORCE_INLINE void remove(size_t index) const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->remove(index);
|
||||
_data->removeElement(index);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -28,7 +28,7 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
: _array(src._array), _index(src._index) {}
|
||||
|
||||
FORCE_INLINE this_type& operator=(const this_type& src) {
|
||||
getUpstreamElement().set(src.as<VariantConstRef>());
|
||||
getOrAddUpstreamElement().set(src.as<VariantConstRef>());
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
// std::string, String, ArrayRef, ObjectRef
|
||||
template <typename T>
|
||||
FORCE_INLINE this_type& operator=(const T& src) {
|
||||
getUpstreamElement().set(src);
|
||||
getOrAddUpstreamElement().set(src);
|
||||
return *this;
|
||||
}
|
||||
//
|
||||
@ -47,7 +47,7 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
// TValue = char*, const char*, const __FlashStringHelper*
|
||||
template <typename T>
|
||||
FORCE_INLINE this_type& operator=(T* src) {
|
||||
getUpstreamElement().set(src);
|
||||
getOrAddUpstreamElement().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE typename VariantTo<T>::type to() const {
|
||||
return getUpstreamElement().template to<T>();
|
||||
return getOrAddUpstreamElement().template to<T>();
|
||||
}
|
||||
|
||||
// Replaces the value
|
||||
@ -89,14 +89,14 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
// std::string, String, ArrayRef, ObjectRef
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(const TValue& value) const {
|
||||
return getUpstreamElement().set(value);
|
||||
return getOrAddUpstreamElement().set(value);
|
||||
}
|
||||
//
|
||||
// bool set(TValue)
|
||||
// TValue = char*, const char*, const __FlashStringHelper*
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(TValue* value) const {
|
||||
return getUpstreamElement().set(value);
|
||||
return getOrAddUpstreamElement().set(value);
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
@ -120,20 +120,20 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef getOrAddMember(TNestedKey* key) const {
|
||||
return getUpstreamElement().getOrAddMember(key);
|
||||
return getOrAddUpstreamElement().getOrAddMember(key);
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef getOrAddMember(const TNestedKey& key) const {
|
||||
return getUpstreamElement().getOrAddMember(key);
|
||||
return getOrAddUpstreamElement().getOrAddMember(key);
|
||||
}
|
||||
|
||||
VariantRef addElement() const {
|
||||
return getUpstreamElement().addElement();
|
||||
return getOrAddUpstreamElement().addElement();
|
||||
}
|
||||
|
||||
VariantRef getElement(size_t index) const {
|
||||
return getUpstreamElement().getElement(index);
|
||||
return getOrAddUpstreamElement().getElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE void remove(size_t index) const {
|
||||
@ -160,6 +160,10 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
return _array.getElement(_index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getOrAddUpstreamElement() const {
|
||||
return _array.getOrAddElement(_index);
|
||||
}
|
||||
|
||||
TArray _array;
|
||||
const size_t _index;
|
||||
};
|
||||
|
@ -25,45 +25,56 @@ class CollectionData {
|
||||
// - no destructor
|
||||
// - no virtual
|
||||
// - no inheritance
|
||||
VariantSlot *addSlot(MemoryPool *);
|
||||
|
||||
VariantData *add(MemoryPool *pool);
|
||||
// Array only
|
||||
|
||||
VariantData *addElement(MemoryPool *pool);
|
||||
|
||||
VariantData *getElement(size_t index) const;
|
||||
|
||||
VariantData *getOrAddElement(size_t index, MemoryPool *pool);
|
||||
|
||||
void removeElement(size_t index);
|
||||
|
||||
bool equalsArray(const CollectionData &other) const;
|
||||
|
||||
// Object only
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData *add(TAdaptedString key, MemoryPool *pool);
|
||||
VariantData *addMember(TAdaptedString key, MemoryPool *pool);
|
||||
|
||||
void clear();
|
||||
template <typename TAdaptedString>
|
||||
VariantData *getMember(TAdaptedString key) const;
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData *getOrAddMember(TAdaptedString key, MemoryPool *pool);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
void removeMember(TAdaptedString key) {
|
||||
removeSlot(getSlot(key));
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
bool containsKey(const TAdaptedString &key) const;
|
||||
|
||||
bool copyFrom(const CollectionData &src, MemoryPool *pool);
|
||||
|
||||
bool equalsArray(const CollectionData &other) const;
|
||||
bool equalsObject(const CollectionData &other) const;
|
||||
|
||||
VariantData *get(size_t index) const;
|
||||
// Generic
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData *get(TAdaptedString key) const;
|
||||
void clear();
|
||||
size_t memoryUsage() const;
|
||||
size_t nesting() const;
|
||||
size_t size() const;
|
||||
|
||||
VariantSlot *addSlot(MemoryPool *);
|
||||
void removeSlot(VariantSlot *slot);
|
||||
|
||||
bool copyFrom(const CollectionData &src, MemoryPool *pool);
|
||||
|
||||
VariantSlot *head() const {
|
||||
return _head;
|
||||
}
|
||||
|
||||
void remove(size_t index);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
void remove(TAdaptedString key) {
|
||||
remove(getSlot(key));
|
||||
}
|
||||
|
||||
void remove(VariantSlot *slot);
|
||||
|
||||
size_t memoryUsage() const;
|
||||
size_t nesting() const;
|
||||
size_t size() const;
|
||||
|
||||
void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance);
|
||||
|
||||
private:
|
||||
|
@ -26,12 +26,13 @@ inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) {
|
||||
return slot;
|
||||
}
|
||||
|
||||
inline VariantData* CollectionData::add(MemoryPool* pool) {
|
||||
inline VariantData* CollectionData::addElement(MemoryPool* pool) {
|
||||
return slotData(addSlot(pool));
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData* CollectionData::add(TAdaptedString key, MemoryPool* pool) {
|
||||
inline VariantData* CollectionData::addMember(TAdaptedString key,
|
||||
MemoryPool* pool) {
|
||||
VariantSlot* slot = addSlot(pool);
|
||||
if (!slotSetKey(slot, key, pool))
|
||||
return 0;
|
||||
@ -55,11 +56,11 @@ inline bool CollectionData::copyFrom(const CollectionData& src,
|
||||
VariantData* var;
|
||||
if (s->key() != 0) {
|
||||
if (s->ownsKey())
|
||||
var = add(RamStringAdapter(s->key()), pool);
|
||||
var = addMember(RamStringAdapter(s->key()), pool);
|
||||
else
|
||||
var = add(ConstRamStringAdapter(s->key()), pool);
|
||||
var = addMember(ConstRamStringAdapter(s->key()), pool);
|
||||
} else {
|
||||
var = add(pool);
|
||||
var = addElement(pool);
|
||||
}
|
||||
if (!var)
|
||||
return false;
|
||||
@ -73,7 +74,7 @@ inline bool CollectionData::equalsObject(const CollectionData& other) const {
|
||||
size_t count = 0;
|
||||
for (VariantSlot* slot = _head; slot; slot = slot->next()) {
|
||||
VariantData* v1 = slot->data();
|
||||
VariantData* v2 = other.get(adaptString(slot->key()));
|
||||
VariantData* v2 = other.getMember(adaptString(slot->key()));
|
||||
if (!variantEquals(v1, v2))
|
||||
return false;
|
||||
count++;
|
||||
@ -123,17 +124,40 @@ inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData* CollectionData::get(TAdaptedString key) const {
|
||||
inline VariantData* CollectionData::getMember(TAdaptedString key) const {
|
||||
VariantSlot* slot = getSlot(key);
|
||||
return slot ? slot->data() : 0;
|
||||
}
|
||||
|
||||
inline VariantData* CollectionData::get(size_t index) const {
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData* CollectionData::getOrAddMember(TAdaptedString key,
|
||||
MemoryPool* pool) {
|
||||
VariantSlot* slot = getSlot(key);
|
||||
return slot ? slot->data() : addMember(key, pool);
|
||||
}
|
||||
|
||||
inline VariantData* CollectionData::getElement(size_t index) const {
|
||||
VariantSlot* slot = getSlot(index);
|
||||
return slot ? slot->data() : 0;
|
||||
}
|
||||
|
||||
inline void CollectionData::remove(VariantSlot* slot) {
|
||||
inline VariantData* CollectionData::getOrAddElement(size_t index,
|
||||
MemoryPool* pool) {
|
||||
VariantSlot* slot = _head;
|
||||
while (slot && index > 0) {
|
||||
slot = slot->next();
|
||||
index--;
|
||||
}
|
||||
if (!slot)
|
||||
index++;
|
||||
while (index > 0) {
|
||||
slot = addSlot(pool);
|
||||
index--;
|
||||
}
|
||||
return slotData(slot);
|
||||
}
|
||||
|
||||
inline void CollectionData::removeSlot(VariantSlot* slot) {
|
||||
if (!slot)
|
||||
return;
|
||||
VariantSlot* prev = getPreviousSlot(slot);
|
||||
@ -146,8 +170,8 @@ inline void CollectionData::remove(VariantSlot* slot) {
|
||||
_tail = prev;
|
||||
}
|
||||
|
||||
inline void CollectionData::remove(size_t index) {
|
||||
remove(getSlot(index));
|
||||
inline void CollectionData::removeElement(size_t index) {
|
||||
removeSlot(getSlot(index));
|
||||
}
|
||||
|
||||
inline size_t CollectionData::memoryUsage() const {
|
||||
|
@ -192,6 +192,10 @@ class JsonDocument : public Visitable {
|
||||
return VariantConstRef(_data.getElement(index));
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) {
|
||||
return VariantRef(&_pool, _data.getOrAddElement(index, &_pool));
|
||||
}
|
||||
|
||||
// JsonVariantConst getMember(char*) const
|
||||
// JsonVariantConst getMember(const char*) const
|
||||
// JsonVariantConst getMember(const __FlashStringHelper*) const
|
||||
|
@ -139,7 +139,7 @@ class JsonDeserializer {
|
||||
for (;;) {
|
||||
if (memberFilter.allow()) {
|
||||
// Allocate slot in array
|
||||
VariantData *value = array.add(_pool);
|
||||
VariantData *value = array.addElement(_pool);
|
||||
if (!value)
|
||||
return DeserializationError::NoMemory;
|
||||
|
||||
@ -231,7 +231,7 @@ class JsonDeserializer {
|
||||
TFilter memberFilter = filter[key];
|
||||
|
||||
if (memberFilter.allow()) {
|
||||
VariantData *variant = object.get(adaptString(key));
|
||||
VariantData *variant = object.getMember(adaptString(key));
|
||||
if (!variant) {
|
||||
// Allocate slot in object
|
||||
VariantSlot *slot = object.addSlot(_pool);
|
||||
|
@ -269,7 +269,7 @@ class MsgPackDeserializer {
|
||||
return DeserializationError::TooDeep;
|
||||
|
||||
for (; n; --n) {
|
||||
VariantData *value = array.add(_pool);
|
||||
VariantData *value = array.addElement(_pool);
|
||||
if (!value)
|
||||
return DeserializationError::NoMemory;
|
||||
|
||||
|
@ -129,11 +129,14 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
||||
return getOrAddUpstreamMember().addElement();
|
||||
}
|
||||
|
||||
// getElement(size_t) const
|
||||
FORCE_INLINE VariantRef getElement(size_t index) const {
|
||||
return getUpstreamMember().getElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
|
||||
return getOrAddUpstreamMember().getOrAddElement(index);
|
||||
}
|
||||
|
||||
// getMember(char*) const
|
||||
// getMember(const char*) const
|
||||
// getMember(const __FlashStringHelper*) const
|
||||
|
@ -28,14 +28,14 @@ template <typename TAdaptedString>
|
||||
inline VariantData *objectGet(const CollectionData *obj, TAdaptedString key) {
|
||||
if (!obj)
|
||||
return 0;
|
||||
return obj->get(key);
|
||||
return obj->getMember(key);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
void objectRemove(CollectionData *obj, TAdaptedString key) {
|
||||
if (!obj)
|
||||
return;
|
||||
obj->remove(key);
|
||||
obj->removeMember(key);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
@ -49,10 +49,10 @@ inline VariantData *objectGetOrCreate(CollectionData *obj, TAdaptedString key,
|
||||
return 0;
|
||||
|
||||
// search a matching key
|
||||
VariantData *var = obj->get(key);
|
||||
VariantData *var = obj->getMember(key);
|
||||
if (var)
|
||||
return var;
|
||||
|
||||
return obj->add(key, pool);
|
||||
return obj->addMember(key, pool);
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
@ -213,7 +213,7 @@ class ObjectRef : public ObjectRefBase<CollectionData>,
|
||||
FORCE_INLINE void remove(iterator it) const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->remove(it.internal());
|
||||
_data->removeSlot(it.internal());
|
||||
}
|
||||
|
||||
// remove(const std::string&) const
|
||||
|
@ -186,13 +186,13 @@ class VariantData {
|
||||
|
||||
void remove(size_t index) {
|
||||
if (isArray())
|
||||
_content.asCollection.remove(index);
|
||||
_content.asCollection.removeElement(index);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
void remove(TAdaptedString key) {
|
||||
if (isObject())
|
||||
_content.asCollection.remove(key);
|
||||
_content.asCollection.removeMember(key);
|
||||
}
|
||||
|
||||
void setBoolean(bool value) {
|
||||
@ -335,16 +335,24 @@ class VariantData {
|
||||
toArray();
|
||||
if (!isArray())
|
||||
return 0;
|
||||
return _content.asCollection.add(pool);
|
||||
return _content.asCollection.addElement(pool);
|
||||
}
|
||||
|
||||
VariantData *getElement(size_t index) const {
|
||||
return isArray() ? _content.asCollection.get(index) : 0;
|
||||
return isArray() ? _content.asCollection.getElement(index) : 0;
|
||||
}
|
||||
|
||||
VariantData *getOrAddElement(size_t index, MemoryPool *pool) {
|
||||
if (isNull())
|
||||
toArray();
|
||||
if (!isArray())
|
||||
return 0;
|
||||
return _content.asCollection.getOrAddElement(index, pool);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData *getMember(TAdaptedString key) const {
|
||||
return isObject() ? _content.asCollection.get(key) : 0;
|
||||
return isObject() ? _content.asCollection.getMember(key) : 0;
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
@ -353,10 +361,7 @@ class VariantData {
|
||||
toObject();
|
||||
if (!isObject())
|
||||
return 0;
|
||||
VariantData *var = _content.asCollection.get(key);
|
||||
if (var)
|
||||
return var;
|
||||
return _content.asCollection.add(key, pool);
|
||||
return _content.asCollection.getOrAddMember(key, pool);
|
||||
}
|
||||
|
||||
void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance) {
|
||||
|
@ -160,18 +160,26 @@ inline CollectionData *variantToObject(VariantData *var) {
|
||||
return &var->toObject();
|
||||
}
|
||||
|
||||
inline NO_INLINE VariantData *variantAdd(VariantData *var, MemoryPool *pool) {
|
||||
inline NO_INLINE VariantData *variantAddElement(VariantData *var,
|
||||
MemoryPool *pool) {
|
||||
return var != 0 ? var->addElement(pool) : 0;
|
||||
}
|
||||
|
||||
inline NO_INLINE VariantData *variantGetOrAddElement(VariantData *var,
|
||||
size_t index,
|
||||
MemoryPool *pool) {
|
||||
return var != 0 ? var->getOrAddElement(index, pool) : 0;
|
||||
}
|
||||
|
||||
template <typename TChar>
|
||||
NO_INLINE VariantData *variantGetOrCreate(VariantData *var, TChar *key,
|
||||
NO_INLINE VariantData *variantGetOrAddMember(VariantData *var, TChar *key,
|
||||
MemoryPool *pool) {
|
||||
return var != 0 ? var->getOrAddMember(adaptString(key), pool) : 0;
|
||||
}
|
||||
|
||||
template <typename TString>
|
||||
NO_INLINE VariantData *variantGetOrCreate(VariantData *var, const TString &key,
|
||||
NO_INLINE VariantData *variantGetOrAddMember(VariantData *var,
|
||||
const TString &key,
|
||||
MemoryPool *pool) {
|
||||
return var != 0 ? var->getOrAddMember(adaptString(key), pool) : 0;
|
||||
}
|
||||
|
@ -119,13 +119,17 @@ inline VariantConstRef VariantConstRef::getElement(size_t index) const {
|
||||
}
|
||||
|
||||
inline VariantRef VariantRef::addElement() const {
|
||||
return VariantRef(_pool, variantAdd(_data, _pool));
|
||||
return VariantRef(_pool, variantAddElement(_data, _pool));
|
||||
}
|
||||
|
||||
inline VariantRef VariantRef::getElement(size_t index) const {
|
||||
return VariantRef(_pool, _data != 0 ? _data->getElement(index) : 0);
|
||||
}
|
||||
|
||||
inline VariantRef VariantRef::getOrAddElement(size_t index) const {
|
||||
return VariantRef(_pool, variantGetOrAddElement(_data, index, _pool));
|
||||
}
|
||||
|
||||
template <typename TChar>
|
||||
inline VariantRef VariantRef::getMember(TChar *key) const {
|
||||
return VariantRef(_pool, _data != 0 ? _data->getMember(adaptString(key)) : 0);
|
||||
@ -139,11 +143,11 @@ VariantRef::getMember(const TString &key) const {
|
||||
|
||||
template <typename TChar>
|
||||
inline VariantRef VariantRef::getOrAddMember(TChar *key) const {
|
||||
return VariantRef(_pool, variantGetOrCreate(_data, key, _pool));
|
||||
return VariantRef(_pool, variantGetOrAddMember(_data, key, _pool));
|
||||
}
|
||||
|
||||
template <typename TString>
|
||||
inline VariantRef VariantRef::getOrAddMember(const TString &key) const {
|
||||
return VariantRef(_pool, variantGetOrCreate(_data, key, _pool));
|
||||
return VariantRef(_pool, variantGetOrAddMember(_data, key, _pool));
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
@ -301,6 +301,8 @@ class VariantRef : public VariantRefBase<VariantData>,
|
||||
|
||||
FORCE_INLINE VariantRef getElement(size_t) const;
|
||||
|
||||
FORCE_INLINE VariantRef getOrAddElement(size_t) const;
|
||||
|
||||
// getMember(const char*) const
|
||||
// getMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
@ -391,7 +393,7 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantConstRef getMember(TChar *key) const {
|
||||
const CollectionData *obj = variantAsObject(_data);
|
||||
return VariantConstRef(obj ? obj->get(adaptString(key)) : 0);
|
||||
return VariantConstRef(obj ? obj->getMember(adaptString(key)) : 0);
|
||||
}
|
||||
|
||||
// operator[](const std::string&) const
|
||||
|
Reference in New Issue
Block a user