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