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