mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-29 10:17:39 +02:00
Merge ArrayImpl
, CollectionImpl
, and ObjectImpl
into VariantImpl
This commit is contained in:
@ -1,41 +0,0 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2025, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
class ArrayImpl : public CollectionImpl {
|
||||
public:
|
||||
ArrayImpl() {}
|
||||
|
||||
ArrayImpl(VariantData* data, ResourceManager* resources)
|
||||
: CollectionImpl(data, resources) {}
|
||||
|
||||
bool isNull() const {
|
||||
return !data_ || data_->type != VariantType::Array;
|
||||
}
|
||||
|
||||
VariantData* addElement();
|
||||
|
||||
template <typename T>
|
||||
bool addValue(const T& value);
|
||||
|
||||
VariantData* getOrAddElement(size_t index);
|
||||
|
||||
VariantData* getElement(size_t index) const;
|
||||
|
||||
void removeElement(size_t index);
|
||||
|
||||
void remove(iterator it) {
|
||||
CollectionImpl::removeOne(it);
|
||||
}
|
||||
|
||||
private:
|
||||
iterator at(size_t index) const;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
@ -4,14 +4,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ArrayData.hpp>
|
||||
#include <ArduinoJson/Variant/VariantCompare.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
#include <ArduinoJson/Variant/VariantImpl.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
inline ArrayImpl::iterator ArrayImpl::at(size_t index) const {
|
||||
if (isNull())
|
||||
inline VariantImpl::iterator VariantImpl::at(size_t index) const {
|
||||
if (!isArray())
|
||||
return iterator();
|
||||
|
||||
auto it = createIterator();
|
||||
@ -22,17 +21,17 @@ inline ArrayImpl::iterator ArrayImpl::at(size_t index) const {
|
||||
return it;
|
||||
}
|
||||
|
||||
inline VariantData* ArrayImpl::addElement() {
|
||||
if (isNull())
|
||||
inline VariantData* VariantImpl::addElement() {
|
||||
if (!isArray())
|
||||
return nullptr;
|
||||
auto slot = allocVariant();
|
||||
if (!slot)
|
||||
return nullptr;
|
||||
CollectionImpl::appendOne(slot);
|
||||
VariantImpl::appendOne(slot);
|
||||
return slot.ptr();
|
||||
}
|
||||
|
||||
inline VariantData* ArrayImpl::getOrAddElement(size_t index) {
|
||||
inline VariantData* VariantImpl::getOrAddElement(size_t index) {
|
||||
auto it = createIterator();
|
||||
while (!it.done() && index > 0) {
|
||||
it.next(resources_);
|
||||
@ -50,17 +49,17 @@ inline VariantData* ArrayImpl::getOrAddElement(size_t index) {
|
||||
return element;
|
||||
}
|
||||
|
||||
inline VariantData* ArrayImpl::getElement(size_t index) const {
|
||||
inline VariantData* VariantImpl::getElement(size_t index) const {
|
||||
return at(index).data();
|
||||
}
|
||||
|
||||
inline void ArrayImpl::removeElement(size_t index) {
|
||||
remove(at(index));
|
||||
inline void VariantImpl::removeElement(size_t index) {
|
||||
removeElement(at(index));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool ArrayImpl::addValue(const T& value) {
|
||||
if (isNull())
|
||||
inline bool VariantImpl::addValue(const T& value) {
|
||||
if (!isArray())
|
||||
return false;
|
||||
auto slot = allocVariant();
|
||||
if (!slot)
|
||||
@ -70,7 +69,7 @@ inline bool ArrayImpl::addValue(const T& value) {
|
||||
freeVariant(slot);
|
||||
return false;
|
||||
}
|
||||
CollectionImpl::appendOne(slot);
|
||||
appendOne(slot);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,12 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
|
||||
}
|
||||
|
||||
VariantData* getOrCreateData() const {
|
||||
return VariantAttorney::getOrCreateVariantImpl(upstream_).getOrAddElement(
|
||||
index_);
|
||||
auto data = VariantAttorney::getOrCreateData(upstream_);
|
||||
auto resources = VariantAttorney::getResourceManager(upstream_);
|
||||
if (!data)
|
||||
return nullptr;
|
||||
data->getOrCreateArray();
|
||||
return VariantImpl(data, resources).getOrAddElement(index_);
|
||||
}
|
||||
|
||||
TUpstream upstream_;
|
||||
|
@ -26,16 +26,19 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
JsonArray(detail::VariantData* data, detail::ResourceManager* resources)
|
||||
: impl_(data, resources) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonArray(detail::VariantImpl impl) : impl_(impl) {}
|
||||
|
||||
// Returns a JsonVariant pointing to the array.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/
|
||||
operator JsonVariant() {
|
||||
return JsonVariant(getData(), getResourceManager());
|
||||
return JsonVariant(impl_);
|
||||
}
|
||||
|
||||
// Returns a read-only reference to the array.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/
|
||||
operator JsonArrayConst() const {
|
||||
return JsonArrayConst(getData(), getResourceManager());
|
||||
return JsonArrayConst(impl_);
|
||||
}
|
||||
|
||||
// Appends a new (empty) element to the array.
|
||||
@ -101,7 +104,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// Removes the element at the specified iterator.
|
||||
// https://arduinojson.org/v7/api/jsonarray/remove/
|
||||
void remove(iterator it) const {
|
||||
impl_.remove(it.iterator_);
|
||||
impl_.removeElement(it.iterator_);
|
||||
}
|
||||
|
||||
// Removes the element at the specified index.
|
||||
@ -122,7 +125,8 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// Removes all the elements of the array.
|
||||
// https://arduinojson.org/v7/api/jsonarray/clear/
|
||||
void clear() const {
|
||||
impl_.clear();
|
||||
if (impl_.isArray())
|
||||
impl_.empty();
|
||||
}
|
||||
|
||||
// Gets or sets the element at the specified index.
|
||||
@ -145,7 +149,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
}
|
||||
|
||||
operator JsonVariantConst() const {
|
||||
return JsonVariantConst(getData(), getResourceManager());
|
||||
return JsonVariantConst(impl_);
|
||||
}
|
||||
|
||||
// Returns true if the reference is unbound.
|
||||
@ -207,7 +211,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
return impl_.getData();
|
||||
}
|
||||
|
||||
mutable detail::ArrayImpl impl_;
|
||||
mutable detail::VariantImpl impl_;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PUBLIC_NAMESPACE
|
||||
|
@ -41,7 +41,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
: impl_(data, resources) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonArrayConst(const detail::ArrayImpl& impl) : impl_(impl) {}
|
||||
JsonArrayConst(const detail::VariantImpl& impl) : impl_(impl) {}
|
||||
|
||||
// Returns the element at the specified index.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/subscript/
|
||||
@ -64,7 +64,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
}
|
||||
|
||||
operator JsonVariantConst() const {
|
||||
return JsonVariantConst(impl_.getData(), impl_.getResourceManager());
|
||||
return JsonVariantConst(impl_);
|
||||
}
|
||||
|
||||
// Returns true if the reference is unbound.
|
||||
@ -102,7 +102,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
return impl_.getData();
|
||||
}
|
||||
|
||||
detail::ArrayImpl impl_;
|
||||
detail::VariantImpl impl_;
|
||||
};
|
||||
|
||||
// Compares the content of two arrays.
|
||||
|
@ -30,7 +30,7 @@ class JsonArrayIterator {
|
||||
|
||||
public:
|
||||
JsonArrayIterator() {}
|
||||
explicit JsonArrayIterator(detail::ArrayImpl::iterator iterator,
|
||||
explicit JsonArrayIterator(detail::VariantImpl::iterator iterator,
|
||||
detail::ResourceManager* resources)
|
||||
: iterator_(iterator), resources_(resources) {}
|
||||
|
||||
@ -55,7 +55,7 @@ class JsonArrayIterator {
|
||||
}
|
||||
|
||||
private:
|
||||
detail::ArrayImpl::iterator iterator_;
|
||||
detail::VariantImpl::iterator iterator_;
|
||||
detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
@ -64,7 +64,7 @@ class JsonArrayConstIterator {
|
||||
|
||||
public:
|
||||
JsonArrayConstIterator() {}
|
||||
explicit JsonArrayConstIterator(detail::ArrayImpl::iterator iterator,
|
||||
explicit JsonArrayConstIterator(detail::VariantImpl::iterator iterator,
|
||||
detail::ResourceManager* resources)
|
||||
: iterator_(iterator), resources_(resources) {}
|
||||
|
||||
@ -89,7 +89,7 @@ class JsonArrayConstIterator {
|
||||
}
|
||||
|
||||
private:
|
||||
mutable detail::ArrayImpl::iterator iterator_;
|
||||
mutable detail::VariantImpl::iterator iterator_;
|
||||
mutable detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
|
@ -15,7 +15,7 @@ struct VariantData;
|
||||
class ResourceManager;
|
||||
|
||||
class CollectionIterator {
|
||||
friend class CollectionImpl;
|
||||
friend class VariantImpl;
|
||||
|
||||
public:
|
||||
CollectionIterator() : slot_(nullptr), currentId_(NULL_SLOT) {}
|
||||
@ -65,76 +65,4 @@ class CollectionIterator {
|
||||
SlotId currentId_;
|
||||
};
|
||||
|
||||
class CollectionImpl {
|
||||
protected:
|
||||
VariantData* data_;
|
||||
ResourceManager* resources_;
|
||||
|
||||
public:
|
||||
using iterator = CollectionIterator;
|
||||
|
||||
CollectionImpl() : data_(nullptr), resources_(nullptr) {}
|
||||
|
||||
CollectionImpl(VariantData* data, ResourceManager* resources)
|
||||
: data_(data), resources_(resources) {}
|
||||
|
||||
explicit operator bool() const {
|
||||
return data_ && data_->isCollection();
|
||||
}
|
||||
|
||||
bool isNull() const {
|
||||
return !operator bool();
|
||||
}
|
||||
|
||||
VariantData* getData() const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
ResourceManager* getResourceManager() const {
|
||||
return resources_;
|
||||
}
|
||||
|
||||
iterator createIterator() const;
|
||||
|
||||
size_t size() const;
|
||||
size_t nesting() const;
|
||||
|
||||
void clear();
|
||||
|
||||
SlotId head() const {
|
||||
return getCollectionData()->head;
|
||||
}
|
||||
|
||||
protected:
|
||||
void appendOne(Slot<VariantData> slot);
|
||||
void appendPair(Slot<VariantData> key, Slot<VariantData> value);
|
||||
|
||||
void removeOne(iterator it);
|
||||
void removePair(iterator it);
|
||||
|
||||
VariantData* getVariant(SlotId id) const {
|
||||
ARDUINOJSON_ASSERT(resources_ != nullptr);
|
||||
return resources_->getVariant(id);
|
||||
}
|
||||
|
||||
void freeVariant(Slot<VariantData> slot) {
|
||||
ARDUINOJSON_ASSERT(resources_ != nullptr);
|
||||
resources_->freeVariant(slot);
|
||||
}
|
||||
|
||||
Slot<VariantData> allocVariant() {
|
||||
ARDUINOJSON_ASSERT(resources_ != nullptr);
|
||||
return resources_->allocVariant();
|
||||
}
|
||||
|
||||
private:
|
||||
Slot<VariantData> getPreviousSlot(VariantData*) const;
|
||||
|
||||
CollectionData* getCollectionData() const {
|
||||
ARDUINOJSON_ASSERT(data_ != nullptr);
|
||||
ARDUINOJSON_ASSERT(data_->isCollection());
|
||||
return &data_->content.asCollection;
|
||||
}
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -19,14 +19,14 @@ inline void CollectionIterator::next(const ResourceManager* resources) {
|
||||
currentId_ = nextId;
|
||||
}
|
||||
|
||||
inline CollectionImpl::iterator CollectionImpl::createIterator() const {
|
||||
inline VariantImpl::iterator VariantImpl::createIterator() const {
|
||||
if (!data_ || !data_->isCollection())
|
||||
return iterator();
|
||||
auto coll = getCollectionData();
|
||||
return iterator(getVariant(coll->head), coll->head);
|
||||
}
|
||||
|
||||
inline void CollectionImpl::appendOne(Slot<VariantData> slot) {
|
||||
inline void VariantImpl::appendOne(Slot<VariantData> slot) {
|
||||
auto coll = getCollectionData();
|
||||
|
||||
if (coll->tail != NULL_SLOT) {
|
||||
@ -39,8 +39,8 @@ inline void CollectionImpl::appendOne(Slot<VariantData> slot) {
|
||||
}
|
||||
}
|
||||
|
||||
inline void CollectionImpl::appendPair(Slot<VariantData> key,
|
||||
Slot<VariantData> value) {
|
||||
inline void VariantImpl::appendPair(Slot<VariantData> key,
|
||||
Slot<VariantData> value) {
|
||||
auto coll = getCollectionData();
|
||||
|
||||
key->next = value.id();
|
||||
@ -54,26 +54,7 @@ inline void CollectionImpl::appendPair(Slot<VariantData> key,
|
||||
coll->tail = value.id();
|
||||
}
|
||||
}
|
||||
|
||||
inline void CollectionImpl::clear() {
|
||||
if (!data_ || !data_->isCollection())
|
||||
return;
|
||||
|
||||
auto coll = getCollectionData();
|
||||
|
||||
auto next = coll->head;
|
||||
while (next != NULL_SLOT) {
|
||||
auto currId = next;
|
||||
auto slot = getVariant(next);
|
||||
next = slot->next;
|
||||
freeVariant({slot, currId});
|
||||
}
|
||||
|
||||
coll->head = NULL_SLOT;
|
||||
coll->tail = NULL_SLOT;
|
||||
}
|
||||
|
||||
inline Slot<VariantData> CollectionImpl::getPreviousSlot(
|
||||
inline Slot<VariantData> VariantImpl::getPreviousSlot(
|
||||
VariantData* target) const {
|
||||
auto coll = getCollectionData();
|
||||
auto prev = Slot<VariantData>();
|
||||
@ -88,7 +69,7 @@ inline Slot<VariantData> CollectionImpl::getPreviousSlot(
|
||||
return prev;
|
||||
}
|
||||
|
||||
inline void CollectionImpl::removeOne(iterator it) {
|
||||
inline void VariantImpl::removeOne(iterator it) {
|
||||
if (it.done())
|
||||
return;
|
||||
auto coll = getCollectionData();
|
||||
@ -104,7 +85,7 @@ inline void CollectionImpl::removeOne(iterator it) {
|
||||
freeVariant({it.slot_, it.currentId_});
|
||||
}
|
||||
|
||||
inline void CollectionImpl::removePair(ObjectImpl::iterator it) {
|
||||
inline void VariantImpl::removePair(VariantImpl::iterator it) {
|
||||
if (it.done())
|
||||
return;
|
||||
|
||||
@ -121,7 +102,7 @@ inline void CollectionImpl::removePair(ObjectImpl::iterator it) {
|
||||
removeOne(it);
|
||||
}
|
||||
|
||||
inline size_t CollectionImpl::nesting() const {
|
||||
inline size_t VariantImpl::nesting() const {
|
||||
if (!data_ || !data_->isCollection())
|
||||
return 0;
|
||||
size_t maxChildNesting = 0;
|
||||
@ -134,11 +115,4 @@ inline size_t CollectionImpl::nesting() const {
|
||||
return maxChildNesting + 1;
|
||||
}
|
||||
|
||||
inline size_t CollectionImpl::size() const {
|
||||
size_t count = 0;
|
||||
for (auto it = createIterator(); !it.done(); it.next(resources_))
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -267,14 +267,14 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
template <typename T, detail::enable_if_t<
|
||||
detail::is_same<T, JsonVariant>::value, int> = 0>
|
||||
JsonVariant add() {
|
||||
return JsonVariant(getVariantImpl().addElement(), &resources_);
|
||||
return JsonVariant(getOrCreateArray().addElement(), &resources_);
|
||||
}
|
||||
|
||||
// Appends a value to the root array.
|
||||
// https://arduinojson.org/v7/api/jsondocument/add/
|
||||
template <typename TValue>
|
||||
bool add(const TValue& value) {
|
||||
return getVariantImpl().addValue(value);
|
||||
return getOrCreateArray().addValue(value);
|
||||
}
|
||||
|
||||
// Appends a value to the root array.
|
||||
@ -282,7 +282,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
template <typename TChar,
|
||||
detail::enable_if_t<!detail::is_const<TChar>::value, int> = 0>
|
||||
bool add(TChar* value) {
|
||||
return getVariantImpl().addValue(value);
|
||||
return getOrCreateArray().addValue(value);
|
||||
}
|
||||
|
||||
// Removes an element of the root array.
|
||||
@ -392,6 +392,14 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
return detail::VariantImpl(&data_, &resources_);
|
||||
}
|
||||
|
||||
detail::VariantImpl getOrCreateArray() {
|
||||
return detail::VariantImpl(data_.getOrCreateArray(), &resources_);
|
||||
}
|
||||
|
||||
detail::VariantImpl getOrCreateObject() {
|
||||
return detail::VariantImpl(data_.getOrCreateObject(), &resources_);
|
||||
}
|
||||
|
||||
JsonVariant getVariant() {
|
||||
return JsonVariant(&data_, &resources_);
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ class JsonDeserializer {
|
||||
// Read each value
|
||||
for (;;) {
|
||||
if (elementFilter.allow()) {
|
||||
ArrayImpl array(arrayData, resources_);
|
||||
VariantImpl array(arrayData, resources_);
|
||||
|
||||
// Allocate slot in array
|
||||
VariantData* value = array.addElement();
|
||||
@ -277,7 +277,7 @@ class JsonDeserializer {
|
||||
TFilter memberFilter = filter[key];
|
||||
|
||||
if (memberFilter.allow()) {
|
||||
ObjectImpl object(objectData, resources_);
|
||||
VariantImpl object(objectData, resources_);
|
||||
auto member = object.getMember(adaptString(key));
|
||||
if (!member) {
|
||||
auto keyVariant = object.addPair(&member);
|
||||
|
@ -19,7 +19,7 @@ class JsonSerializer : public VariantDataVisitor<size_t> {
|
||||
JsonSerializer(TWriter writer, ResourceManager* resources)
|
||||
: formatter_(writer), resources_(resources) {}
|
||||
|
||||
size_t visit(const ArrayImpl& array) {
|
||||
size_t visitArray(const VariantImpl& array) {
|
||||
write('[');
|
||||
|
||||
auto slotId = array.head();
|
||||
@ -39,7 +39,7 @@ class JsonSerializer : public VariantDataVisitor<size_t> {
|
||||
return bytesWritten();
|
||||
}
|
||||
|
||||
size_t visit(const ObjectImpl& object) {
|
||||
size_t visitObject(const VariantImpl& object) {
|
||||
write('{');
|
||||
|
||||
auto slotId = object.head();
|
||||
|
@ -19,7 +19,7 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
||||
PrettyJsonSerializer(TWriter writer, ResourceManager* resources)
|
||||
: base(writer, resources), nesting_(0) {}
|
||||
|
||||
size_t visit(const ArrayImpl& array) {
|
||||
size_t visitArray(const VariantImpl& array) {
|
||||
auto it = array.createIterator();
|
||||
if (!it.done()) {
|
||||
base::write("[\r\n");
|
||||
@ -40,7 +40,7 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
||||
return this->bytesWritten();
|
||||
}
|
||||
|
||||
size_t visit(const ObjectImpl& object) {
|
||||
size_t visitObject(const VariantImpl& object) {
|
||||
auto it = object.createIterator();
|
||||
if (!it.done()) {
|
||||
base::write("{\r\n");
|
||||
|
@ -349,10 +349,10 @@ class MsgPackDeserializer {
|
||||
|
||||
bool allowArray = filter.allowArray();
|
||||
|
||||
ArrayImpl array;
|
||||
VariantImpl array;
|
||||
if (allowArray) {
|
||||
ARDUINOJSON_ASSERT(variant != 0);
|
||||
array = ArrayImpl(variant->toArray(), resources_);
|
||||
array = VariantImpl(variant->toArray(), resources_);
|
||||
}
|
||||
|
||||
TFilter elementFilter = filter[0U];
|
||||
@ -385,10 +385,10 @@ class MsgPackDeserializer {
|
||||
if (nestingLimit.reached())
|
||||
return DeserializationError::TooDeep;
|
||||
|
||||
ObjectImpl object;
|
||||
VariantImpl object;
|
||||
if (filter.allowObject()) {
|
||||
ARDUINOJSON_ASSERT(variant != 0);
|
||||
object = ObjectImpl(variant->toObject(), resources_);
|
||||
object = VariantImpl(variant->toObject(), resources_);
|
||||
}
|
||||
|
||||
for (; n; --n) {
|
||||
|
@ -47,7 +47,7 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
|
||||
return bytesWritten();
|
||||
}
|
||||
|
||||
size_t visit(const ArrayImpl& array) {
|
||||
size_t visitArray(const VariantImpl& array) {
|
||||
size_t n = array.size();
|
||||
if (n < 0x10) {
|
||||
writeByte(uint8_t(0x90 + n));
|
||||
@ -69,7 +69,7 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
|
||||
return bytesWritten();
|
||||
}
|
||||
|
||||
size_t visit(const ObjectImpl& object) {
|
||||
size_t visitObject(const VariantImpl& object) {
|
||||
size_t n = object.size();
|
||||
if (n < 0x10) {
|
||||
writeByte(uint8_t(0x80 + n));
|
||||
|
@ -26,28 +26,31 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
JsonObject(detail::VariantData* data, detail::ResourceManager* resource)
|
||||
: impl_(data, resource) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonObject(detail::VariantImpl impl) : impl_(impl) {}
|
||||
|
||||
operator JsonVariant() const {
|
||||
return JsonVariant(getData(), getResourceManager());
|
||||
return JsonVariant(impl_);
|
||||
}
|
||||
|
||||
operator JsonObjectConst() const {
|
||||
return JsonObjectConst(getData(), getResourceManager());
|
||||
return JsonObjectConst(impl_);
|
||||
}
|
||||
|
||||
operator JsonVariantConst() const {
|
||||
return JsonVariantConst(getData(), getResourceManager());
|
||||
return JsonVariantConst(impl_);
|
||||
}
|
||||
|
||||
// Returns true if the reference is unbound.
|
||||
// https://arduinojson.org/v7/api/jsonobject/isnull/
|
||||
bool isNull() const {
|
||||
return impl_.isNull();
|
||||
return !operator bool();
|
||||
}
|
||||
|
||||
// Returns true if the reference is bound.
|
||||
// https://arduinojson.org/v7/api/jsonobject/isnull/
|
||||
operator bool() const {
|
||||
return !isNull();
|
||||
return impl_.isObject();
|
||||
}
|
||||
|
||||
// Returns the depth (nesting level) of the object.
|
||||
@ -77,7 +80,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// Removes all the members of the object.
|
||||
// https://arduinojson.org/v7/api/jsonobject/clear/
|
||||
void clear() const {
|
||||
impl_.clear();
|
||||
if (impl_.isObject())
|
||||
impl_.empty();
|
||||
}
|
||||
|
||||
// Copies an object.
|
||||
@ -127,7 +131,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// Removes the member at the specified iterator.
|
||||
// https://arduinojson.org/v7/api/jsonobject/remove/
|
||||
FORCE_INLINE void remove(iterator it) const {
|
||||
impl_.remove(it.iterator_);
|
||||
impl_.removeMember(it.iterator_);
|
||||
}
|
||||
|
||||
// Removes the member with the specified key.
|
||||
@ -230,7 +234,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
return impl_.getData();
|
||||
}
|
||||
|
||||
mutable detail::ObjectImpl impl_;
|
||||
mutable detail::VariantImpl impl_;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PUBLIC_NAMESPACE
|
||||
|
@ -26,10 +26,10 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
: impl_(data, resources) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonObjectConst(const detail::ObjectImpl& impl) : impl_(impl) {}
|
||||
JsonObjectConst(const detail::VariantImpl& impl) : impl_(impl) {}
|
||||
|
||||
operator JsonVariantConst() const {
|
||||
return JsonVariantConst(impl_.getData(), impl_.getResourceManager());
|
||||
return JsonVariantConst(impl_);
|
||||
}
|
||||
|
||||
// Returns true if the reference is unbound.
|
||||
@ -136,7 +136,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
return impl_.getData();
|
||||
}
|
||||
|
||||
detail::ObjectImpl impl_;
|
||||
detail::VariantImpl impl_;
|
||||
};
|
||||
|
||||
inline bool operator==(JsonObjectConst lhs, JsonObjectConst rhs) {
|
||||
|
@ -14,7 +14,7 @@ class JsonObjectIterator {
|
||||
public:
|
||||
JsonObjectIterator() {}
|
||||
|
||||
explicit JsonObjectIterator(detail::ObjectImpl::iterator iterator,
|
||||
explicit JsonObjectIterator(detail::VariantImpl::iterator iterator,
|
||||
detail::ResourceManager* resources)
|
||||
: iterator_(iterator), resources_(resources) {}
|
||||
|
||||
@ -40,7 +40,7 @@ class JsonObjectIterator {
|
||||
}
|
||||
|
||||
private:
|
||||
detail::ObjectImpl::iterator iterator_;
|
||||
detail::VariantImpl::iterator iterator_;
|
||||
detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
@ -50,7 +50,7 @@ class JsonObjectConstIterator {
|
||||
public:
|
||||
JsonObjectConstIterator() {}
|
||||
|
||||
explicit JsonObjectConstIterator(detail::ObjectImpl::iterator iterator,
|
||||
explicit JsonObjectConstIterator(detail::VariantImpl::iterator iterator,
|
||||
detail::ResourceManager* resources)
|
||||
: iterator_(iterator), resources_(resources) {}
|
||||
|
||||
@ -76,7 +76,7 @@ class JsonObjectConstIterator {
|
||||
}
|
||||
|
||||
private:
|
||||
detail::ObjectImpl::iterator iterator_;
|
||||
detail::VariantImpl::iterator iterator_;
|
||||
detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
|
@ -15,7 +15,7 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
|
||||
class JsonPair {
|
||||
public:
|
||||
// INTERNAL USE ONLY
|
||||
JsonPair(detail::ObjectImpl::iterator iterator,
|
||||
JsonPair(detail::VariantImpl::iterator iterator,
|
||||
detail::ResourceManager* resources) {
|
||||
if (!iterator.done()) {
|
||||
detail::VariantImpl variant(iterator.data(), resources);
|
||||
@ -44,7 +44,7 @@ class JsonPair {
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/begin_end/
|
||||
class JsonPairConst {
|
||||
public:
|
||||
JsonPairConst(detail::ObjectImpl::iterator iterator,
|
||||
JsonPairConst(detail::VariantImpl::iterator iterator,
|
||||
detail::ResourceManager* resources) {
|
||||
if (!iterator.done()) {
|
||||
detail::VariantImpl variant(iterator.data(), resources);
|
||||
|
@ -60,8 +60,12 @@ class MemberProxy
|
||||
}
|
||||
|
||||
VariantData* getOrCreateData() const {
|
||||
return VariantAttorney::getOrCreateVariantImpl(upstream_).getOrAddMember(
|
||||
key_);
|
||||
auto data = VariantAttorney::getOrCreateData(upstream_);
|
||||
auto resources = VariantAttorney::getResourceManager(upstream_);
|
||||
if (!data)
|
||||
return nullptr;
|
||||
data->getOrCreateObject();
|
||||
return VariantImpl(data, resources).getOrAddMember(key_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -1,51 +0,0 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2025, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
class VariantImpl;
|
||||
|
||||
class ObjectImpl : public CollectionImpl {
|
||||
public:
|
||||
ObjectImpl() {}
|
||||
|
||||
ObjectImpl(VariantData* data, ResourceManager* resources)
|
||||
: CollectionImpl(data, resources) {}
|
||||
|
||||
bool isNull() const {
|
||||
return !data_ || data_->type != VariantType::Object;
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData* addMember(TAdaptedString key);
|
||||
|
||||
VariantData* addPair(VariantData** value);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData* getOrAddMember(TAdaptedString key);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData* getMember(TAdaptedString key) const;
|
||||
|
||||
template <typename TAdaptedString>
|
||||
void removeMember(TAdaptedString key);
|
||||
|
||||
void remove(iterator it) {
|
||||
CollectionImpl::removePair(it);
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return CollectionImpl::size() / 2;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename TAdaptedString>
|
||||
iterator findKey(TAdaptedString key) const;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
@ -4,14 +4,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Object/ObjectData.hpp>
|
||||
#include <ArduinoJson/Variant/VariantCompare.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
#include <ArduinoJson/Variant/VariantImpl.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData* ObjectImpl::getMember(TAdaptedString key) const {
|
||||
inline VariantData* VariantImpl::getMember(TAdaptedString key) const {
|
||||
auto it = findKey(key);
|
||||
if (it.done())
|
||||
return nullptr;
|
||||
@ -20,7 +19,7 @@ inline VariantData* ObjectImpl::getMember(TAdaptedString key) const {
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData* ObjectImpl::getOrAddMember(TAdaptedString key) {
|
||||
VariantData* VariantImpl::getOrAddMember(TAdaptedString key) {
|
||||
auto data = getMember(key);
|
||||
if (data)
|
||||
return data;
|
||||
@ -28,8 +27,8 @@ VariantData* ObjectImpl::getOrAddMember(TAdaptedString key) {
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline ObjectImpl::iterator ObjectImpl::findKey(TAdaptedString key) const {
|
||||
if (isNull())
|
||||
inline VariantImpl::iterator VariantImpl::findKey(TAdaptedString key) const {
|
||||
if (!isObject())
|
||||
return iterator();
|
||||
if (key.isNull())
|
||||
return iterator();
|
||||
@ -44,13 +43,13 @@ inline ObjectImpl::iterator ObjectImpl::findKey(TAdaptedString key) const {
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline void ObjectImpl::removeMember(TAdaptedString key) {
|
||||
remove(findKey(key));
|
||||
inline void VariantImpl::removeMember(TAdaptedString key) {
|
||||
removeMember(findKey(key));
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData* ObjectImpl::addMember(TAdaptedString key) {
|
||||
if (isNull())
|
||||
inline VariantData* VariantImpl::addMember(TAdaptedString key) {
|
||||
if (!isObject())
|
||||
return nullptr;
|
||||
|
||||
auto keySlot = allocVariant();
|
||||
@ -65,13 +64,13 @@ inline VariantData* ObjectImpl::addMember(TAdaptedString key) {
|
||||
if (!keyImpl.setString(key))
|
||||
return nullptr;
|
||||
|
||||
CollectionImpl::appendPair(keySlot, valueSlot);
|
||||
VariantImpl::appendPair(keySlot, valueSlot);
|
||||
|
||||
return valueSlot.ptr();
|
||||
}
|
||||
|
||||
inline VariantData* ObjectImpl::addPair(VariantData** value) {
|
||||
ARDUINOJSON_ASSERT(!isNull());
|
||||
inline VariantData* VariantImpl::addPair(VariantData** value) {
|
||||
ARDUINOJSON_ASSERT(isObject());
|
||||
|
||||
auto keySlot = allocVariant();
|
||||
if (!keySlot)
|
||||
@ -82,7 +81,7 @@ inline VariantData* ObjectImpl::addPair(VariantData** value) {
|
||||
return nullptr;
|
||||
*value = valueSlot.ptr();
|
||||
|
||||
CollectionImpl::appendPair(keySlot, valueSlot);
|
||||
VariantImpl::appendPair(keySlot, valueSlot);
|
||||
|
||||
return keySlot.ptr();
|
||||
}
|
||||
|
@ -42,6 +42,9 @@ class JsonVariantConst : public detail::VariantTag,
|
||||
detail::ResourceManager* resources)
|
||||
: impl_(data, resources) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
explicit JsonVariantConst(detail::VariantImpl impl) : impl_(impl) {}
|
||||
|
||||
// Returns true if the value is null or the reference is unbound.
|
||||
// https://arduinojson.org/v7/api/jsonvariantconst/isnull/
|
||||
bool isNull() const {
|
||||
|
@ -28,11 +28,11 @@ class VisitorAdapter {
|
||||
|
||||
VisitorAdapter(TVisitor& visitor) : visitor_(&visitor) {}
|
||||
|
||||
result_type visit(const ArrayImpl& array) {
|
||||
result_type visitArray(const VariantImpl& array) {
|
||||
return visitor_->visit(JsonArrayConst(array));
|
||||
}
|
||||
|
||||
result_type visit(const ObjectImpl& object) {
|
||||
result_type visitObject(const VariantImpl& object) {
|
||||
return visitor_->visit(JsonObjectConst(object));
|
||||
}
|
||||
|
||||
|
@ -31,11 +31,6 @@ class VariantAttorney {
|
||||
return VariantImpl(client.getData(), client.getResourceManager());
|
||||
}
|
||||
|
||||
template <typename TClient>
|
||||
static VariantImpl getOrCreateVariantImpl(TClient& client) {
|
||||
return VariantImpl(client.getOrCreateData(), client.getResourceManager());
|
||||
}
|
||||
|
||||
template <typename TClient>
|
||||
static VariantData* getOrCreateData(TClient& client) {
|
||||
return client.getOrCreateData();
|
||||
|
@ -4,10 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ArrayData.hpp>
|
||||
#include <ArduinoJson/Numbers/JsonFloat.hpp>
|
||||
#include <ArduinoJson/Numbers/JsonInteger.hpp>
|
||||
#include <ArduinoJson/Object/ObjectData.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
@ -15,6 +13,14 @@ template <typename TResult>
|
||||
struct VariantDataVisitor {
|
||||
using result_type = TResult;
|
||||
|
||||
TResult visitArray(const VariantImpl&) {
|
||||
return TResult();
|
||||
}
|
||||
|
||||
TResult visitObject(const VariantImpl&) {
|
||||
return TResult();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TResult visit(const T&) {
|
||||
return TResult();
|
||||
|
@ -4,11 +4,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ArrayData.hpp>
|
||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Misc/SerializedValue.hpp>
|
||||
#include <ArduinoJson/Numbers/convertNumber.hpp>
|
||||
#include <ArduinoJson/Object/ObjectData.hpp>
|
||||
#include <ArduinoJson/Strings/JsonString.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
@ -16,7 +15,12 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
class VariantImpl {
|
||||
VariantData* data_;
|
||||
ResourceManager* resources_;
|
||||
|
||||
public:
|
||||
using iterator = CollectionIterator;
|
||||
|
||||
VariantImpl() : data_(nullptr), resources_(nullptr) {}
|
||||
|
||||
VariantImpl(VariantData* data, ResourceManager* resources)
|
||||
@ -48,10 +52,10 @@ class VariantImpl {
|
||||
#endif
|
||||
|
||||
case VariantType::Array:
|
||||
return visit.visit(ArrayImpl(data_, resources_));
|
||||
return visit.visitArray(VariantImpl(data_, resources_));
|
||||
|
||||
case VariantType::Object:
|
||||
return visit.visit(ObjectImpl(data_, resources_));
|
||||
return visit.visitObject(VariantImpl(data_, resources_));
|
||||
|
||||
case VariantType::TinyString:
|
||||
return visit.visit(JsonString(data_->content.asTinyString));
|
||||
@ -89,18 +93,10 @@ class VariantImpl {
|
||||
}
|
||||
}
|
||||
|
||||
VariantData* addElement() {
|
||||
if (!data_)
|
||||
return nullptr;
|
||||
return ArrayImpl(data_->getOrCreateArray(), resources_).addElement();
|
||||
}
|
||||
VariantData* addElement();
|
||||
|
||||
template <typename T>
|
||||
bool addValue(const T& value) {
|
||||
if (!data_)
|
||||
return false;
|
||||
return ArrayImpl(data_->getOrCreateArray(), resources_).addValue(value);
|
||||
}
|
||||
bool addValue(const T& value);
|
||||
|
||||
bool asBoolean() const {
|
||||
if (!data_)
|
||||
@ -262,31 +258,26 @@ class VariantImpl {
|
||||
}
|
||||
#endif
|
||||
|
||||
VariantData* getElement(size_t index) {
|
||||
return ArrayImpl(data_, resources_).getElement(index);
|
||||
SlotId head() const {
|
||||
return getCollectionData()->head;
|
||||
}
|
||||
|
||||
iterator createIterator() const;
|
||||
|
||||
VariantData* getElement(size_t index) const;
|
||||
|
||||
VariantData* getOrAddElement(size_t index);
|
||||
|
||||
VariantData* addPair(VariantData** value);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData* getMember(TAdaptedString key) {
|
||||
return ObjectImpl(data_, resources_).getMember(key);
|
||||
}
|
||||
|
||||
VariantData* getOrAddElement(size_t index) {
|
||||
if (!data_)
|
||||
return nullptr;
|
||||
return ArrayImpl(data_->getOrCreateArray(), resources_)
|
||||
.getOrAddElement(index);
|
||||
}
|
||||
VariantData* addMember(TAdaptedString key);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData* getOrAddMember(TAdaptedString key) {
|
||||
if (key.isNull())
|
||||
return nullptr;
|
||||
if (!data_)
|
||||
return nullptr;
|
||||
return ObjectImpl(data_->getOrCreateObject(), resources_)
|
||||
.getOrAddMember(key);
|
||||
}
|
||||
VariantData* getMember(TAdaptedString key) const;
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData* getOrAddMember(TAdaptedString key);
|
||||
|
||||
bool isArray() const {
|
||||
return type() == VariantType::Array;
|
||||
@ -340,17 +331,21 @@ class VariantImpl {
|
||||
return data_ && data_->isString();
|
||||
}
|
||||
|
||||
size_t nesting() {
|
||||
return CollectionImpl(data_, resources_).nesting();
|
||||
size_t nesting() const;
|
||||
|
||||
void removeElement(iterator it) {
|
||||
if (!isArray())
|
||||
return;
|
||||
removeOne(it);
|
||||
}
|
||||
|
||||
void removeElement(size_t index) {
|
||||
ArrayImpl(data_, resources_).removeElement(index);
|
||||
}
|
||||
void removeElement(size_t index);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
void removeMember(TAdaptedString key) {
|
||||
ObjectImpl(data_, resources_).removeMember(key);
|
||||
void removeMember(TAdaptedString key);
|
||||
|
||||
void removeMember(iterator it) {
|
||||
removePair(it);
|
||||
}
|
||||
|
||||
bool setBoolean(bool value) {
|
||||
@ -454,13 +449,21 @@ class VariantImpl {
|
||||
|
||||
bool setLinkedString(const char* s);
|
||||
|
||||
size_t size() {
|
||||
auto size = CollectionImpl(data_, resources_).size();
|
||||
void empty();
|
||||
|
||||
if (data_ && data_->type == VariantType::Object)
|
||||
size /= 2;
|
||||
size_t size() const {
|
||||
if (!data_)
|
||||
return 0;
|
||||
|
||||
return size;
|
||||
size_t count = 0;
|
||||
|
||||
for (auto it = createIterator(); !it.done(); it.next(resources_))
|
||||
count++;
|
||||
|
||||
if (data_->type == VariantType::Object)
|
||||
count /= 2; // TODO: do this in JsonObject?
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
VariantType type() const {
|
||||
@ -471,8 +474,39 @@ class VariantImpl {
|
||||
void clear();
|
||||
|
||||
private:
|
||||
VariantData* data_;
|
||||
ResourceManager* resources_;
|
||||
template <typename TAdaptedString>
|
||||
iterator findKey(TAdaptedString key) const;
|
||||
|
||||
iterator at(size_t index) const;
|
||||
|
||||
void appendOne(Slot<VariantData> slot);
|
||||
void appendPair(Slot<VariantData> key, Slot<VariantData> value);
|
||||
|
||||
void removeOne(iterator it);
|
||||
void removePair(iterator it);
|
||||
|
||||
VariantData* getVariant(SlotId id) const {
|
||||
ARDUINOJSON_ASSERT(resources_ != nullptr);
|
||||
return resources_->getVariant(id);
|
||||
}
|
||||
|
||||
void freeVariant(Slot<VariantData> slot) {
|
||||
ARDUINOJSON_ASSERT(resources_ != nullptr);
|
||||
resources_->freeVariant(slot);
|
||||
}
|
||||
|
||||
Slot<VariantData> allocVariant() {
|
||||
ARDUINOJSON_ASSERT(resources_ != nullptr);
|
||||
return resources_->allocVariant();
|
||||
}
|
||||
|
||||
Slot<VariantData> getPreviousSlot(VariantData*) const;
|
||||
|
||||
CollectionData* getCollectionData() const {
|
||||
ARDUINOJSON_ASSERT(data_ != nullptr);
|
||||
ARDUINOJSON_ASSERT(data_->isCollection());
|
||||
return &data_->content.asCollection;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -536,9 +570,25 @@ inline void VariantImpl::clear() {
|
||||
resources_->freeEightByte(data_->content.asSlotId);
|
||||
#endif
|
||||
|
||||
CollectionImpl(data_, resources_).clear();
|
||||
if (data_->type & VariantTypeBits::CollectionMask)
|
||||
empty();
|
||||
|
||||
data_->type = VariantType::Null;
|
||||
}
|
||||
|
||||
inline void VariantImpl::empty() {
|
||||
auto coll = getCollectionData();
|
||||
|
||||
auto next = coll->head;
|
||||
while (next != NULL_SLOT) {
|
||||
auto currId = next;
|
||||
auto slot = getVariant(next);
|
||||
next = slot->next;
|
||||
freeVariant({slot, currId});
|
||||
}
|
||||
|
||||
coll->head = NULL_SLOT;
|
||||
coll->tail = NULL_SLOT;
|
||||
}
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -120,14 +120,14 @@ class VariantRefBase : public VariantTag {
|
||||
// https://arduinojson.org/v7/api/jsonvariant/add/
|
||||
template <typename T>
|
||||
bool add(const T& value) const {
|
||||
return getOrCreateVariantImpl().addValue(value);
|
||||
return getOrCreateOrCreateArray().addValue(value);
|
||||
}
|
||||
|
||||
// Appends a value to the array.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/add/
|
||||
template <typename T, enable_if_t<!is_const<T>::value, int> = 0>
|
||||
bool add(T* value) const {
|
||||
return getOrCreateVariantImpl().addValue(value);
|
||||
return getOrCreateOrCreateArray().addValue(value);
|
||||
}
|
||||
|
||||
// Removes an element of the array.
|
||||
@ -279,6 +279,18 @@ class VariantRefBase : public VariantTag {
|
||||
return VariantImpl(getOrCreateData(), getResourceManager());
|
||||
}
|
||||
|
||||
VariantImpl getOrCreateOrCreateArray() const {
|
||||
auto data = getOrCreateData();
|
||||
return VariantImpl(data ? data->getOrCreateArray() : nullptr,
|
||||
getResourceManager());
|
||||
}
|
||||
|
||||
VariantImpl getOrCreateOrCreateObject() const {
|
||||
auto data = getOrCreateData();
|
||||
return VariantImpl(data ? data->getOrCreateObject() : nullptr,
|
||||
getResourceManager());
|
||||
}
|
||||
|
||||
FORCE_INLINE ArduinoJson::JsonVariant getVariant() const;
|
||||
|
||||
FORCE_INLINE ArduinoJson::JsonVariantConst getVariantConst() const {
|
||||
|
@ -69,7 +69,7 @@ inline void convertToJson(const VariantRefBase<TDerived>& src,
|
||||
template <typename TDerived>
|
||||
template <typename T, enable_if_t<is_same<T, JsonVariant>::value, int>>
|
||||
inline T VariantRefBase<TDerived>::add() const {
|
||||
return JsonVariant(getOrCreateVariantImpl().addElement(),
|
||||
return JsonVariant(getOrCreateOrCreateArray().addElement(),
|
||||
getResourceManager());
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user