mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-21 06:22:23 +02:00
Extract ArrayData
from CollectionData
This commit is contained in:
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include "ArduinoJson/Document/JsonDocument.hpp"
|
#include "ArduinoJson/Document/JsonDocument.hpp"
|
||||||
|
|
||||||
|
#include "ArduinoJson/Array/ArrayImpl.hpp"
|
||||||
#include "ArduinoJson/Array/ElementProxy.hpp"
|
#include "ArduinoJson/Array/ElementProxy.hpp"
|
||||||
#include "ArduinoJson/Array/JsonArrayImpl.hpp"
|
#include "ArduinoJson/Array/JsonArrayImpl.hpp"
|
||||||
#include "ArduinoJson/Array/Utilities.hpp"
|
#include "ArduinoJson/Array/Utilities.hpp"
|
||||||
|
65
src/ArduinoJson/Array/ArrayData.hpp
Normal file
65
src/ArduinoJson/Array/ArrayData.hpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright © 2014-2023, Benoit BLANCHON
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||||
|
|
||||||
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
|
class ArrayData : public CollectionData {
|
||||||
|
public:
|
||||||
|
VariantData* addElement(ResourceManager* resources);
|
||||||
|
|
||||||
|
static VariantData* addElement(ArrayData* array, ResourceManager* resources) {
|
||||||
|
if (!array)
|
||||||
|
return nullptr;
|
||||||
|
return array->addElement(resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
VariantData* getOrAddElement(size_t index, ResourceManager* resources);
|
||||||
|
|
||||||
|
VariantData* getElement(size_t index) const;
|
||||||
|
|
||||||
|
static VariantData* getElement(const ArrayData* array, size_t index) {
|
||||||
|
if (!array)
|
||||||
|
return nullptr;
|
||||||
|
return array->getElement(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeElement(size_t index, ResourceManager* resources);
|
||||||
|
|
||||||
|
static void removeElement(ArrayData* array, size_t index,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
if (!array)
|
||||||
|
return;
|
||||||
|
array->removeElement(index, resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equals(const ArrayData&) const;
|
||||||
|
|
||||||
|
static bool equals(const ArrayData* lhs, const ArrayData* rhs) {
|
||||||
|
if (lhs == rhs)
|
||||||
|
return true;
|
||||||
|
if (!lhs || !rhs)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return lhs->equals(*rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool copyFrom(const ArrayData& src, ResourceManager* resources);
|
||||||
|
|
||||||
|
static bool copy(ArrayData* dst, const ArrayData* src,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
if (!dst || !src)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return dst->copyFrom(*src, resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
VariantSlot* getSlot(size_t index) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
81
src/ArduinoJson/Array/ArrayImpl.hpp
Normal file
81
src/ArduinoJson/Array/ArrayImpl.hpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright © 2014-2023, Benoit BLANCHON
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Array/ArrayData.hpp>
|
||||||
|
#include <ArduinoJson/Variant/VariantCompare.hpp>
|
||||||
|
|
||||||
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
|
inline VariantData* ArrayData::addElement(ResourceManager* resources) {
|
||||||
|
auto slot = resources->allocVariant();
|
||||||
|
if (!slot)
|
||||||
|
return nullptr;
|
||||||
|
addSlot(slot);
|
||||||
|
return slot->data();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool ArrayData::copyFrom(const ArrayData& src,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
clear(resources);
|
||||||
|
|
||||||
|
for (VariantSlot* s = src.head(); s; s = s->next()) {
|
||||||
|
auto var = addElement(resources);
|
||||||
|
if (!variantCopyFrom(var, s->data(), resources))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool ArrayData::equals(const ArrayData& other) const {
|
||||||
|
auto a = head();
|
||||||
|
auto b = other.head();
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (!a && !b) // both ended
|
||||||
|
return true;
|
||||||
|
if (!a || !b) // one ended
|
||||||
|
return false;
|
||||||
|
if (compare(a->data(), b->data()) != COMPARE_RESULT_EQUAL)
|
||||||
|
return false;
|
||||||
|
a = a->next();
|
||||||
|
b = b->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline VariantData* ArrayData::getOrAddElement(size_t index,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
VariantSlot* slot = head();
|
||||||
|
while (slot && index > 0) {
|
||||||
|
slot = slot->next();
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
if (!slot)
|
||||||
|
index++;
|
||||||
|
while (index > 0) {
|
||||||
|
slot = resources->allocVariant();
|
||||||
|
if (!slot)
|
||||||
|
return nullptr;
|
||||||
|
addSlot(slot);
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
return slot->data();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline VariantData* ArrayData::getElement(size_t index) const {
|
||||||
|
return slotData(getSlot(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline VariantSlot* ArrayData::getSlot(size_t index) const {
|
||||||
|
if (!head())
|
||||||
|
return 0;
|
||||||
|
return head()->next(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void ArrayData::removeElement(size_t index, ResourceManager* resources) {
|
||||||
|
removeSlot(getSlot(index), resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
@ -24,7 +24,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
|||||||
FORCE_INLINE JsonArray() : data_(0), resources_(0) {}
|
FORCE_INLINE JsonArray() : data_(0), resources_(0) {}
|
||||||
|
|
||||||
// INTERNAL USE ONLY
|
// INTERNAL USE ONLY
|
||||||
FORCE_INLINE JsonArray(detail::CollectionData* data,
|
FORCE_INLINE JsonArray(detail::ArrayData* data,
|
||||||
detail::ResourceManager* resources)
|
detail::ResourceManager* resources)
|
||||||
: data_(data), resources_(resources) {}
|
: data_(data), resources_(resources) {}
|
||||||
|
|
||||||
@ -46,7 +46,8 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
|||||||
// Returns a reference to the new element.
|
// Returns a reference to the new element.
|
||||||
// https://arduinojson.org/v6/api/jsonarray/add/
|
// https://arduinojson.org/v6/api/jsonarray/add/
|
||||||
JsonVariant add() const {
|
JsonVariant add() const {
|
||||||
return JsonVariant(collectionAddElement(data_, resources_), resources_);
|
return JsonVariant(detail::ArrayData::addElement(data_, resources_),
|
||||||
|
resources_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Appends a value to the array.
|
// Appends a value to the array.
|
||||||
@ -80,12 +81,12 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
|||||||
// Copies an array.
|
// Copies an array.
|
||||||
// https://arduinojson.org/v6/api/jsonarray/set/
|
// https://arduinojson.org/v6/api/jsonarray/set/
|
||||||
FORCE_INLINE bool set(JsonArrayConst src) const {
|
FORCE_INLINE bool set(JsonArrayConst src) const {
|
||||||
return collectionCopy(data_, src.data_, resources_);
|
return detail::ArrayData::copy(data_, src.data_, resources_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compares the content of two arrays.
|
// Compares the content of two arrays.
|
||||||
FORCE_INLINE bool operator==(JsonArray rhs) const {
|
FORCE_INLINE bool operator==(JsonArray rhs) const {
|
||||||
return arrayEquals(data_, rhs.data_);
|
return detail::ArrayData::equals(data_, rhs.data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes the element at the specified iterator.
|
// Removes the element at the specified iterator.
|
||||||
@ -99,7 +100,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
|||||||
// ⚠️ Doesn't release the memory associated with the removed element.
|
// ⚠️ Doesn't release the memory associated with the removed element.
|
||||||
// https://arduinojson.org/v6/api/jsonarray/remove/
|
// https://arduinojson.org/v6/api/jsonarray/remove/
|
||||||
FORCE_INLINE void remove(size_t index) const {
|
FORCE_INLINE void remove(size_t index) const {
|
||||||
collectionRemoveElement(data_, index, resources_);
|
detail::ArrayData::removeElement(data_, index, resources_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes all the elements of the array.
|
// Removes all the elements of the array.
|
||||||
@ -172,7 +173,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
|||||||
return collectionToVariant(data_);
|
return collectionToVariant(data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::CollectionData* data_;
|
detail::ArrayData* data_;
|
||||||
detail::ResourceManager* resources_;
|
detail::ResourceManager* resources_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -40,19 +40,18 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
|||||||
FORCE_INLINE JsonArrayConst() : data_(0) {}
|
FORCE_INLINE JsonArrayConst() : data_(0) {}
|
||||||
|
|
||||||
// INTERNAL USE ONLY
|
// INTERNAL USE ONLY
|
||||||
FORCE_INLINE JsonArrayConst(const detail::CollectionData* data)
|
FORCE_INLINE JsonArrayConst(const detail::ArrayData* data) : data_(data) {}
|
||||||
: data_(data) {}
|
|
||||||
|
|
||||||
// Compares the content of two arrays.
|
// Compares the content of two arrays.
|
||||||
// Returns true if the two arrays are equal.
|
// Returns true if the two arrays are equal.
|
||||||
FORCE_INLINE bool operator==(JsonArrayConst rhs) const {
|
FORCE_INLINE bool operator==(JsonArrayConst rhs) const {
|
||||||
return arrayEquals(data_, rhs.data_);
|
return detail::ArrayData::equals(data_, rhs.data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the element at the specified index.
|
// Returns the element at the specified index.
|
||||||
// https://arduinojson.org/v6/api/jsonarrayconst/subscript/
|
// https://arduinojson.org/v6/api/jsonarrayconst/subscript/
|
||||||
FORCE_INLINE JsonVariantConst operator[](size_t index) const {
|
FORCE_INLINE JsonVariantConst operator[](size_t index) const {
|
||||||
return JsonVariantConst(collectionGetElement(data_, index));
|
return JsonVariantConst(detail::ArrayData::getElement(data_, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
operator JsonVariantConst() const {
|
operator JsonVariantConst() const {
|
||||||
@ -94,7 +93,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
|||||||
return collectionToVariant(data_);
|
return collectionToVariant(data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
const detail::CollectionData* data_;
|
const detail::ArrayData* data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -29,8 +29,6 @@ class CollectionData {
|
|||||||
size_t memoryUsage() const;
|
size_t memoryUsage() const;
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
|
|
||||||
VariantData* addElement(ResourceManager* resources);
|
|
||||||
|
|
||||||
VariantData* addMember(StringNode* key, ResourceManager* resources);
|
VariantData* addMember(StringNode* key, ResourceManager* resources);
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
@ -39,10 +37,6 @@ class CollectionData {
|
|||||||
void clear(ResourceManager* resources);
|
void clear(ResourceManager* resources);
|
||||||
bool copyFrom(const CollectionData& src, ResourceManager* resources);
|
bool copyFrom(const CollectionData& src, ResourceManager* resources);
|
||||||
|
|
||||||
VariantData* getOrAddElement(size_t index, ResourceManager* resources);
|
|
||||||
|
|
||||||
VariantData* getElement(size_t index) const;
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
VariantData* getOrAddMember(TAdaptedString key, ResourceManager* resources);
|
VariantData* getOrAddMember(TAdaptedString key, ResourceManager* resources);
|
||||||
|
|
||||||
@ -51,8 +45,6 @@ class CollectionData {
|
|||||||
|
|
||||||
void removeSlot(VariantSlot* slot, ResourceManager* resources);
|
void removeSlot(VariantSlot* slot, ResourceManager* resources);
|
||||||
|
|
||||||
void removeElement(size_t index, ResourceManager* resources);
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
void removeMember(TAdaptedString key, ResourceManager* resources);
|
void removeMember(TAdaptedString key, ResourceManager* resources);
|
||||||
|
|
||||||
@ -62,15 +54,14 @@ class CollectionData {
|
|||||||
|
|
||||||
void movePointers(ptrdiff_t variantDistance);
|
void movePointers(ptrdiff_t variantDistance);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void addSlot(VariantSlot*);
|
void addSlot(VariantSlot*);
|
||||||
|
|
||||||
VariantSlot* getPreviousSlot(VariantSlot*) const;
|
|
||||||
|
|
||||||
VariantSlot* getSlot(size_t index) const;
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
VariantSlot* getSlot(TAdaptedString key) const;
|
VariantSlot* getSlot(TAdaptedString key) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VariantSlot* getPreviousSlot(VariantSlot*) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const VariantData* collectionToVariant(
|
inline const VariantData* collectionToVariant(
|
||||||
@ -84,10 +75,6 @@ inline VariantData* collectionToVariant(CollectionData* collection) {
|
|||||||
return reinterpret_cast<VariantData*>(data);
|
return reinterpret_cast<VariantData*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool arrayEquals(const detail::CollectionData& lhs,
|
|
||||||
const detail::CollectionData& rhs);
|
|
||||||
bool arrayEquals(const detail::CollectionData* lhs,
|
|
||||||
const detail::CollectionData* rhs);
|
|
||||||
bool objectEquals(const detail::CollectionData& lhs,
|
bool objectEquals(const detail::CollectionData& lhs,
|
||||||
const detail::CollectionData& rhs);
|
const detail::CollectionData& rhs);
|
||||||
bool objectEquals(const detail::CollectionData* lhs,
|
bool objectEquals(const detail::CollectionData* lhs,
|
||||||
|
@ -8,20 +8,6 @@
|
|||||||
|
|
||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
inline VariantData* collectionAddElement(CollectionData* array,
|
|
||||||
ResourceManager* resources) {
|
|
||||||
if (!array)
|
|
||||||
return nullptr;
|
|
||||||
return array->addElement(resources);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
inline VariantData* collectionAddMember(CollectionData* obj, TAdaptedString key,
|
|
||||||
ResourceManager* resources) {
|
|
||||||
ARDUINOJSON_ASSERT(obj != nullptr);
|
|
||||||
return obj->addMember(key, resources);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void collectionClear(CollectionData* c, ResourceManager* resources) {
|
inline void collectionClear(CollectionData* c, ResourceManager* resources) {
|
||||||
if (!c)
|
if (!c)
|
||||||
return;
|
return;
|
||||||
@ -36,13 +22,6 @@ inline bool collectionCopy(CollectionData* dst, const CollectionData* src,
|
|||||||
return dst->copyFrom(*src, resources);
|
return dst->copyFrom(*src, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantData* collectionGetElement(const CollectionData* obj,
|
|
||||||
size_t index) {
|
|
||||||
if (!obj)
|
|
||||||
return nullptr;
|
|
||||||
return obj->getElement(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
inline VariantData* collectionGetMember(const CollectionData* obj,
|
inline VariantData* collectionGetMember(const CollectionData* obj,
|
||||||
TAdaptedString key) {
|
TAdaptedString key) {
|
||||||
@ -58,13 +37,6 @@ inline void collectionRemove(CollectionData* data, VariantSlot* slot,
|
|||||||
data->removeSlot(slot, resources);
|
data->removeSlot(slot, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void collectionRemoveElement(CollectionData* array, size_t index,
|
|
||||||
ResourceManager* resources) {
|
|
||||||
if (!array)
|
|
||||||
return;
|
|
||||||
array->removeElement(index, resources);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
inline void collectionRemoveMember(CollectionData* obj, TAdaptedString key,
|
inline void collectionRemoveMember(CollectionData* obj, TAdaptedString key,
|
||||||
ResourceManager* resources) {
|
ResourceManager* resources) {
|
||||||
|
@ -23,14 +23,6 @@ inline void CollectionData::addSlot(VariantSlot* slot) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantData* CollectionData::addElement(ResourceManager* resources) {
|
|
||||||
auto slot = resources->allocVariant();
|
|
||||||
if (!slot)
|
|
||||||
return nullptr;
|
|
||||||
addSlot(slot);
|
|
||||||
return slot->data();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline VariantData* CollectionData::addMember(StringNode* key,
|
inline VariantData* CollectionData::addMember(StringNode* key,
|
||||||
ResourceManager* resources) {
|
ResourceManager* resources) {
|
||||||
ARDUINOJSON_ASSERT(key != nullptr);
|
ARDUINOJSON_ASSERT(key != nullptr);
|
||||||
@ -67,25 +59,6 @@ inline VariantData* CollectionData::getMember(TAdaptedString key) const {
|
|||||||
return slotData(getSlot(key));
|
return slotData(getSlot(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantData* CollectionData::getOrAddElement(
|
|
||||||
size_t index, ResourceManager* resources) {
|
|
||||||
VariantSlot* slot = head_;
|
|
||||||
while (slot && index > 0) {
|
|
||||||
slot = slot->next();
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
if (!slot)
|
|
||||||
index++;
|
|
||||||
while (index > 0) {
|
|
||||||
slot = resources->allocVariant();
|
|
||||||
if (!slot)
|
|
||||||
return nullptr;
|
|
||||||
addSlot(slot);
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
return slot->data();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
VariantData* CollectionData::getOrAddMember(TAdaptedString key,
|
VariantData* CollectionData::getOrAddMember(TAdaptedString key,
|
||||||
ResourceManager* resources) {
|
ResourceManager* resources) {
|
||||||
@ -95,10 +68,6 @@ VariantData* CollectionData::getOrAddMember(TAdaptedString key,
|
|||||||
return addMember(key, resources);
|
return addMember(key, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantData* CollectionData::getElement(size_t index) const {
|
|
||||||
return slotData(getSlot(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CollectionData::clear(ResourceManager* resources) {
|
inline void CollectionData::clear(ResourceManager* resources) {
|
||||||
for (auto slot = head_; slot; slot = slot->next())
|
for (auto slot = head_; slot; slot = slot->next())
|
||||||
slotRelease(slot, resources);
|
slotRelease(slot, resources);
|
||||||
@ -111,14 +80,10 @@ inline bool CollectionData::copyFrom(const CollectionData& src,
|
|||||||
clear(resources);
|
clear(resources);
|
||||||
|
|
||||||
for (VariantSlot* s = src.head(); s; s = s->next()) {
|
for (VariantSlot* s = src.head(); s; s = s->next()) {
|
||||||
VariantData* var;
|
ARDUINOJSON_ASSERT(s->key() != 0);
|
||||||
if (s->key() != 0) {
|
|
||||||
JsonString key(s->key(),
|
JsonString key(s->key(),
|
||||||
s->ownsKey() ? JsonString::Copied : JsonString::Linked);
|
s->ownsKey() ? JsonString::Copied : JsonString::Linked);
|
||||||
var = addMember(adaptString(key), resources);
|
auto var = addMember(adaptString(key), resources);
|
||||||
} else {
|
|
||||||
var = addElement(resources);
|
|
||||||
}
|
|
||||||
if (!variantCopyFrom(var, s->data(), resources))
|
if (!variantCopyFrom(var, s->data(), resources))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -138,12 +103,6 @@ inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
|
|||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantSlot* CollectionData::getSlot(size_t index) const {
|
|
||||||
if (!head_)
|
|
||||||
return 0;
|
|
||||||
return head_->next(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
|
inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
|
||||||
VariantSlot* current = head_;
|
VariantSlot* current = head_;
|
||||||
while (current) {
|
while (current) {
|
||||||
@ -170,11 +129,6 @@ inline void CollectionData::removeSlot(VariantSlot* slot,
|
|||||||
slotRelease(slot, resources);
|
slotRelease(slot, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CollectionData::removeElement(size_t index,
|
|
||||||
ResourceManager* resources) {
|
|
||||||
removeSlot(getSlot(index), resources);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
inline void CollectionData::removeMember(TAdaptedString key,
|
inline void CollectionData::removeMember(TAdaptedString key,
|
||||||
ResourceManager* resources) {
|
ResourceManager* resources) {
|
||||||
@ -211,31 +165,6 @@ inline void CollectionData::movePointers(ptrdiff_t variantDistance) {
|
|||||||
slot->data()->movePointers(variantDistance);
|
slot->data()->movePointers(variantDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool arrayEquals(const CollectionData& lhs, const CollectionData& rhs) {
|
|
||||||
auto a = lhs.head();
|
|
||||||
auto b = rhs.head();
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (!a && !b) // both ended
|
|
||||||
return true;
|
|
||||||
if (!a || !b) // one ended
|
|
||||||
return false;
|
|
||||||
if (compare(a->data(), b->data()) != COMPARE_RESULT_EQUAL)
|
|
||||||
return false;
|
|
||||||
a = a->next();
|
|
||||||
b = b->next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool arrayEquals(const CollectionData* lhs, const CollectionData* rhs) {
|
|
||||||
if (lhs == rhs)
|
|
||||||
return true;
|
|
||||||
if (!lhs || !rhs)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return arrayEquals(*lhs, *rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool objectEquals(const CollectionData& lhs, const CollectionData& rhs) {
|
inline bool objectEquals(const CollectionData& lhs, const CollectionData& rhs) {
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
for (auto a = lhs.head(); a; a = a->next()) {
|
for (auto a = lhs.head(); a; a = a->next()) {
|
||||||
|
@ -146,7 +146,7 @@ class JsonDeserializer {
|
|||||||
|
|
||||||
template <typename TFilter>
|
template <typename TFilter>
|
||||||
DeserializationError::Code parseArray(
|
DeserializationError::Code parseArray(
|
||||||
CollectionData& array, TFilter filter,
|
ArrayData& array, TFilter filter,
|
||||||
DeserializationOption::NestingLimit nestingLimit) {
|
DeserializationOption::NestingLimit nestingLimit) {
|
||||||
DeserializationError::Code err;
|
DeserializationError::Code err;
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ class JsonDeserializer {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
if (elementFilter.allow()) {
|
if (elementFilter.allow()) {
|
||||||
// Allocate slot in array
|
// Allocate slot in array
|
||||||
VariantData* value = collectionAddElement(&array, resources_);
|
VariantData* value = array.addElement(resources_);
|
||||||
if (!value)
|
if (!value)
|
||||||
return DeserializationError::NoMemory;
|
return DeserializationError::NoMemory;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ class JsonSerializer : public Visitor<size_t> {
|
|||||||
|
|
||||||
JsonSerializer(TWriter writer) : formatter_(writer) {}
|
JsonSerializer(TWriter writer) : formatter_(writer) {}
|
||||||
|
|
||||||
FORCE_INLINE size_t visitArray(const CollectionData& array) {
|
FORCE_INLINE size_t visitArray(const ArrayData& array) {
|
||||||
write('[');
|
write('[');
|
||||||
|
|
||||||
const VariantSlot* slot = array.head();
|
const VariantSlot* slot = array.head();
|
||||||
|
@ -18,7 +18,7 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
|||||||
public:
|
public:
|
||||||
PrettyJsonSerializer(TWriter writer) : base(writer), nesting_(0) {}
|
PrettyJsonSerializer(TWriter writer) : base(writer), nesting_(0) {}
|
||||||
|
|
||||||
size_t visitArray(const CollectionData& array) {
|
size_t visitArray(const ArrayData& array) {
|
||||||
const VariantSlot* slot = array.head();
|
const VariantSlot* slot = array.head();
|
||||||
if (slot) {
|
if (slot) {
|
||||||
base::write("[\r\n");
|
base::write("[\r\n");
|
||||||
|
@ -419,7 +419,7 @@ class MsgPackDeserializer {
|
|||||||
|
|
||||||
bool allowArray = filter.allowArray();
|
bool allowArray = filter.allowArray();
|
||||||
|
|
||||||
CollectionData* array;
|
ArrayData* array;
|
||||||
if (allowArray) {
|
if (allowArray) {
|
||||||
ARDUINOJSON_ASSERT(variant != 0);
|
ARDUINOJSON_ASSERT(variant != 0);
|
||||||
array = &variant->toArray();
|
array = &variant->toArray();
|
||||||
@ -434,7 +434,7 @@ class MsgPackDeserializer {
|
|||||||
|
|
||||||
if (elementFilter.allow()) {
|
if (elementFilter.allow()) {
|
||||||
ARDUINOJSON_ASSERT(array != 0);
|
ARDUINOJSON_ASSERT(array != 0);
|
||||||
value = collectionAddElement(array, resources_);
|
value = array->addElement(resources_);
|
||||||
if (!value)
|
if (!value)
|
||||||
return DeserializationError::NoMemory;
|
return DeserializationError::NoMemory;
|
||||||
} else {
|
} else {
|
||||||
|
@ -44,7 +44,7 @@ class MsgPackSerializer : public Visitor<size_t> {
|
|||||||
return bytesWritten();
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t visitArray(const CollectionData& array) {
|
size_t visitArray(const ArrayData& array) {
|
||||||
size_t n = array.size();
|
size_t n = array.size();
|
||||||
if (n < 0x10) {
|
if (n < 0x10) {
|
||||||
writeByte(uint8_t(0x90 + array.size()));
|
writeByte(uint8_t(0x90 + array.size()));
|
||||||
|
@ -79,12 +79,12 @@ struct Comparer<decltype(nullptr), void> : NullComparer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ArrayComparer : ComparerBase {
|
struct ArrayComparer : ComparerBase {
|
||||||
const CollectionData* rhs_;
|
const ArrayData* rhs_;
|
||||||
|
|
||||||
explicit ArrayComparer(const CollectionData& rhs) : rhs_(&rhs) {}
|
explicit ArrayComparer(const ArrayData& rhs) : rhs_(&rhs) {}
|
||||||
|
|
||||||
CompareResult visitArray(const CollectionData& lhs) {
|
CompareResult visitArray(const ArrayData& lhs) {
|
||||||
if (arrayEquals(lhs, *rhs_))
|
if (rhs_->equals(lhs))
|
||||||
return COMPARE_RESULT_EQUAL;
|
return COMPARE_RESULT_EQUAL;
|
||||||
else
|
else
|
||||||
return COMPARE_RESULT_DIFFER;
|
return COMPARE_RESULT_DIFFER;
|
||||||
@ -128,7 +128,7 @@ struct VariantComparer : ComparerBase {
|
|||||||
|
|
||||||
explicit VariantComparer(const VariantData* value) : rhs(value) {}
|
explicit VariantComparer(const VariantData* value) : rhs(value) {}
|
||||||
|
|
||||||
CompareResult visitArray(const CollectionData& lhs) {
|
CompareResult visitArray(const ArrayData& lhs) {
|
||||||
ArrayComparer comparer(lhs);
|
ArrayComparer comparer(lhs);
|
||||||
return accept(comparer);
|
return accept(comparer);
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,12 @@
|
|||||||
|
|
||||||
#include <stddef.h> // size_t
|
#include <stddef.h> // size_t
|
||||||
|
|
||||||
|
#include <ArduinoJson/Array/ArrayData.hpp>
|
||||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||||
#include <ArduinoJson/Numbers/JsonFloat.hpp>
|
#include <ArduinoJson/Numbers/JsonFloat.hpp>
|
||||||
#include <ArduinoJson/Numbers/JsonInteger.hpp>
|
#include <ArduinoJson/Numbers/JsonInteger.hpp>
|
||||||
|
|
||||||
|
|
||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -45,6 +47,7 @@ union VariantContent {
|
|||||||
JsonUInt asUnsignedInteger;
|
JsonUInt asUnsignedInteger;
|
||||||
JsonInteger asSignedInteger;
|
JsonInteger asSignedInteger;
|
||||||
CollectionData asCollection;
|
CollectionData asCollection;
|
||||||
|
ArrayData asArray;
|
||||||
const char* asLinkedString;
|
const char* asLinkedString;
|
||||||
struct StringNode* asOwnedString;
|
struct StringNode* asOwnedString;
|
||||||
};
|
};
|
||||||
|
@ -14,12 +14,8 @@
|
|||||||
|
|
||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
VariantData* collectionAddElement(CollectionData* array,
|
|
||||||
ResourceManager* resources);
|
|
||||||
bool collectionCopy(CollectionData* dst, const CollectionData* src,
|
bool collectionCopy(CollectionData* dst, const CollectionData* src,
|
||||||
ResourceManager* resources);
|
ResourceManager* resources);
|
||||||
void collectionRemoveElement(CollectionData* data, size_t index,
|
|
||||||
ResourceManager* resources);
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T parseNumber(const char* s);
|
T parseNumber(const char* s);
|
||||||
void slotRelease(VariantSlot* slot, ResourceManager* resources);
|
void slotRelease(VariantSlot* slot, ResourceManager* resources);
|
||||||
@ -38,7 +34,7 @@ class VariantData {
|
|||||||
return visitor.visitFloat(content_.asFloat);
|
return visitor.visitFloat(content_.asFloat);
|
||||||
|
|
||||||
case VALUE_IS_ARRAY:
|
case VALUE_IS_ARRAY:
|
||||||
return visitor.visitArray(content_.asCollection);
|
return visitor.visitArray(content_.asArray);
|
||||||
|
|
||||||
case VALUE_IS_OBJECT:
|
case VALUE_IS_OBJECT:
|
||||||
return visitor.visitObject(content_.asCollection);
|
return visitor.visitObject(content_.asCollection);
|
||||||
@ -71,7 +67,7 @@ class VariantData {
|
|||||||
|
|
||||||
VariantData* addElement(ResourceManager* resources) {
|
VariantData* addElement(ResourceManager* resources) {
|
||||||
auto array = isNull() ? &toArray() : asArray();
|
auto array = isNull() ? &toArray() : asArray();
|
||||||
return collectionAddElement(array, resources);
|
return detail::ArrayData::addElement(array, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool asBoolean() const {
|
bool asBoolean() const {
|
||||||
@ -90,11 +86,11 @@ class VariantData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionData* asArray() {
|
ArrayData* asArray() {
|
||||||
return isArray() ? &content_.asCollection : 0;
|
return isArray() ? &content_.asArray : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CollectionData* asArray() const {
|
const ArrayData* asArray() const {
|
||||||
return const_cast<VariantData*>(this)->asArray();
|
return const_cast<VariantData*>(this)->asArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +177,7 @@ class VariantData {
|
|||||||
}
|
}
|
||||||
switch (src->type()) {
|
switch (src->type()) {
|
||||||
case VALUE_IS_ARRAY:
|
case VALUE_IS_ARRAY:
|
||||||
return collectionCopy(&toArray(), src->asArray(), resources);
|
return toArray().copyFrom(*src->asArray(), resources);
|
||||||
case VALUE_IS_OBJECT:
|
case VALUE_IS_OBJECT:
|
||||||
return collectionCopy(&toObject(), src->asObject(), resources);
|
return collectionCopy(&toObject(), src->asObject(), resources);
|
||||||
case VALUE_IS_OWNED_STRING: {
|
case VALUE_IS_OWNED_STRING: {
|
||||||
@ -319,7 +315,7 @@ class VariantData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void removeElement(size_t index, ResourceManager* resources) {
|
void removeElement(size_t index, ResourceManager* resources) {
|
||||||
collectionRemoveElement(asArray(), index, resources);
|
ArrayData::removeElement(asArray(), index, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
@ -427,13 +423,13 @@ class VariantData {
|
|||||||
return isCollection() ? content_.asCollection.size() : 0;
|
return isCollection() ? content_.asCollection.size() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionData& toArray() {
|
ArrayData& toArray() {
|
||||||
setType(VALUE_IS_ARRAY);
|
setType(VALUE_IS_ARRAY);
|
||||||
new (&content_.asCollection) CollectionData();
|
new (&content_.asArray) ArrayData();
|
||||||
return content_.asCollection;
|
return content_.asArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionData& toArray(ResourceManager* resources) {
|
ArrayData& toArray(ResourceManager* resources) {
|
||||||
release(resources);
|
release(resources);
|
||||||
return toArray();
|
return toArray();
|
||||||
}
|
}
|
||||||
@ -594,8 +590,7 @@ inline size_t variantSize(const VariantData* var) {
|
|||||||
return var != 0 ? var->size() : 0;
|
return var != 0 ? var->size() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline CollectionData* variantToArray(VariantData* var,
|
inline ArrayData* variantToArray(VariantData* var, ResourceManager* resources) {
|
||||||
ResourceManager* resources) {
|
|
||||||
if (!var)
|
if (!var)
|
||||||
return 0;
|
return 0;
|
||||||
return &var->toArray(resources);
|
return &var->toArray(resources);
|
||||||
|
@ -14,7 +14,7 @@ template <typename TResult>
|
|||||||
struct Visitor {
|
struct Visitor {
|
||||||
typedef TResult result_type;
|
typedef TResult result_type;
|
||||||
|
|
||||||
TResult visitArray(const CollectionData&) {
|
TResult visitArray(const ArrayData&) {
|
||||||
return TResult();
|
return TResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user