mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-29 10:17:39 +02:00
Extract ArrayImpl
, CollectionImpl
, and ObjectImpl
This commit is contained in:
@ -8,59 +8,30 @@
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
class ArrayData : public CollectionData {
|
||||
class ArrayImpl : public CollectionImpl {
|
||||
public:
|
||||
VariantData* addElement(ResourceManager* resources);
|
||||
ArrayImpl() {}
|
||||
|
||||
static VariantData* addElement(ArrayData* array, ResourceManager* resources) {
|
||||
if (!array)
|
||||
return nullptr;
|
||||
return array->addElement(resources);
|
||||
}
|
||||
ArrayImpl(CollectionData* data, ResourceManager* resources)
|
||||
: CollectionImpl(data, resources) {}
|
||||
|
||||
VariantData* addElement();
|
||||
|
||||
template <typename T>
|
||||
bool addValue(const T& value, ResourceManager* resources);
|
||||
bool addValue(const T& value);
|
||||
|
||||
template <typename T>
|
||||
static bool addValue(ArrayData* array, const T& value,
|
||||
ResourceManager* resources) {
|
||||
if (!array)
|
||||
return false;
|
||||
return array->addValue(value, resources);
|
||||
}
|
||||
VariantData* getOrAddElement(size_t index);
|
||||
|
||||
VariantData* getOrAddElement(size_t index, ResourceManager* resources);
|
||||
VariantData* getElement(size_t index) const;
|
||||
|
||||
VariantData* getElement(size_t index, const ResourceManager* resources) const;
|
||||
void removeElement(size_t index);
|
||||
|
||||
static VariantData* getElement(const ArrayData* array, size_t index,
|
||||
const ResourceManager* resources) {
|
||||
if (!array)
|
||||
return nullptr;
|
||||
return array->getElement(index, resources);
|
||||
}
|
||||
|
||||
void removeElement(size_t index, ResourceManager* resources);
|
||||
|
||||
static void removeElement(ArrayData* array, size_t index,
|
||||
ResourceManager* resources) {
|
||||
if (!array)
|
||||
return;
|
||||
array->removeElement(index, resources);
|
||||
}
|
||||
|
||||
void remove(iterator it, ResourceManager* resources) {
|
||||
CollectionData::removeOne(it, resources);
|
||||
}
|
||||
|
||||
static void remove(ArrayData* array, iterator it,
|
||||
ResourceManager* resources) {
|
||||
if (array)
|
||||
return array->remove(it, resources);
|
||||
void remove(iterator it) {
|
||||
CollectionImpl::removeOne(it);
|
||||
}
|
||||
|
||||
private:
|
||||
iterator at(size_t index, const ResourceManager* resources) const;
|
||||
iterator at(size_t index) const;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -10,36 +10,37 @@
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
inline ArrayData::iterator ArrayData::at(
|
||||
size_t index, const ResourceManager* resources) const {
|
||||
auto it = createIterator(resources);
|
||||
inline ArrayImpl::iterator ArrayImpl::at(size_t index) const {
|
||||
auto it = createIterator();
|
||||
while (!it.done() && index) {
|
||||
it.next(resources);
|
||||
it.next(resources_);
|
||||
--index;
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
inline VariantData* ArrayData::addElement(ResourceManager* resources) {
|
||||
auto slot = resources->allocVariant();
|
||||
inline VariantData* ArrayImpl::addElement() {
|
||||
if (!data_)
|
||||
return nullptr;
|
||||
ARDUINOJSON_ASSERT(resources_ != nullptr);
|
||||
auto slot = resources_->allocVariant();
|
||||
if (!slot)
|
||||
return nullptr;
|
||||
CollectionData::appendOne(slot, resources);
|
||||
CollectionImpl::appendOne(slot);
|
||||
return slot.ptr();
|
||||
}
|
||||
|
||||
inline VariantData* ArrayData::getOrAddElement(size_t index,
|
||||
ResourceManager* resources) {
|
||||
auto it = createIterator(resources);
|
||||
inline VariantData* ArrayImpl::getOrAddElement(size_t index) {
|
||||
auto it = createIterator();
|
||||
while (!it.done() && index > 0) {
|
||||
it.next(resources);
|
||||
it.next(resources_);
|
||||
index--;
|
||||
}
|
||||
if (it.done())
|
||||
index++;
|
||||
VariantData* element = it.data();
|
||||
while (index > 0) {
|
||||
element = addElement(resources);
|
||||
element = addElement();
|
||||
if (!element)
|
||||
return nullptr;
|
||||
index--;
|
||||
@ -47,27 +48,28 @@ inline VariantData* ArrayData::getOrAddElement(size_t index,
|
||||
return element;
|
||||
}
|
||||
|
||||
inline VariantData* ArrayData::getElement(
|
||||
size_t index, const ResourceManager* resources) const {
|
||||
return at(index, resources).data();
|
||||
inline VariantData* ArrayImpl::getElement(size_t index) const {
|
||||
return at(index).data();
|
||||
}
|
||||
|
||||
inline void ArrayData::removeElement(size_t index, ResourceManager* resources) {
|
||||
remove(at(index, resources), resources);
|
||||
inline void ArrayImpl::removeElement(size_t index) {
|
||||
remove(at(index));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool ArrayData::addValue(const T& value, ResourceManager* resources) {
|
||||
ARDUINOJSON_ASSERT(resources != nullptr);
|
||||
auto slot = resources->allocVariant();
|
||||
inline bool ArrayImpl::addValue(const T& value) {
|
||||
if (!data_)
|
||||
return false;
|
||||
ARDUINOJSON_ASSERT(resources_ != nullptr);
|
||||
auto slot = resources_->allocVariant();
|
||||
if (!slot)
|
||||
return false;
|
||||
JsonVariant variant(slot.ptr(), resources);
|
||||
JsonVariant variant(slot.ptr(), resources_);
|
||||
if (!variant.set(value)) {
|
||||
resources->freeVariant(slot);
|
||||
resources_->freeVariant(slot);
|
||||
return false;
|
||||
}
|
||||
CollectionData::appendOne(slot, resources);
|
||||
CollectionImpl::appendOne(slot);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -55,9 +55,9 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantData* getData() const {
|
||||
return VariantData::getElement(
|
||||
VariantAttorney::getData(upstream_), index_,
|
||||
VariantAttorney::getResourceManager(upstream_));
|
||||
auto data = VariantAttorney::getData(upstream_);
|
||||
auto resources = VariantAttorney::getResourceManager(upstream_);
|
||||
return VariantData::asArray(data, resources).getElement(index_);
|
||||
}
|
||||
|
||||
VariantData* getOrCreateData() const {
|
||||
|
@ -20,24 +20,25 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
using iterator = JsonArrayIterator;
|
||||
|
||||
// Constructs an unbound reference.
|
||||
JsonArray() : data_(0), resources_(0) {}
|
||||
JsonArray() {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonArray(detail::VariantData* data, detail::ResourceManager* resources)
|
||||
: data_(data), resources_(resources) {}
|
||||
: impl_(detail::VariantData::asArray(data, resources)) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonArray(const detail::ArrayImpl& impl) : impl_(impl) {}
|
||||
|
||||
// Returns a JsonVariant pointing to the array.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/
|
||||
operator JsonVariant() {
|
||||
void* data = data_; // prevent warning cast-align
|
||||
return JsonVariant(reinterpret_cast<detail::VariantData*>(data),
|
||||
resources_);
|
||||
return JsonVariant(getData(), getResourceManager());
|
||||
}
|
||||
|
||||
// Returns a read-only reference to the array.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/
|
||||
operator JsonArrayConst() const {
|
||||
return JsonArrayConst(getData(), resources_);
|
||||
return JsonArrayConst(getData(), getResourceManager());
|
||||
}
|
||||
|
||||
// Appends a new (empty) element to the array.
|
||||
@ -55,15 +56,14 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
template <typename T, detail::enable_if_t<
|
||||
detail::is_same<T, JsonVariant>::value, int> = 0>
|
||||
JsonVariant add() const {
|
||||
return JsonVariant(detail::VariantData::addElement(data_, resources_),
|
||||
resources_);
|
||||
return JsonVariant(impl_.addElement(), impl_.getResourceManager());
|
||||
}
|
||||
|
||||
// Appends a value to the array.
|
||||
// https://arduinojson.org/v7/api/jsonarray/add/
|
||||
template <typename T>
|
||||
bool add(const T& value) const {
|
||||
return detail::VariantData::addValue(data_, value, resources_);
|
||||
return impl_.addValue(value);
|
||||
}
|
||||
|
||||
// Appends a value to the array.
|
||||
@ -71,16 +71,13 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
template <typename T,
|
||||
detail::enable_if_t<!detail::is_const<T>::value, int> = 0>
|
||||
bool add(T* value) const {
|
||||
return detail::VariantData::addValue(data_, value, resources_);
|
||||
return impl_.addValue(value);
|
||||
}
|
||||
|
||||
// Returns an iterator to the first element of the array.
|
||||
// https://arduinojson.org/v7/api/jsonarray/begin/
|
||||
iterator begin() const {
|
||||
auto array = detail::VariantData::asArray(data_);
|
||||
if (!array)
|
||||
return iterator();
|
||||
return iterator(array->createIterator(resources_), resources_);
|
||||
return iterator(impl_.createIterator(), impl_.getResourceManager());
|
||||
}
|
||||
|
||||
// Returns an iterator following the last element of the array.
|
||||
@ -92,7 +89,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// Copies an array.
|
||||
// https://arduinojson.org/v7/api/jsonarray/set/
|
||||
bool set(JsonArrayConst src) const {
|
||||
if (!data_)
|
||||
if (isNull())
|
||||
return false;
|
||||
|
||||
clear();
|
||||
@ -107,14 +104,13 @@ 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 {
|
||||
detail::ArrayData::remove(detail::VariantData::asArray(data_), it.iterator_,
|
||||
resources_);
|
||||
impl_.remove(it.iterator_);
|
||||
}
|
||||
|
||||
// Removes the element at the specified index.
|
||||
// https://arduinojson.org/v7/api/jsonarray/remove/
|
||||
void remove(size_t index) const {
|
||||
detail::VariantData::removeElement(data_, index, resources_);
|
||||
impl_.removeElement(index);
|
||||
}
|
||||
|
||||
// Removes the element at the specified index.
|
||||
@ -129,7 +125,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// Removes all the elements of the array.
|
||||
// https://arduinojson.org/v7/api/jsonarray/clear/
|
||||
void clear() const {
|
||||
detail::ArrayData::clear(detail::VariantData::asArray(data_), resources_);
|
||||
impl_.clear();
|
||||
}
|
||||
|
||||
// Gets or sets the element at the specified index.
|
||||
@ -152,13 +148,13 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
}
|
||||
|
||||
operator JsonVariantConst() const {
|
||||
return JsonVariantConst(data_, resources_);
|
||||
return JsonVariantConst(getData(), getResourceManager());
|
||||
}
|
||||
|
||||
// Returns true if the reference is unbound.
|
||||
// https://arduinojson.org/v7/api/jsonarray/isnull/
|
||||
bool isNull() const {
|
||||
return !data_ || !data_->isArray();
|
||||
return impl_.isNull();
|
||||
}
|
||||
|
||||
// Returns true if the reference is bound.
|
||||
@ -170,13 +166,13 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// Returns the depth (nesting level) of the array.
|
||||
// https://arduinojson.org/v7/api/jsonarray/nesting/
|
||||
size_t nesting() const {
|
||||
return detail::VariantData::nesting(data_, resources_);
|
||||
return impl_.nesting();
|
||||
}
|
||||
|
||||
// Returns the number of elements in the array.
|
||||
// https://arduinojson.org/v7/api/jsonarray/size/
|
||||
size_t size() const {
|
||||
return data_ ? data_->size(resources_) : 0;
|
||||
return impl_.size();
|
||||
}
|
||||
|
||||
// DEPRECATED: use add<JsonVariant>() instead
|
||||
@ -203,19 +199,18 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
|
||||
private:
|
||||
detail::ResourceManager* getResourceManager() const {
|
||||
return resources_;
|
||||
return impl_.getResourceManager();
|
||||
}
|
||||
|
||||
detail::VariantData* getData() const {
|
||||
return data_;
|
||||
return impl_.getData();
|
||||
}
|
||||
|
||||
detail::VariantData* getOrCreateData() const {
|
||||
return data_;
|
||||
return impl_.getData();
|
||||
}
|
||||
|
||||
detail::VariantData* data_;
|
||||
detail::ResourceManager* resources_;
|
||||
mutable detail::ArrayImpl impl_;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PUBLIC_NAMESPACE
|
||||
|
@ -24,10 +24,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
// Returns an iterator to the first element of the array.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/begin/
|
||||
iterator begin() const {
|
||||
auto array = detail::VariantData::asArray(data_);
|
||||
if (!array)
|
||||
return iterator();
|
||||
return iterator(array->createIterator(resources_), resources_);
|
||||
return iterator(impl_.createIterator(), impl_.getResourceManager());
|
||||
}
|
||||
|
||||
// Returns an iterator to the element following the last element of the array.
|
||||
@ -37,21 +34,22 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
}
|
||||
|
||||
// Creates an unbound reference.
|
||||
JsonArrayConst() : data_(0), resources_(0) {}
|
||||
JsonArrayConst() {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonArrayConst(const detail::VariantData* data,
|
||||
const detail::ResourceManager* resources)
|
||||
: data_(data), resources_(resources) {}
|
||||
JsonArrayConst(detail::VariantData* data, detail::ResourceManager* resources)
|
||||
: impl_(detail::VariantData::asArray(data, resources)) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonArrayConst(const detail::ArrayImpl& impl) : impl_(impl) {}
|
||||
|
||||
// Returns the element at the specified index.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/subscript/
|
||||
template <typename T,
|
||||
detail::enable_if_t<detail::is_integral<T>::value, int> = 0>
|
||||
JsonVariantConst operator[](T index) const {
|
||||
return JsonVariantConst(
|
||||
detail::VariantData::getElement(data_, size_t(index), resources_),
|
||||
resources_);
|
||||
return JsonVariantConst(impl_.getElement(size_t(index)),
|
||||
impl_.getResourceManager());
|
||||
}
|
||||
|
||||
// Returns the element at the specified index.
|
||||
@ -66,13 +64,13 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
}
|
||||
|
||||
operator JsonVariantConst() const {
|
||||
return JsonVariantConst(getData(), resources_);
|
||||
return JsonVariantConst(impl_.getData(), impl_.getResourceManager());
|
||||
}
|
||||
|
||||
// Returns true if the reference is unbound.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/isnull/
|
||||
bool isNull() const {
|
||||
return !data_ || !data_->isArray();
|
||||
return impl_.isNull();
|
||||
}
|
||||
|
||||
// Returns true if the reference is bound.
|
||||
@ -84,13 +82,13 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
// Returns the depth (nesting level) of the array.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/nesting/
|
||||
size_t nesting() const {
|
||||
return detail::VariantData::nesting(getData(), resources_);
|
||||
return impl_.nesting();
|
||||
}
|
||||
|
||||
// Returns the number of elements in the array.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/size/
|
||||
size_t size() const {
|
||||
return data_ ? data_->size(resources_) : 0;
|
||||
return impl_.size();
|
||||
}
|
||||
|
||||
// DEPRECATED: always returns zero
|
||||
@ -101,11 +99,10 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
|
||||
private:
|
||||
const detail::VariantData* getData() const {
|
||||
return data_;
|
||||
return impl_.getData();
|
||||
}
|
||||
|
||||
const detail::VariantData* data_;
|
||||
const detail::ResourceManager* resources_;
|
||||
detail::ArrayImpl impl_;
|
||||
};
|
||||
|
||||
// Compares the content of two arrays.
|
||||
|
@ -30,7 +30,7 @@ class JsonArrayIterator {
|
||||
|
||||
public:
|
||||
JsonArrayIterator() {}
|
||||
explicit JsonArrayIterator(detail::ArrayData::iterator iterator,
|
||||
explicit JsonArrayIterator(detail::ArrayImpl::iterator iterator,
|
||||
detail::ResourceManager* resources)
|
||||
: iterator_(iterator), resources_(resources) {}
|
||||
|
||||
@ -55,7 +55,7 @@ class JsonArrayIterator {
|
||||
}
|
||||
|
||||
private:
|
||||
detail::ArrayData::iterator iterator_;
|
||||
detail::ArrayImpl::iterator iterator_;
|
||||
detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
@ -64,8 +64,8 @@ class JsonArrayConstIterator {
|
||||
|
||||
public:
|
||||
JsonArrayConstIterator() {}
|
||||
explicit JsonArrayConstIterator(detail::ArrayData::iterator iterator,
|
||||
const detail::ResourceManager* resources)
|
||||
explicit JsonArrayConstIterator(detail::ArrayImpl::iterator iterator,
|
||||
detail::ResourceManager* resources)
|
||||
: iterator_(iterator), resources_(resources) {}
|
||||
|
||||
JsonVariantConst operator*() const {
|
||||
@ -89,8 +89,8 @@ class JsonArrayConstIterator {
|
||||
}
|
||||
|
||||
private:
|
||||
detail::ArrayData::iterator iterator_;
|
||||
const detail::ResourceManager* resources_;
|
||||
mutable detail::ArrayImpl::iterator iterator_;
|
||||
mutable detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PUBLIC_NAMESPACE
|
||||
|
@ -16,7 +16,7 @@ class VariantData;
|
||||
class ResourceManager;
|
||||
|
||||
class CollectionIterator {
|
||||
friend class CollectionData;
|
||||
friend class CollectionImpl;
|
||||
|
||||
public:
|
||||
CollectionIterator() : slot_(nullptr), currentId_(NULL_SLOT) {}
|
||||
@ -51,11 +51,11 @@ class CollectionIterator {
|
||||
}
|
||||
|
||||
VariantData* data() {
|
||||
return reinterpret_cast<VariantData*>(slot_);
|
||||
return slot_;
|
||||
}
|
||||
|
||||
const VariantData* data() const {
|
||||
return reinterpret_cast<const VariantData*>(slot_);
|
||||
return slot_;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -65,58 +65,68 @@ class CollectionIterator {
|
||||
SlotId currentId_, nextId_;
|
||||
};
|
||||
|
||||
class CollectionData {
|
||||
SlotId head_ = NULL_SLOT;
|
||||
SlotId tail_ = NULL_SLOT;
|
||||
struct CollectionData {
|
||||
SlotId head = NULL_SLOT;
|
||||
SlotId tail = NULL_SLOT;
|
||||
|
||||
public:
|
||||
// Placement new
|
||||
static void* operator new(size_t, void* p) noexcept {
|
||||
return p;
|
||||
}
|
||||
|
||||
static void operator delete(void*, void*) noexcept {}
|
||||
};
|
||||
|
||||
class CollectionImpl {
|
||||
protected:
|
||||
CollectionData* data_;
|
||||
ResourceManager* resources_;
|
||||
|
||||
public:
|
||||
using iterator = CollectionIterator;
|
||||
|
||||
iterator createIterator(const ResourceManager* resources) const;
|
||||
CollectionImpl() : data_(nullptr), resources_(nullptr) {}
|
||||
|
||||
size_t size(const ResourceManager*) const;
|
||||
size_t nesting(const ResourceManager*) const;
|
||||
CollectionImpl(CollectionData* data, ResourceManager* resources)
|
||||
: data_(data), resources_(resources) {}
|
||||
|
||||
void clear(ResourceManager* resources);
|
||||
|
||||
static void clear(CollectionData* collection, ResourceManager* resources) {
|
||||
if (!collection)
|
||||
return;
|
||||
collection->clear(resources);
|
||||
explicit operator bool() const {
|
||||
return data_ != nullptr;
|
||||
}
|
||||
|
||||
bool isNull() const {
|
||||
return data_ == nullptr;
|
||||
}
|
||||
|
||||
VariantData* getData() const {
|
||||
void* data = data_; // prevent warning cast-align
|
||||
return reinterpret_cast<VariantData*>(data);
|
||||
}
|
||||
|
||||
ResourceManager* getResourceManager() const {
|
||||
return resources_;
|
||||
}
|
||||
|
||||
iterator createIterator() const;
|
||||
|
||||
size_t size() const;
|
||||
size_t nesting() const;
|
||||
|
||||
void clear();
|
||||
|
||||
SlotId head() const {
|
||||
return head_;
|
||||
return data_->head;
|
||||
}
|
||||
|
||||
protected:
|
||||
void appendOne(Slot<VariantData> slot, const ResourceManager* resources);
|
||||
void appendPair(Slot<VariantData> key, Slot<VariantData> value,
|
||||
const ResourceManager* resources);
|
||||
void appendOne(Slot<VariantData> slot);
|
||||
void appendPair(Slot<VariantData> key, Slot<VariantData> value);
|
||||
|
||||
void removeOne(iterator it, ResourceManager* resources);
|
||||
void removePair(iterator it, ResourceManager* resources);
|
||||
void removeOne(iterator it);
|
||||
void removePair(iterator it);
|
||||
|
||||
private:
|
||||
Slot<VariantData> getPreviousSlot(VariantData*, const ResourceManager*) const;
|
||||
Slot<VariantData> getPreviousSlot(VariantData*) const;
|
||||
};
|
||||
|
||||
inline const VariantData* collectionToVariant(
|
||||
const CollectionData* collection) {
|
||||
const void* data = collection; // prevent warning cast-align
|
||||
return reinterpret_cast<const VariantData*>(data);
|
||||
}
|
||||
|
||||
inline VariantData* collectionToVariant(CollectionData* collection) {
|
||||
void* data = collection; // prevent warning cast-align
|
||||
return reinterpret_cast<VariantData*>(data);
|
||||
}
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -25,57 +25,64 @@ inline void CollectionIterator::next(const ResourceManager* resources) {
|
||||
nextId_ = slot_->next();
|
||||
}
|
||||
|
||||
inline CollectionData::iterator CollectionData::createIterator(
|
||||
const ResourceManager* resources) const {
|
||||
return iterator(resources->getVariant(head_), head_);
|
||||
inline CollectionImpl::iterator CollectionImpl::createIterator() const {
|
||||
if (!data_)
|
||||
return iterator();
|
||||
return iterator(resources_->getVariant(data_->head), data_->head);
|
||||
}
|
||||
|
||||
inline void CollectionData::appendOne(Slot<VariantData> slot,
|
||||
const ResourceManager* resources) {
|
||||
if (tail_ != NULL_SLOT) {
|
||||
auto tail = resources->getVariant(tail_);
|
||||
inline void CollectionImpl::appendOne(Slot<VariantData> slot) {
|
||||
ARDUINOJSON_ASSERT(data_ != nullptr);
|
||||
ARDUINOJSON_ASSERT(resources_ != nullptr);
|
||||
|
||||
if (data_->tail != NULL_SLOT) {
|
||||
auto tail = resources_->getVariant(data_->tail);
|
||||
tail->setNext(slot.id());
|
||||
tail_ = slot.id();
|
||||
data_->tail = slot.id();
|
||||
} else {
|
||||
head_ = slot.id();
|
||||
tail_ = slot.id();
|
||||
data_->head = slot.id();
|
||||
data_->tail = slot.id();
|
||||
}
|
||||
}
|
||||
|
||||
inline void CollectionData::appendPair(Slot<VariantData> key,
|
||||
Slot<VariantData> value,
|
||||
const ResourceManager* resources) {
|
||||
inline void CollectionImpl::appendPair(Slot<VariantData> key,
|
||||
Slot<VariantData> value) {
|
||||
ARDUINOJSON_ASSERT(data_ != nullptr);
|
||||
ARDUINOJSON_ASSERT(resources_ != nullptr);
|
||||
|
||||
key->setNext(value.id());
|
||||
|
||||
if (tail_ != NULL_SLOT) {
|
||||
auto tail = resources->getVariant(tail_);
|
||||
if (data_->tail != NULL_SLOT) {
|
||||
auto tail = resources_->getVariant(data_->tail);
|
||||
tail->setNext(key.id());
|
||||
tail_ = value.id();
|
||||
data_->tail = value.id();
|
||||
} else {
|
||||
head_ = key.id();
|
||||
tail_ = value.id();
|
||||
data_->head = key.id();
|
||||
data_->tail = value.id();
|
||||
}
|
||||
}
|
||||
|
||||
inline void CollectionData::clear(ResourceManager* resources) {
|
||||
auto next = head_;
|
||||
inline void CollectionImpl::clear() {
|
||||
if (!data_)
|
||||
return;
|
||||
auto next = data_->head;
|
||||
while (next != NULL_SLOT) {
|
||||
auto currId = next;
|
||||
auto slot = resources->getVariant(next);
|
||||
auto slot = resources_->getVariant(next);
|
||||
next = slot->next();
|
||||
resources->freeVariant({slot, currId});
|
||||
resources_->freeVariant({slot, currId});
|
||||
}
|
||||
|
||||
head_ = NULL_SLOT;
|
||||
tail_ = NULL_SLOT;
|
||||
data_->head = NULL_SLOT;
|
||||
data_->tail = NULL_SLOT;
|
||||
}
|
||||
|
||||
inline Slot<VariantData> CollectionData::getPreviousSlot(
|
||||
VariantData* target, const ResourceManager* resources) const {
|
||||
inline Slot<VariantData> CollectionImpl::getPreviousSlot(
|
||||
VariantData* target) const {
|
||||
auto prev = Slot<VariantData>();
|
||||
auto currentId = head_;
|
||||
auto currentId = data_->head;
|
||||
while (currentId != NULL_SLOT) {
|
||||
auto currentSlot = resources->getVariant(currentId);
|
||||
auto currentSlot = resources_->getVariant(currentId);
|
||||
if (currentSlot == target)
|
||||
break;
|
||||
prev = Slot<VariantData>(currentSlot, currentId);
|
||||
@ -84,52 +91,53 @@ inline Slot<VariantData> CollectionData::getPreviousSlot(
|
||||
return prev;
|
||||
}
|
||||
|
||||
inline void CollectionData::removeOne(iterator it, ResourceManager* resources) {
|
||||
inline void CollectionImpl::removeOne(iterator it) {
|
||||
if (it.done())
|
||||
return;
|
||||
auto curr = it.slot_;
|
||||
auto prev = getPreviousSlot(curr, resources);
|
||||
auto prev = getPreviousSlot(curr);
|
||||
auto next = curr->next();
|
||||
if (prev)
|
||||
prev->setNext(next);
|
||||
else
|
||||
head_ = next;
|
||||
data_->head = next;
|
||||
if (next == NULL_SLOT)
|
||||
tail_ = prev.id();
|
||||
resources->freeVariant({it.slot_, it.currentId_});
|
||||
data_->tail = prev.id();
|
||||
resources_->freeVariant({it.slot_, it.currentId_});
|
||||
}
|
||||
|
||||
inline void CollectionData::removePair(ObjectData::iterator it,
|
||||
ResourceManager* resources) {
|
||||
inline void CollectionImpl::removePair(ObjectImpl::iterator it) {
|
||||
if (it.done())
|
||||
return;
|
||||
|
||||
auto keySlot = it.slot_;
|
||||
|
||||
auto valueId = it.nextId_;
|
||||
auto valueSlot = resources->getVariant(valueId);
|
||||
auto valueSlot = resources_->getVariant(valueId);
|
||||
|
||||
// remove value slot
|
||||
keySlot->setNext(valueSlot->next());
|
||||
resources->freeVariant({valueSlot, valueId});
|
||||
resources_->freeVariant({valueSlot, valueId});
|
||||
|
||||
// remove key slot
|
||||
removeOne(it, resources);
|
||||
removeOne(it);
|
||||
}
|
||||
|
||||
inline size_t CollectionData::nesting(const ResourceManager* resources) const {
|
||||
inline size_t CollectionImpl::nesting() const {
|
||||
if (!data_)
|
||||
return 0;
|
||||
size_t maxChildNesting = 0;
|
||||
for (auto it = createIterator(resources); !it.done(); it.next(resources)) {
|
||||
size_t childNesting = it->nesting(resources);
|
||||
for (auto it = createIterator(); !it.done(); it.next(resources_)) {
|
||||
size_t childNesting = it->nesting(resources_);
|
||||
if (childNesting > maxChildNesting)
|
||||
maxChildNesting = childNesting;
|
||||
}
|
||||
return maxChildNesting + 1;
|
||||
}
|
||||
|
||||
inline size_t CollectionData::size(const ResourceManager* resources) const {
|
||||
inline size_t CollectionImpl::size() const {
|
||||
size_t count = 0;
|
||||
for (auto it = createIterator(resources); !it.done(); it.next(resources))
|
||||
for (auto it = createIterator(); !it.done(); it.next(resources_))
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
@ -415,8 +415,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
|
||||
return &data_;
|
||||
}
|
||||
|
||||
detail::ResourceManager resources_;
|
||||
detail::VariantData data_;
|
||||
mutable detail::ResourceManager resources_;
|
||||
mutable detail::VariantData data_;
|
||||
};
|
||||
|
||||
inline void convertToJson(const JsonDocument& src, JsonVariant dst) {
|
||||
|
@ -71,13 +71,14 @@ class JsonDeserializer {
|
||||
switch (current()) {
|
||||
case '[':
|
||||
if (filter.allowArray())
|
||||
return parseArray(variant.toArray(), filter, nestingLimit);
|
||||
return parseArray(variant.toArray(resources_), filter, nestingLimit);
|
||||
else
|
||||
return skipArray(nestingLimit);
|
||||
|
||||
case '{':
|
||||
if (filter.allowObject())
|
||||
return parseObject(variant.toObject(), filter, nestingLimit);
|
||||
return parseObject(variant.toObject(resources_), filter,
|
||||
nestingLimit);
|
||||
else
|
||||
return skipObject(nestingLimit);
|
||||
|
||||
@ -146,7 +147,7 @@ class JsonDeserializer {
|
||||
|
||||
template <typename TFilter>
|
||||
DeserializationError::Code parseArray(
|
||||
ArrayData& array, TFilter filter,
|
||||
ArrayImpl array, TFilter filter,
|
||||
DeserializationOption::NestingLimit nestingLimit) {
|
||||
DeserializationError::Code err;
|
||||
|
||||
@ -172,7 +173,7 @@ class JsonDeserializer {
|
||||
for (;;) {
|
||||
if (elementFilter.allow()) {
|
||||
// Allocate slot in array
|
||||
VariantData* value = array.addElement(resources_);
|
||||
VariantData* value = array.addElement();
|
||||
if (!value)
|
||||
return DeserializationError::NoMemory;
|
||||
|
||||
@ -232,7 +233,7 @@ class JsonDeserializer {
|
||||
|
||||
template <typename TFilter>
|
||||
DeserializationError::Code parseObject(
|
||||
ObjectData& object, TFilter filter,
|
||||
ObjectImpl object, TFilter filter,
|
||||
DeserializationOption::NestingLimit nestingLimit) {
|
||||
DeserializationError::Code err;
|
||||
|
||||
@ -273,9 +274,9 @@ class JsonDeserializer {
|
||||
TFilter memberFilter = filter[key];
|
||||
|
||||
if (memberFilter.allow()) {
|
||||
auto member = object.getMember(adaptString(key), resources_);
|
||||
auto member = object.getMember(adaptString(key));
|
||||
if (!member) {
|
||||
auto keyVariant = object.addPair(&member, resources_);
|
||||
auto keyVariant = object.addPair(&member);
|
||||
if (!keyVariant)
|
||||
return DeserializationError::NoMemory;
|
||||
|
||||
|
@ -16,10 +16,10 @@ class JsonSerializer : public VariantDataVisitor<size_t> {
|
||||
public:
|
||||
static const bool producesText = true;
|
||||
|
||||
JsonSerializer(TWriter writer, const ResourceManager* resources)
|
||||
JsonSerializer(TWriter writer, ResourceManager* resources)
|
||||
: formatter_(writer), resources_(resources) {}
|
||||
|
||||
size_t visit(const ArrayData& array) {
|
||||
size_t visit(const ArrayImpl& array) {
|
||||
write('[');
|
||||
|
||||
auto slotId = array.head();
|
||||
@ -39,7 +39,7 @@ class JsonSerializer : public VariantDataVisitor<size_t> {
|
||||
return bytesWritten();
|
||||
}
|
||||
|
||||
size_t visit(const ObjectData& object) {
|
||||
size_t visit(const ObjectImpl& object) {
|
||||
write('{');
|
||||
|
||||
auto slotId = object.head();
|
||||
@ -120,7 +120,7 @@ class JsonSerializer : public VariantDataVisitor<size_t> {
|
||||
TextFormatter<TWriter> formatter_;
|
||||
|
||||
protected:
|
||||
const ResourceManager* resources_;
|
||||
ResourceManager* resources_;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -16,11 +16,11 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
||||
using base = JsonSerializer<TWriter>;
|
||||
|
||||
public:
|
||||
PrettyJsonSerializer(TWriter writer, const ResourceManager* resources)
|
||||
PrettyJsonSerializer(TWriter writer, ResourceManager* resources)
|
||||
: base(writer, resources), nesting_(0) {}
|
||||
|
||||
size_t visit(const ArrayData& array) {
|
||||
auto it = array.createIterator(base::resources_);
|
||||
size_t visit(const ArrayImpl& array) {
|
||||
auto it = array.createIterator();
|
||||
if (!it.done()) {
|
||||
base::write("[\r\n");
|
||||
nesting_++;
|
||||
@ -40,8 +40,8 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
||||
return this->bytesWritten();
|
||||
}
|
||||
|
||||
size_t visit(const ObjectData& object) {
|
||||
auto it = object.createIterator(base::resources_);
|
||||
size_t visit(const ObjectImpl& object) {
|
||||
auto it = object.createIterator();
|
||||
if (!it.done()) {
|
||||
base::write("{\r\n");
|
||||
nesting_++;
|
||||
|
@ -349,12 +349,10 @@ class MsgPackDeserializer {
|
||||
|
||||
bool allowArray = filter.allowArray();
|
||||
|
||||
ArrayData* array;
|
||||
ArrayImpl array;
|
||||
if (allowArray) {
|
||||
ARDUINOJSON_ASSERT(variant != 0);
|
||||
array = &variant->toArray();
|
||||
} else {
|
||||
array = 0;
|
||||
array = variant->toArray(resources_);
|
||||
}
|
||||
|
||||
TFilter elementFilter = filter[0U];
|
||||
@ -363,8 +361,7 @@ class MsgPackDeserializer {
|
||||
VariantData* value;
|
||||
|
||||
if (elementFilter.allow()) {
|
||||
ARDUINOJSON_ASSERT(array != 0);
|
||||
value = array->addElement(resources_);
|
||||
value = array.addElement();
|
||||
if (!value)
|
||||
return DeserializationError::NoMemory;
|
||||
} else {
|
||||
@ -388,12 +385,10 @@ class MsgPackDeserializer {
|
||||
if (nestingLimit.reached())
|
||||
return DeserializationError::TooDeep;
|
||||
|
||||
ObjectData* object;
|
||||
ObjectImpl object;
|
||||
if (filter.allowObject()) {
|
||||
ARDUINOJSON_ASSERT(variant != 0);
|
||||
object = &variant->toObject();
|
||||
} else {
|
||||
object = 0;
|
||||
object = variant->toObject(resources_);
|
||||
}
|
||||
|
||||
for (; n; --n) {
|
||||
@ -406,9 +401,7 @@ class MsgPackDeserializer {
|
||||
VariantData* member = 0;
|
||||
|
||||
if (memberFilter.allow()) {
|
||||
ARDUINOJSON_ASSERT(object != 0);
|
||||
|
||||
auto keyVariant = object->addPair(&member, resources_);
|
||||
auto keyVariant = object.addPair(&member);
|
||||
if (!keyVariant)
|
||||
return DeserializationError::NoMemory;
|
||||
|
||||
|
@ -19,7 +19,7 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
|
||||
public:
|
||||
static const bool producesText = false;
|
||||
|
||||
MsgPackSerializer(TWriter writer, const ResourceManager* resources)
|
||||
MsgPackSerializer(TWriter writer, ResourceManager* resources)
|
||||
: writer_(writer), resources_(resources) {}
|
||||
|
||||
template <typename T>
|
||||
@ -47,8 +47,8 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
|
||||
return bytesWritten();
|
||||
}
|
||||
|
||||
size_t visit(const ArrayData& array) {
|
||||
size_t n = array.size(resources_);
|
||||
size_t visit(const ArrayImpl& array) {
|
||||
size_t n = array.size();
|
||||
if (n < 0x10) {
|
||||
writeByte(uint8_t(0x90 + n));
|
||||
} else if (n < 0x10000) {
|
||||
@ -69,8 +69,8 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
|
||||
return bytesWritten();
|
||||
}
|
||||
|
||||
size_t visit(const ObjectData& object) {
|
||||
size_t n = object.size(resources_);
|
||||
size_t visit(const ObjectImpl& object) {
|
||||
size_t n = object.size();
|
||||
if (n < 0x10) {
|
||||
writeByte(uint8_t(0x80 + n));
|
||||
} else if (n < 0x10000) {
|
||||
@ -209,7 +209,7 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
|
||||
}
|
||||
|
||||
CountingDecorator<TWriter> writer_;
|
||||
const ResourceManager* resources_;
|
||||
ResourceManager* resources_;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -20,30 +20,31 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
using iterator = JsonObjectIterator;
|
||||
|
||||
// Creates an unbound reference.
|
||||
JsonObject() : data_(0), resources_(0) {}
|
||||
JsonObject() {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonObject(const detail::ObjectImpl& impl) : impl_(impl) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonObject(detail::VariantData* data, detail::ResourceManager* resource)
|
||||
: data_(data), resources_(resource) {}
|
||||
: impl_(detail::VariantData::asObject(data, resource)) {}
|
||||
|
||||
operator JsonVariant() const {
|
||||
void* data = data_; // prevent warning cast-align
|
||||
return JsonVariant(reinterpret_cast<detail::VariantData*>(data),
|
||||
resources_);
|
||||
return JsonVariant(getData(), getResourceManager());
|
||||
}
|
||||
|
||||
operator JsonObjectConst() const {
|
||||
return JsonObjectConst(data_, resources_);
|
||||
return JsonObjectConst(getData(), getResourceManager());
|
||||
}
|
||||
|
||||
operator JsonVariantConst() const {
|
||||
return JsonVariantConst(data_, resources_);
|
||||
return JsonVariantConst(getData(), getResourceManager());
|
||||
}
|
||||
|
||||
// Returns true if the reference is unbound.
|
||||
// https://arduinojson.org/v7/api/jsonobject/isnull/
|
||||
bool isNull() const {
|
||||
return !data_ || !data_->isObject();
|
||||
return impl_.isNull();
|
||||
}
|
||||
|
||||
// Returns true if the reference is bound.
|
||||
@ -55,22 +56,19 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// Returns the depth (nesting level) of the object.
|
||||
// https://arduinojson.org/v7/api/jsonobject/nesting/
|
||||
size_t nesting() const {
|
||||
return detail::VariantData::nesting(data_, resources_);
|
||||
return impl_.nesting();
|
||||
}
|
||||
|
||||
// Returns the number of members in the object.
|
||||
// https://arduinojson.org/v7/api/jsonobject/size/
|
||||
size_t size() const {
|
||||
return data_ ? data_->size(resources_) : 0;
|
||||
return impl_.size();
|
||||
}
|
||||
|
||||
// Returns an iterator to the first key-value pair of the object.
|
||||
// https://arduinojson.org/v7/api/jsonobject/begin/
|
||||
iterator begin() const {
|
||||
auto obj = detail::VariantData::asObject(data_);
|
||||
if (!obj)
|
||||
return iterator();
|
||||
return iterator(obj->createIterator(resources_), resources_);
|
||||
return iterator(impl_.createIterator(), impl_.getResourceManager());
|
||||
}
|
||||
|
||||
// Returns an iterator following the last key-value pair of the object.
|
||||
@ -82,13 +80,13 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// Removes all the members of the object.
|
||||
// https://arduinojson.org/v7/api/jsonobject/clear/
|
||||
void clear() const {
|
||||
detail::ObjectData::clear(detail::VariantData::asObject(data_), resources_);
|
||||
impl_.clear();
|
||||
}
|
||||
|
||||
// Copies an object.
|
||||
// https://arduinojson.org/v7/api/jsonobject/set/
|
||||
bool set(JsonObjectConst src) {
|
||||
if (!data_ || !src.data_)
|
||||
if (isNull() || src.isNull())
|
||||
return false;
|
||||
|
||||
clear();
|
||||
@ -132,8 +130,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 {
|
||||
detail::ObjectData::remove(detail::VariantData::asObject(data_),
|
||||
it.iterator_, resources_);
|
||||
impl_.remove(it.iterator_);
|
||||
}
|
||||
|
||||
// Removes the member with the specified key.
|
||||
@ -141,8 +138,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
template <typename TString,
|
||||
detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
|
||||
void remove(const TString& key) const {
|
||||
detail::VariantData::removeMember(data_, detail::adaptString(key),
|
||||
resources_);
|
||||
impl_.removeMember(detail::adaptString(key));
|
||||
}
|
||||
|
||||
// Removes the member with the specified key.
|
||||
@ -158,8 +154,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// https://arduinojson.org/v7/api/jsonobject/remove/
|
||||
template <typename TChar>
|
||||
FORCE_INLINE void remove(TChar* key) const {
|
||||
detail::VariantData::removeMember(data_, detail::adaptString(key),
|
||||
resources_);
|
||||
impl_.removeMember(detail::adaptString(key));
|
||||
}
|
||||
|
||||
// DEPRECATED: use obj[key].is<T>() instead
|
||||
@ -168,8 +163,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
|
||||
ARDUINOJSON_DEPRECATED("use obj[key].is<T>() instead")
|
||||
bool containsKey(const TString& key) const {
|
||||
return detail::VariantData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
return impl_.getMember(detail::adaptString(key)) != 0;
|
||||
}
|
||||
|
||||
// DEPRECATED: use obj["key"].is<T>() instead
|
||||
@ -180,8 +174,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
int> = 0>
|
||||
ARDUINOJSON_DEPRECATED("use obj[\"key\"].is<T>() instead")
|
||||
bool containsKey(TChar* key) const {
|
||||
return detail::VariantData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
return impl_.getMember(detail::adaptString(key)) != 0;
|
||||
}
|
||||
|
||||
// DEPRECATED: use obj[key].is<T>() instead
|
||||
@ -229,19 +222,18 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
|
||||
private:
|
||||
detail::ResourceManager* getResourceManager() const {
|
||||
return resources_;
|
||||
return impl_.getResourceManager();
|
||||
}
|
||||
|
||||
detail::VariantData* getData() const {
|
||||
return data_;
|
||||
return impl_.getData();
|
||||
}
|
||||
|
||||
detail::VariantData* getOrCreateData() const {
|
||||
return data_;
|
||||
return impl_.getData();
|
||||
}
|
||||
|
||||
detail::VariantData* data_;
|
||||
detail::ResourceManager* resources_;
|
||||
mutable detail::ObjectImpl impl_;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PUBLIC_NAMESPACE
|
||||
|
@ -19,21 +19,23 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
using iterator = JsonObjectConstIterator;
|
||||
|
||||
// Creates an unbound reference.
|
||||
JsonObjectConst() : data_(0), resources_(0) {}
|
||||
JsonObjectConst() {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonObjectConst(const detail::VariantData* data,
|
||||
const detail::ResourceManager* resources)
|
||||
: data_(data), resources_(resources) {}
|
||||
JsonObjectConst(detail::VariantData* data, detail::ResourceManager* resources)
|
||||
: impl_(detail::VariantData::asObject(data, resources)) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonObjectConst(const detail::ObjectImpl& impl) : impl_(impl) {}
|
||||
|
||||
operator JsonVariantConst() const {
|
||||
return JsonVariantConst(getData(), resources_);
|
||||
return JsonVariantConst(impl_.getData(), impl_.getResourceManager());
|
||||
}
|
||||
|
||||
// Returns true if the reference is unbound.
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/isnull/
|
||||
bool isNull() const {
|
||||
return !data_ || !data_->isObject();
|
||||
return impl_.isNull();
|
||||
}
|
||||
|
||||
// Returns true if the reference is bound.
|
||||
@ -45,22 +47,19 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
// Returns the depth (nesting level) of the object.
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/nesting/
|
||||
size_t nesting() const {
|
||||
return detail::VariantData::nesting(getData(), resources_);
|
||||
return impl_.nesting();
|
||||
}
|
||||
|
||||
// Returns the number of members in the object.
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/size/
|
||||
size_t size() const {
|
||||
return data_ ? data_->size(resources_) : 0;
|
||||
return impl_.size();
|
||||
}
|
||||
|
||||
// Returns an iterator to the first key-value pair of the object.
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/begin/
|
||||
iterator begin() const {
|
||||
auto obj = detail::VariantData::asObject(data_);
|
||||
if (!obj)
|
||||
return iterator();
|
||||
return iterator(obj->createIterator(resources_), resources_);
|
||||
return iterator(impl_.createIterator(), impl_.getResourceManager());
|
||||
}
|
||||
|
||||
// Returns an iterator following the last key-value pair of the object.
|
||||
@ -75,8 +74,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
|
||||
ARDUINOJSON_DEPRECATED("use obj[key].is<T>() instead")
|
||||
bool containsKey(const TString& key) const {
|
||||
return detail::VariantData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
return impl_.getMember(detail::adaptString(key)) != 0;
|
||||
}
|
||||
|
||||
// DEPRECATED: use obj["key"].is<T>() instead
|
||||
@ -84,8 +82,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
template <typename TChar>
|
||||
ARDUINOJSON_DEPRECATED("use obj[\"key\"].is<T>() instead")
|
||||
bool containsKey(TChar* key) const {
|
||||
return detail::VariantData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
return impl_.getMember(detail::adaptString(key)) != 0;
|
||||
}
|
||||
|
||||
// DEPRECATED: use obj[key].is<T>() instead
|
||||
@ -102,9 +99,8 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
template <typename TString,
|
||||
detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
|
||||
JsonVariantConst operator[](const TString& key) const {
|
||||
return JsonVariantConst(detail::VariantData::getMember(
|
||||
data_, detail::adaptString(key), resources_),
|
||||
resources_);
|
||||
return JsonVariantConst(impl_.getMember(detail::adaptString(key)),
|
||||
impl_.getResourceManager());
|
||||
}
|
||||
|
||||
// Gets the member with specified key.
|
||||
@ -114,9 +110,8 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
!detail::is_const<TChar>::value,
|
||||
int> = 0>
|
||||
JsonVariantConst operator[](TChar* key) const {
|
||||
return JsonVariantConst(detail::VariantData::getMember(
|
||||
data_, detail::adaptString(key), resources_),
|
||||
resources_);
|
||||
return JsonVariantConst(impl_.getMember(detail::adaptString(key)),
|
||||
impl_.getResourceManager());
|
||||
}
|
||||
|
||||
// Gets the member with specified key.
|
||||
@ -138,11 +133,10 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
|
||||
private:
|
||||
const detail::VariantData* getData() const {
|
||||
return data_;
|
||||
return impl_.getData();
|
||||
}
|
||||
|
||||
const detail::VariantData* data_;
|
||||
const detail::ResourceManager* resources_;
|
||||
detail::ObjectImpl impl_;
|
||||
};
|
||||
|
||||
inline bool operator==(JsonObjectConst lhs, JsonObjectConst rhs) {
|
||||
|
@ -14,7 +14,7 @@ class JsonObjectIterator {
|
||||
public:
|
||||
JsonObjectIterator() {}
|
||||
|
||||
explicit JsonObjectIterator(detail::ObjectData::iterator iterator,
|
||||
explicit JsonObjectIterator(detail::ObjectImpl::iterator iterator,
|
||||
detail::ResourceManager* resources)
|
||||
: iterator_(iterator), resources_(resources) {}
|
||||
|
||||
@ -40,7 +40,7 @@ class JsonObjectIterator {
|
||||
}
|
||||
|
||||
private:
|
||||
detail::ObjectData::iterator iterator_;
|
||||
detail::ObjectImpl::iterator iterator_;
|
||||
detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
@ -50,8 +50,8 @@ class JsonObjectConstIterator {
|
||||
public:
|
||||
JsonObjectConstIterator() {}
|
||||
|
||||
explicit JsonObjectConstIterator(detail::ObjectData::iterator iterator,
|
||||
const detail::ResourceManager* resources)
|
||||
explicit JsonObjectConstIterator(detail::ObjectImpl::iterator iterator,
|
||||
detail::ResourceManager* resources)
|
||||
: iterator_(iterator), resources_(resources) {}
|
||||
|
||||
JsonPairConst operator*() const {
|
||||
@ -76,8 +76,8 @@ class JsonObjectConstIterator {
|
||||
}
|
||||
|
||||
private:
|
||||
detail::ObjectData::iterator iterator_;
|
||||
const detail::ResourceManager* resources_;
|
||||
detail::ObjectImpl::iterator iterator_;
|
||||
detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PUBLIC_NAMESPACE
|
||||
|
@ -15,7 +15,7 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
|
||||
class JsonPair {
|
||||
public:
|
||||
// INTERNAL USE ONLY
|
||||
JsonPair(detail::ObjectData::iterator iterator,
|
||||
JsonPair(detail::ObjectImpl::iterator iterator,
|
||||
detail::ResourceManager* resources) {
|
||||
if (!iterator.done()) {
|
||||
key_ = iterator->asString(resources);
|
||||
@ -43,8 +43,8 @@ class JsonPair {
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/begin_end/
|
||||
class JsonPairConst {
|
||||
public:
|
||||
JsonPairConst(detail::ObjectData::iterator iterator,
|
||||
const detail::ResourceManager* resources) {
|
||||
JsonPairConst(detail::ObjectImpl::iterator iterator,
|
||||
detail::ResourceManager* resources) {
|
||||
if (!iterator.done()) {
|
||||
key_ = iterator->asString(resources);
|
||||
iterator.next(resources);
|
||||
|
@ -8,63 +8,38 @@
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
class ObjectData : public CollectionData {
|
||||
class ObjectImpl : public CollectionImpl {
|
||||
public:
|
||||
template <typename TAdaptedString>
|
||||
VariantData* addMember(TAdaptedString key, ResourceManager* resources);
|
||||
ObjectImpl() {}
|
||||
|
||||
VariantData* addPair(VariantData** value, ResourceManager* resources);
|
||||
ObjectImpl(CollectionData* data, ResourceManager* resources)
|
||||
: CollectionImpl(data, resources) {}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData* getOrAddMember(TAdaptedString key, ResourceManager* resources);
|
||||
VariantData* addMember(TAdaptedString key);
|
||||
|
||||
VariantData* addPair(VariantData** value);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData* getMember(TAdaptedString key,
|
||||
const ResourceManager* resources) const;
|
||||
VariantData* getOrAddMember(TAdaptedString key);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
static VariantData* getMember(const ObjectData* object, TAdaptedString key,
|
||||
const ResourceManager* resources) {
|
||||
if (!object)
|
||||
return nullptr;
|
||||
return object->getMember(key, resources);
|
||||
VariantData* getMember(TAdaptedString key) const;
|
||||
|
||||
template <typename TAdaptedString>
|
||||
void removeMember(TAdaptedString key);
|
||||
|
||||
void remove(iterator it) {
|
||||
CollectionImpl::removePair(it);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
void removeMember(TAdaptedString key, ResourceManager* resources);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
static void removeMember(ObjectData* obj, TAdaptedString key,
|
||||
ResourceManager* resources) {
|
||||
if (!obj)
|
||||
return;
|
||||
obj->removeMember(key, resources);
|
||||
}
|
||||
|
||||
void remove(iterator it, ResourceManager* resources) {
|
||||
CollectionData::removePair(it, resources);
|
||||
}
|
||||
|
||||
static void remove(ObjectData* obj, ObjectData::iterator it,
|
||||
ResourceManager* resources) {
|
||||
if (!obj)
|
||||
return;
|
||||
obj->remove(it, resources);
|
||||
}
|
||||
|
||||
size_t size(const ResourceManager* resources) const {
|
||||
return CollectionData::size(resources) / 2;
|
||||
}
|
||||
|
||||
static size_t size(const ObjectData* obj, const ResourceManager* resources) {
|
||||
if (!obj)
|
||||
return 0;
|
||||
return obj->size(resources);
|
||||
size_t size() const {
|
||||
return CollectionImpl::size() / 2;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename TAdaptedString>
|
||||
iterator findKey(TAdaptedString key, const ResourceManager* resources) const;
|
||||
iterator findKey(TAdaptedString key) const;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -11,32 +11,29 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData* ObjectData::getMember(
|
||||
TAdaptedString key, const ResourceManager* resources) const {
|
||||
auto it = findKey(key, resources);
|
||||
inline VariantData* ObjectImpl::getMember(TAdaptedString key) const {
|
||||
auto it = findKey(key);
|
||||
if (it.done())
|
||||
return nullptr;
|
||||
it.next(resources);
|
||||
it.next(resources_);
|
||||
return it.data();
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData* ObjectData::getOrAddMember(TAdaptedString key,
|
||||
ResourceManager* resources) {
|
||||
auto data = getMember(key, resources);
|
||||
VariantData* ObjectImpl::getOrAddMember(TAdaptedString key) {
|
||||
auto data = getMember(key);
|
||||
if (data)
|
||||
return data;
|
||||
return addMember(key, resources);
|
||||
return addMember(key);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline ObjectData::iterator ObjectData::findKey(
|
||||
TAdaptedString key, const ResourceManager* resources) const {
|
||||
inline ObjectImpl::iterator ObjectImpl::findKey(TAdaptedString key) const {
|
||||
if (key.isNull())
|
||||
return iterator();
|
||||
bool isKey = true;
|
||||
for (auto it = createIterator(resources); !it.done(); it.next(resources)) {
|
||||
if (isKey && stringEquals(key, adaptString(it->asString(resources))))
|
||||
for (auto it = createIterator(); !it.done(); it.next(resources_)) {
|
||||
if (isKey && stringEquals(key, adaptString(it->asString(resources_))))
|
||||
return it;
|
||||
isKey = !isKey;
|
||||
}
|
||||
@ -44,42 +41,47 @@ inline ObjectData::iterator ObjectData::findKey(
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline void ObjectData::removeMember(TAdaptedString key,
|
||||
ResourceManager* resources) {
|
||||
remove(findKey(key, resources), resources);
|
||||
inline void ObjectImpl::removeMember(TAdaptedString key) {
|
||||
remove(findKey(key));
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData* ObjectData::addMember(TAdaptedString key,
|
||||
ResourceManager* resources) {
|
||||
auto keySlot = resources->allocVariant();
|
||||
inline VariantData* ObjectImpl::addMember(TAdaptedString key) {
|
||||
if (!data_)
|
||||
return nullptr;
|
||||
ARDUINOJSON_ASSERT(resources_ != nullptr);
|
||||
|
||||
auto keySlot = resources_->allocVariant();
|
||||
if (!keySlot)
|
||||
return nullptr;
|
||||
|
||||
auto valueSlot = resources->allocVariant();
|
||||
auto valueSlot = resources_->allocVariant();
|
||||
if (!valueSlot)
|
||||
return nullptr;
|
||||
|
||||
if (!keySlot->setString(key, resources))
|
||||
if (!keySlot->setString(key, resources_))
|
||||
return nullptr;
|
||||
|
||||
CollectionData::appendPair(keySlot, valueSlot, resources);
|
||||
CollectionImpl::appendPair(keySlot, valueSlot);
|
||||
|
||||
return valueSlot.ptr();
|
||||
}
|
||||
|
||||
inline VariantData* ObjectData::addPair(VariantData** value,
|
||||
ResourceManager* resources) {
|
||||
auto keySlot = resources->allocVariant();
|
||||
inline VariantData* ObjectImpl::addPair(VariantData** value) {
|
||||
if (!data_)
|
||||
return nullptr;
|
||||
ARDUINOJSON_ASSERT(resources_ != nullptr);
|
||||
|
||||
auto keySlot = resources_->allocVariant();
|
||||
if (!keySlot)
|
||||
return nullptr;
|
||||
|
||||
auto valueSlot = resources->allocVariant();
|
||||
auto valueSlot = resources_->allocVariant();
|
||||
if (!valueSlot)
|
||||
return nullptr;
|
||||
*value = valueSlot.ptr();
|
||||
|
||||
CollectionData::appendPair(keySlot, valueSlot, resources);
|
||||
CollectionImpl::appendPair(keySlot, valueSlot);
|
||||
|
||||
return keySlot.ptr();
|
||||
}
|
||||
|
@ -38,8 +38,8 @@ class JsonVariantConst : public detail::VariantTag,
|
||||
JsonVariantConst() : data_(nullptr), resources_(nullptr) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
explicit JsonVariantConst(const detail::VariantData* data,
|
||||
const detail::ResourceManager* resources)
|
||||
explicit JsonVariantConst(detail::VariantData* data,
|
||||
detail::ResourceManager* resources)
|
||||
: data_(data), resources_(resources) {}
|
||||
|
||||
// Returns true if the value is null or the reference is unbound.
|
||||
@ -181,17 +181,17 @@ class JsonVariantConst : public detail::VariantTag,
|
||||
}
|
||||
|
||||
protected:
|
||||
const detail::VariantData* getData() const {
|
||||
detail::VariantData* getData() const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
const detail::ResourceManager* getResourceManager() const {
|
||||
detail::ResourceManager* getResourceManager() const {
|
||||
return resources_;
|
||||
}
|
||||
|
||||
private:
|
||||
const detail::VariantData* data_;
|
||||
const detail::ResourceManager* resources_;
|
||||
mutable detail::VariantData* data_;
|
||||
mutable detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PUBLIC_NAMESPACE
|
||||
|
@ -26,17 +26,14 @@ class VisitorAdapter {
|
||||
public:
|
||||
using result_type = typename TVisitor::result_type;
|
||||
|
||||
VisitorAdapter(TVisitor& visitor, const ResourceManager* resources)
|
||||
: visitor_(&visitor), resources_(resources) {}
|
||||
VisitorAdapter(TVisitor& visitor) : visitor_(&visitor) {}
|
||||
|
||||
result_type visit(const ArrayData& value) {
|
||||
return visitor_->visit(
|
||||
JsonArrayConst(collectionToVariant(&value), resources_));
|
||||
result_type visit(const ArrayImpl& array) {
|
||||
return visitor_->visit(JsonArrayConst(array));
|
||||
}
|
||||
|
||||
result_type visit(const ObjectData& value) {
|
||||
return visitor_->visit(
|
||||
JsonObjectConst(collectionToVariant(&value), resources_));
|
||||
result_type visit(const ObjectImpl& object) {
|
||||
return visitor_->visit(JsonObjectConst(object));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -46,7 +43,6 @@ class VisitorAdapter {
|
||||
|
||||
private:
|
||||
TVisitor* visitor_;
|
||||
const ResourceManager* resources_;
|
||||
};
|
||||
|
||||
template <typename TVisitor>
|
||||
@ -56,7 +52,7 @@ typename TVisitor::result_type accept(JsonVariantConst variant,
|
||||
if (!data)
|
||||
return visit.visit(nullptr);
|
||||
auto resources = VariantAttorney::getResourceManager(variant);
|
||||
VisitorAdapter<TVisitor> adapter(visit, resources);
|
||||
VisitorAdapter<TVisitor> adapter(visit);
|
||||
return data->accept(adapter, resources);
|
||||
}
|
||||
|
||||
|
@ -57,8 +57,6 @@ union VariantContent {
|
||||
uint32_t asUint32;
|
||||
int32_t asInt32;
|
||||
SlotId asSlotId;
|
||||
ArrayData asArray;
|
||||
ObjectData asObject;
|
||||
CollectionData asCollection;
|
||||
struct StringNode* asOwnedString;
|
||||
char asTinyString[tinyStringMaxLength + 1];
|
||||
|
@ -51,8 +51,8 @@ class VariantData {
|
||||
}
|
||||
|
||||
template <typename TVisitor>
|
||||
typename TVisitor::result_type accept(
|
||||
TVisitor& visit, const ResourceManager* resources) const {
|
||||
typename TVisitor::result_type accept(TVisitor& visit,
|
||||
ResourceManager* resources) {
|
||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||
auto eightByteValue = getEightByte(resources);
|
||||
#else
|
||||
@ -68,10 +68,10 @@ class VariantData {
|
||||
#endif
|
||||
|
||||
case VariantType::Array:
|
||||
return visit.visit(content_.asArray);
|
||||
return visit.visit(asArray(resources));
|
||||
|
||||
case VariantType::Object:
|
||||
return visit.visit(content_.asObject);
|
||||
return visit.visit(asObject(resources));
|
||||
|
||||
case VariantType::TinyString:
|
||||
return visit.visit(JsonString(content_.asTinyString));
|
||||
@ -110,8 +110,8 @@ class VariantData {
|
||||
}
|
||||
|
||||
template <typename TVisitor>
|
||||
static typename TVisitor::result_type accept(const VariantData* var,
|
||||
const ResourceManager* resources,
|
||||
static typename TVisitor::result_type accept(VariantData* var,
|
||||
ResourceManager* resources,
|
||||
TVisitor& visit) {
|
||||
if (var != 0)
|
||||
return var->accept(visit, resources);
|
||||
@ -120,8 +120,8 @@ class VariantData {
|
||||
}
|
||||
|
||||
VariantData* addElement(ResourceManager* resources) {
|
||||
auto array = isNull() ? &toArray() : asArray();
|
||||
return detail::ArrayData::addElement(array, resources);
|
||||
auto array = isNull() ? toArray(resources) : asArray(resources);
|
||||
return array.addElement();
|
||||
}
|
||||
|
||||
static VariantData* addElement(VariantData* var, ResourceManager* resources) {
|
||||
@ -132,8 +132,8 @@ class VariantData {
|
||||
|
||||
template <typename T>
|
||||
bool addValue(const T& value, ResourceManager* resources) {
|
||||
auto array = isNull() ? &toArray() : asArray();
|
||||
return detail::ArrayData::addValue(array, value, resources);
|
||||
auto array = isNull() ? toArray(resources) : asArray(resources);
|
||||
return array.addValue(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -174,28 +174,19 @@ class VariantData {
|
||||
}
|
||||
}
|
||||
|
||||
ArrayData* asArray() {
|
||||
return isArray() ? &content_.asArray : 0;
|
||||
ArrayImpl asArray(ResourceManager* resources) {
|
||||
return ArrayImpl(isArray() ? &content_.asCollection : nullptr, resources);
|
||||
}
|
||||
|
||||
const ArrayData* asArray() const {
|
||||
return const_cast<VariantData*>(this)->asArray();
|
||||
static ArrayImpl asArray(VariantData* var, ResourceManager* resources) {
|
||||
return ArrayImpl(
|
||||
var && var->isArray() ? &var->content_.asCollection : nullptr,
|
||||
resources);
|
||||
}
|
||||
|
||||
static ArrayData* asArray(VariantData* var) {
|
||||
return var ? var->asArray() : 0;
|
||||
}
|
||||
|
||||
static const ArrayData* asArray(const VariantData* var) {
|
||||
return var ? var->asArray() : 0;
|
||||
}
|
||||
|
||||
CollectionData* asCollection() {
|
||||
return isCollection() ? &content_.asCollection : 0;
|
||||
}
|
||||
|
||||
const CollectionData* asCollection() const {
|
||||
return const_cast<VariantData*>(this)->asCollection();
|
||||
CollectionImpl asCollection(ResourceManager* resources) {
|
||||
return CollectionImpl(isCollection() ? &content_.asCollection : nullptr,
|
||||
resources);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -288,20 +279,14 @@ class VariantData {
|
||||
return parseNumber<T>(str);
|
||||
}
|
||||
|
||||
ObjectData* asObject() {
|
||||
return isObject() ? &content_.asObject : 0;
|
||||
ObjectImpl asObject(ResourceManager* resources) {
|
||||
return ObjectImpl(isObject() ? &content_.asCollection : nullptr, resources);
|
||||
}
|
||||
|
||||
const ObjectData* asObject() const {
|
||||
return const_cast<VariantData*>(this)->asObject();
|
||||
}
|
||||
|
||||
static ObjectData* asObject(VariantData* var) {
|
||||
return var ? var->asObject() : 0;
|
||||
}
|
||||
|
||||
static const ObjectData* asObject(const VariantData* var) {
|
||||
return var ? var->asObject() : 0;
|
||||
static ObjectImpl asObject(VariantData* var, ResourceManager* resources) {
|
||||
return ObjectImpl(
|
||||
var && var->isObject() ? &var->content_.asCollection : nullptr,
|
||||
resources);
|
||||
}
|
||||
|
||||
JsonString asRawString() const {
|
||||
@ -334,45 +319,41 @@ class VariantData {
|
||||
const EightByteValue* getEightByte(const ResourceManager* resources) const;
|
||||
#endif
|
||||
|
||||
VariantData* getElement(size_t index,
|
||||
const ResourceManager* resources) const {
|
||||
return ArrayData::getElement(asArray(), index, resources);
|
||||
VariantData* getElement(size_t index, ResourceManager* resources) {
|
||||
return asArray(resources).getElement(index);
|
||||
}
|
||||
|
||||
static VariantData* getElement(const VariantData* var, size_t index,
|
||||
const ResourceManager* resources) {
|
||||
return var != 0 ? var->getElement(index, resources) : 0;
|
||||
static VariantData* getElement(VariantData* var, size_t index,
|
||||
ResourceManager* resources) {
|
||||
if (!var)
|
||||
return nullptr;
|
||||
return var->asArray(resources).getElement(index);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData* getMember(TAdaptedString key,
|
||||
const ResourceManager* resources) const {
|
||||
return ObjectData::getMember(asObject(), key, resources);
|
||||
VariantData* getMember(TAdaptedString key, ResourceManager* resources) {
|
||||
return asObject(resources).getMember(key);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
static VariantData* getMember(const VariantData* var, TAdaptedString key,
|
||||
const ResourceManager* resources) {
|
||||
static VariantData* getMember(VariantData* var, TAdaptedString key,
|
||||
ResourceManager* resources) {
|
||||
if (!var)
|
||||
return 0;
|
||||
return var->getMember(key, resources);
|
||||
}
|
||||
|
||||
VariantData* getOrAddElement(size_t index, ResourceManager* resources) {
|
||||
auto array = isNull() ? &toArray() : asArray();
|
||||
if (!array)
|
||||
return nullptr;
|
||||
return array->getOrAddElement(index, resources);
|
||||
auto array = isNull() ? toArray(resources) : asArray(resources);
|
||||
return array.getOrAddElement(index);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData* getOrAddMember(TAdaptedString key, ResourceManager* resources) {
|
||||
if (key.isNull())
|
||||
return nullptr;
|
||||
auto obj = isNull() ? &toObject() : asObject();
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
return obj->getOrAddMember(key, resources);
|
||||
auto obj = isNull() ? toObject(resources) : asObject(resources);
|
||||
return obj.getOrAddMember(key);
|
||||
}
|
||||
|
||||
bool isArray() const {
|
||||
@ -438,23 +419,18 @@ class VariantData {
|
||||
type_ == VariantType::TinyString;
|
||||
}
|
||||
|
||||
size_t nesting(const ResourceManager* resources) const {
|
||||
auto collection = asCollection();
|
||||
if (collection)
|
||||
return collection->nesting(resources);
|
||||
else
|
||||
return 0;
|
||||
size_t nesting(ResourceManager* resources) {
|
||||
return asCollection(resources).nesting();
|
||||
}
|
||||
|
||||
static size_t nesting(const VariantData* var,
|
||||
const ResourceManager* resources) {
|
||||
static size_t nesting(VariantData* var, ResourceManager* resources) {
|
||||
if (!var)
|
||||
return 0;
|
||||
return var->nesting(resources);
|
||||
}
|
||||
|
||||
void removeElement(size_t index, ResourceManager* resources) {
|
||||
ArrayData::removeElement(asArray(), index, resources);
|
||||
asArray(resources).removeElement(index);
|
||||
}
|
||||
|
||||
static void removeElement(VariantData* var, size_t index,
|
||||
@ -466,7 +442,7 @@ class VariantData {
|
||||
|
||||
template <typename TAdaptedString>
|
||||
void removeMember(TAdaptedString key, ResourceManager* resources) {
|
||||
ObjectData::removeMember(asObject(), key, resources);
|
||||
asObject(resources).removeMember(key);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
@ -563,48 +539,44 @@ class VariantData {
|
||||
content_.asOwnedString = s;
|
||||
}
|
||||
|
||||
size_t size(const ResourceManager* resources) const {
|
||||
size_t size(ResourceManager* resources) {
|
||||
if (isObject())
|
||||
return content_.asObject.size(resources);
|
||||
return asObject(resources).size();
|
||||
|
||||
if (isArray())
|
||||
return content_.asArray.size(resources);
|
||||
return asArray(resources).size();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t size(const VariantData* var, const ResourceManager* resources) {
|
||||
static size_t size(VariantData* var, ResourceManager* resources) {
|
||||
return var != 0 ? var->size(resources) : 0;
|
||||
}
|
||||
|
||||
ArrayData& toArray() {
|
||||
ArrayImpl toArray(ResourceManager* resources) {
|
||||
ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first
|
||||
type_ = VariantType::Array;
|
||||
new (&content_.asArray) ArrayData();
|
||||
return content_.asArray;
|
||||
return ArrayImpl(new (&content_.asCollection) CollectionData(), resources);
|
||||
}
|
||||
|
||||
static VariantData* toArray(VariantData* var, ResourceManager* resources) {
|
||||
static ArrayImpl toArray(VariantData* var, ResourceManager* resources) {
|
||||
if (!var)
|
||||
return 0;
|
||||
return ArrayImpl(nullptr, resources);
|
||||
var->clear(resources);
|
||||
var->toArray();
|
||||
return var;
|
||||
return var->toArray(resources);
|
||||
}
|
||||
|
||||
ObjectData& toObject() {
|
||||
ObjectImpl toObject(ResourceManager* resources) {
|
||||
ARDUINOJSON_ASSERT(type_ == VariantType::Null); // must call clear() first
|
||||
type_ = VariantType::Object;
|
||||
new (&content_.asObject) ObjectData();
|
||||
return content_.asObject;
|
||||
return ObjectImpl(new (&content_.asCollection) CollectionData(), resources);
|
||||
}
|
||||
|
||||
static VariantData* toObject(VariantData* var, ResourceManager* resources) {
|
||||
static ObjectImpl toObject(VariantData* var, ResourceManager* resources) {
|
||||
if (!var)
|
||||
return 0;
|
||||
return ObjectImpl();
|
||||
var->clear(resources);
|
||||
var->toObject();
|
||||
return var;
|
||||
return var->toObject(resources);
|
||||
}
|
||||
|
||||
VariantType type() const {
|
||||
|
@ -66,9 +66,7 @@ inline void VariantData::clear(ResourceManager* resources) {
|
||||
resources->freeEightByte(content_.asSlotId);
|
||||
#endif
|
||||
|
||||
auto collection = asCollection();
|
||||
if (collection)
|
||||
collection->clear(resources);
|
||||
asCollection(resources).clear();
|
||||
|
||||
type_ = VariantType::Null;
|
||||
}
|
||||
|
@ -151,16 +151,14 @@ template <typename TDerived>
|
||||
template <typename T, enable_if_t<is_same<T, JsonArray>::value, int>>
|
||||
inline JsonArray VariantRefBase<TDerived>::to() const {
|
||||
return JsonArray(
|
||||
VariantData::toArray(getOrCreateData(), getResourceManager()),
|
||||
getResourceManager());
|
||||
VariantData::toArray(getOrCreateData(), getResourceManager()));
|
||||
}
|
||||
|
||||
template <typename TDerived>
|
||||
template <typename T, enable_if_t<is_same<T, JsonObject>::value, int>>
|
||||
JsonObject VariantRefBase<TDerived>::to() const {
|
||||
return JsonObject(
|
||||
VariantData::toObject(getOrCreateData(), getResourceManager()),
|
||||
getResourceManager());
|
||||
VariantData::toObject(getOrCreateData(), getResourceManager()));
|
||||
}
|
||||
|
||||
template <typename TDerived>
|
||||
|
Reference in New Issue
Block a user