mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-30 18:57:32 +02:00
CollectionImpl: attach to VariantData*
instead of CollectionData*
This commit is contained in:
@ -12,9 +12,13 @@ class ArrayImpl : public CollectionImpl {
|
|||||||
public:
|
public:
|
||||||
ArrayImpl() {}
|
ArrayImpl() {}
|
||||||
|
|
||||||
ArrayImpl(CollectionData* data, ResourceManager* resources)
|
ArrayImpl(VariantData* data, ResourceManager* resources)
|
||||||
: CollectionImpl(data, resources) {}
|
: CollectionImpl(data, resources) {}
|
||||||
|
|
||||||
|
bool isNull() const {
|
||||||
|
return !data_ || data_->type != VariantType::Array;
|
||||||
|
}
|
||||||
|
|
||||||
VariantData* addElement();
|
VariantData* addElement();
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
inline ArrayImpl::iterator ArrayImpl::at(size_t index) const {
|
inline ArrayImpl::iterator ArrayImpl::at(size_t index) const {
|
||||||
|
if (isNull())
|
||||||
|
return iterator();
|
||||||
|
|
||||||
auto it = createIterator();
|
auto it = createIterator();
|
||||||
while (!it.done() && index) {
|
while (!it.done() && index) {
|
||||||
it.next(resources_);
|
it.next(resources_);
|
||||||
@ -20,7 +23,7 @@ inline ArrayImpl::iterator ArrayImpl::at(size_t index) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline VariantData* ArrayImpl::addElement() {
|
inline VariantData* ArrayImpl::addElement() {
|
||||||
if (!data_)
|
if (isNull())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
auto slot = allocVariant();
|
auto slot = allocVariant();
|
||||||
if (!slot)
|
if (!slot)
|
||||||
@ -57,7 +60,7 @@ inline void ArrayImpl::removeElement(size_t index) {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool ArrayImpl::addValue(const T& value) {
|
inline bool ArrayImpl::addValue(const T& value) {
|
||||||
if (!data_)
|
if (isNull())
|
||||||
return false;
|
return false;
|
||||||
auto slot = allocVariant();
|
auto slot = allocVariant();
|
||||||
if (!slot)
|
if (!slot)
|
||||||
|
@ -24,10 +24,6 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
|||||||
|
|
||||||
// INTERNAL USE ONLY
|
// INTERNAL USE ONLY
|
||||||
JsonArray(detail::VariantData* data, detail::ResourceManager* resources)
|
JsonArray(detail::VariantData* data, detail::ResourceManager* resources)
|
||||||
: impl_(data ? data->asArray() : nullptr, resources) {}
|
|
||||||
|
|
||||||
// INTERNAL USE ONLY
|
|
||||||
JsonArray(detail::CollectionData* data, detail::ResourceManager* resources)
|
|
||||||
: impl_(data, resources) {}
|
: impl_(data, resources) {}
|
||||||
|
|
||||||
// Returns a JsonVariant pointing to the array.
|
// Returns a JsonVariant pointing to the array.
|
||||||
|
@ -38,7 +38,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
|||||||
|
|
||||||
// INTERNAL USE ONLY
|
// INTERNAL USE ONLY
|
||||||
JsonArrayConst(detail::VariantData* data, detail::ResourceManager* resources)
|
JsonArrayConst(detail::VariantData* data, detail::ResourceManager* resources)
|
||||||
: impl_(data ? data->asArray() : nullptr, resources) {}
|
: impl_(data, resources) {}
|
||||||
|
|
||||||
// INTERNAL USE ONLY
|
// INTERNAL USE ONLY
|
||||||
JsonArrayConst(const detail::ArrayImpl& impl) : impl_(impl) {}
|
JsonArrayConst(const detail::ArrayImpl& impl) : impl_(impl) {}
|
||||||
|
@ -66,7 +66,7 @@ class CollectionIterator {
|
|||||||
|
|
||||||
class CollectionImpl {
|
class CollectionImpl {
|
||||||
protected:
|
protected:
|
||||||
CollectionData* data_;
|
VariantData* data_;
|
||||||
ResourceManager* resources_;
|
ResourceManager* resources_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -74,20 +74,19 @@ class CollectionImpl {
|
|||||||
|
|
||||||
CollectionImpl() : data_(nullptr), resources_(nullptr) {}
|
CollectionImpl() : data_(nullptr), resources_(nullptr) {}
|
||||||
|
|
||||||
CollectionImpl(CollectionData* data, ResourceManager* resources)
|
CollectionImpl(VariantData* data, ResourceManager* resources)
|
||||||
: data_(data), resources_(resources) {}
|
: data_(data), resources_(resources) {}
|
||||||
|
|
||||||
explicit operator bool() const {
|
explicit operator bool() const {
|
||||||
return data_ != nullptr;
|
return data_ && data_->isCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNull() const {
|
bool isNull() const {
|
||||||
return data_ == nullptr;
|
return !operator bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantData* getData() const {
|
VariantData* getData() const {
|
||||||
void* data = data_; // prevent warning cast-align
|
return data_;
|
||||||
return reinterpret_cast<VariantData*>(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceManager* getResourceManager() const {
|
ResourceManager* getResourceManager() const {
|
||||||
@ -132,7 +131,8 @@ class CollectionImpl {
|
|||||||
|
|
||||||
CollectionData* getCollectionData() const {
|
CollectionData* getCollectionData() const {
|
||||||
ARDUINOJSON_ASSERT(data_ != nullptr);
|
ARDUINOJSON_ASSERT(data_ != nullptr);
|
||||||
return data_;
|
ARDUINOJSON_ASSERT(data_->isCollection());
|
||||||
|
return &data_->content.asCollection;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ inline void CollectionIterator::next(const ResourceManager* resources) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline CollectionImpl::iterator CollectionImpl::createIterator() const {
|
inline CollectionImpl::iterator CollectionImpl::createIterator() const {
|
||||||
if (!data_)
|
if (!data_ || !data_->isCollection())
|
||||||
return iterator();
|
return iterator();
|
||||||
auto coll = getCollectionData();
|
auto coll = getCollectionData();
|
||||||
return iterator(getVariant(coll->head), coll->head);
|
return iterator(getVariant(coll->head), coll->head);
|
||||||
@ -62,7 +62,7 @@ inline void CollectionImpl::appendPair(Slot<VariantData> key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void CollectionImpl::clear() {
|
inline void CollectionImpl::clear() {
|
||||||
if (!data_)
|
if (!data_ || !data_->isCollection())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto coll = getCollectionData();
|
auto coll = getCollectionData();
|
||||||
@ -128,7 +128,7 @@ inline void CollectionImpl::removePair(ObjectImpl::iterator it) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline size_t CollectionImpl::nesting() const {
|
inline size_t CollectionImpl::nesting() const {
|
||||||
if (!data_)
|
if (!data_ || !data_->isCollection())
|
||||||
return 0;
|
return 0;
|
||||||
size_t maxChildNesting = 0;
|
size_t maxChildNesting = 0;
|
||||||
for (auto it = createIterator(); !it.done(); it.next(resources_)) {
|
for (auto it = createIterator(); !it.done(); it.next(resources_)) {
|
||||||
|
@ -148,7 +148,7 @@ class JsonDeserializer {
|
|||||||
|
|
||||||
template <typename TFilter>
|
template <typename TFilter>
|
||||||
DeserializationError::Code parseArray(
|
DeserializationError::Code parseArray(
|
||||||
CollectionData* arrayData, TFilter filter,
|
VariantData* arrayData, TFilter filter,
|
||||||
DeserializationOption::NestingLimit nestingLimit) {
|
DeserializationOption::NestingLimit nestingLimit) {
|
||||||
DeserializationError::Code err;
|
DeserializationError::Code err;
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ class JsonDeserializer {
|
|||||||
|
|
||||||
template <typename TFilter>
|
template <typename TFilter>
|
||||||
DeserializationError::Code parseObject(
|
DeserializationError::Code parseObject(
|
||||||
CollectionData* objectData, TFilter filter,
|
VariantData* objectData, TFilter filter,
|
||||||
DeserializationOption::NestingLimit nestingLimit) {
|
DeserializationOption::NestingLimit nestingLimit) {
|
||||||
DeserializationError::Code err;
|
DeserializationError::Code err;
|
||||||
|
|
||||||
|
@ -22,13 +22,9 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
|||||||
// Creates an unbound reference.
|
// Creates an unbound reference.
|
||||||
JsonObject() {}
|
JsonObject() {}
|
||||||
|
|
||||||
// INTERNAL USE ONLY
|
|
||||||
JsonObject(detail::CollectionData* data, detail::ResourceManager* resource)
|
|
||||||
: impl_(data, resource) {}
|
|
||||||
|
|
||||||
// INTERNAL USE ONLY
|
// INTERNAL USE ONLY
|
||||||
JsonObject(detail::VariantData* data, detail::ResourceManager* resource)
|
JsonObject(detail::VariantData* data, detail::ResourceManager* resource)
|
||||||
: impl_(data ? data->asObject() : nullptr, resource) {}
|
: impl_(data, resource) {}
|
||||||
|
|
||||||
operator JsonVariant() const {
|
operator JsonVariant() const {
|
||||||
return JsonVariant(getData(), getResourceManager());
|
return JsonVariant(getData(), getResourceManager());
|
||||||
|
@ -23,7 +23,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
|||||||
|
|
||||||
// INTERNAL USE ONLY
|
// INTERNAL USE ONLY
|
||||||
JsonObjectConst(detail::VariantData* data, detail::ResourceManager* resources)
|
JsonObjectConst(detail::VariantData* data, detail::ResourceManager* resources)
|
||||||
: impl_(data ? data->asObject() : nullptr, resources) {}
|
: impl_(data, resources) {}
|
||||||
|
|
||||||
// INTERNAL USE ONLY
|
// INTERNAL USE ONLY
|
||||||
JsonObjectConst(const detail::ObjectImpl& impl) : impl_(impl) {}
|
JsonObjectConst(const detail::ObjectImpl& impl) : impl_(impl) {}
|
||||||
|
@ -14,9 +14,13 @@ class ObjectImpl : public CollectionImpl {
|
|||||||
public:
|
public:
|
||||||
ObjectImpl() {}
|
ObjectImpl() {}
|
||||||
|
|
||||||
ObjectImpl(CollectionData* data, ResourceManager* resources)
|
ObjectImpl(VariantData* data, ResourceManager* resources)
|
||||||
: CollectionImpl(data, resources) {}
|
: CollectionImpl(data, resources) {}
|
||||||
|
|
||||||
|
bool isNull() const {
|
||||||
|
return !data_ || data_->type != VariantType::Object;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
VariantData* addMember(TAdaptedString key);
|
VariantData* addMember(TAdaptedString key);
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ VariantData* ObjectImpl::getOrAddMember(TAdaptedString key) {
|
|||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
inline ObjectImpl::iterator ObjectImpl::findKey(TAdaptedString key) const {
|
inline ObjectImpl::iterator ObjectImpl::findKey(TAdaptedString key) const {
|
||||||
|
if (isNull())
|
||||||
|
return iterator();
|
||||||
if (key.isNull())
|
if (key.isNull())
|
||||||
return iterator();
|
return iterator();
|
||||||
bool isKey = true;
|
bool isKey = true;
|
||||||
@ -48,7 +50,7 @@ inline void ObjectImpl::removeMember(TAdaptedString key) {
|
|||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
inline VariantData* ObjectImpl::addMember(TAdaptedString key) {
|
inline VariantData* ObjectImpl::addMember(TAdaptedString key) {
|
||||||
if (!data_)
|
if (isNull())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto keySlot = allocVariant();
|
auto keySlot = allocVariant();
|
||||||
@ -69,8 +71,7 @@ inline VariantData* ObjectImpl::addMember(TAdaptedString key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline VariantData* ObjectImpl::addPair(VariantData** value) {
|
inline VariantData* ObjectImpl::addPair(VariantData** value) {
|
||||||
if (!data_)
|
ARDUINOJSON_ASSERT(!isNull());
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
auto keySlot = allocVariant();
|
auto keySlot = allocVariant();
|
||||||
if (!keySlot)
|
if (!keySlot)
|
||||||
|
@ -71,17 +71,8 @@ struct VariantData {
|
|||||||
content.asOwnedString = s;
|
content.asOwnedString = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionData* asCollection() {
|
bool isCollection() const {
|
||||||
return type & VariantTypeBits::CollectionMask ? &content.asCollection
|
return type & VariantTypeBits::CollectionMask;
|
||||||
: nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
CollectionData* asArray() {
|
|
||||||
return type == VariantType::Array ? &content.asCollection : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
CollectionData* asObject() {
|
|
||||||
return type == VariantType::Object ? &content.asCollection : nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFloat() const {
|
bool isFloat() const {
|
||||||
@ -93,35 +84,37 @@ struct VariantData {
|
|||||||
type == VariantType::OwnedString || type == VariantType::TinyString;
|
type == VariantType::OwnedString || type == VariantType::TinyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionData* toArray() {
|
VariantData* toArray() {
|
||||||
ARDUINOJSON_ASSERT(type == VariantType::Null);
|
ARDUINOJSON_ASSERT(type == VariantType::Null);
|
||||||
type = VariantType::Array;
|
type = VariantType::Array;
|
||||||
return new (&content.asCollection) CollectionData();
|
new (&content.asCollection) CollectionData();
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionData* toObject() {
|
VariantData* toObject() {
|
||||||
ARDUINOJSON_ASSERT(type == VariantType::Null);
|
ARDUINOJSON_ASSERT(type == VariantType::Null);
|
||||||
type = VariantType::Object;
|
type = VariantType::Object;
|
||||||
return new (&content.asCollection) CollectionData();
|
new (&content.asCollection) CollectionData();
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionData* getOrCreateArray() {
|
VariantData* getOrCreateArray() {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VariantType::Null:
|
case VariantType::Null:
|
||||||
return toArray();
|
return toArray();
|
||||||
case VariantType::Array:
|
case VariantType::Array:
|
||||||
return &content.asCollection;
|
return this;
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionData* getOrCreateObject() {
|
VariantData* getOrCreateObject() {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VariantType::Null:
|
case VariantType::Null:
|
||||||
return toObject();
|
return toObject();
|
||||||
case VariantType::Object:
|
case VariantType::Object:
|
||||||
return &content.asCollection;
|
return this;
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -48,11 +48,10 @@ class VariantImpl {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
case VariantType::Array:
|
case VariantType::Array:
|
||||||
return visit.visit(ArrayImpl(&data_->content.asCollection, resources_));
|
return visit.visit(ArrayImpl(data_, resources_));
|
||||||
|
|
||||||
case VariantType::Object:
|
case VariantType::Object:
|
||||||
return visit.visit(
|
return visit.visit(ObjectImpl(data_, resources_));
|
||||||
ObjectImpl(&data_->content.asCollection, resources_));
|
|
||||||
|
|
||||||
case VariantType::TinyString:
|
case VariantType::TinyString:
|
||||||
return visit.visit(JsonString(data_->content.asTinyString));
|
return visit.visit(JsonString(data_->content.asTinyString));
|
||||||
@ -264,16 +263,12 @@ class VariantImpl {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
VariantData* getElement(size_t index) {
|
VariantData* getElement(size_t index) {
|
||||||
if (!data_)
|
return ArrayImpl(data_, resources_).getElement(index);
|
||||||
return nullptr;
|
|
||||||
return ArrayImpl(data_->asArray(), resources_).getElement(index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
VariantData* getMember(TAdaptedString key) {
|
VariantData* getMember(TAdaptedString key) {
|
||||||
if (!data_)
|
return ObjectImpl(data_, resources_).getMember(key);
|
||||||
return nullptr;
|
|
||||||
return ObjectImpl(data_->asObject(), resources_).getMember(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantData* getOrAddElement(size_t index) {
|
VariantData* getOrAddElement(size_t index) {
|
||||||
@ -301,10 +296,6 @@ class VariantImpl {
|
|||||||
return type() == VariantType::Boolean;
|
return type() == VariantType::Boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isCollection() const {
|
|
||||||
return type() & VariantTypeBits::CollectionMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isFloat() const {
|
bool isFloat() const {
|
||||||
return data_ && data_->isFloat();
|
return data_ && data_->isFloat();
|
||||||
}
|
}
|
||||||
@ -350,22 +341,16 @@ class VariantImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t nesting() {
|
size_t nesting() {
|
||||||
if (!data_)
|
return CollectionImpl(data_, resources_).nesting();
|
||||||
return 0;
|
|
||||||
return CollectionImpl(data_->asCollection(), resources_).nesting();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeElement(size_t index) {
|
void removeElement(size_t index) {
|
||||||
if (!data_)
|
ArrayImpl(data_, resources_).removeElement(index);
|
||||||
return;
|
|
||||||
ArrayImpl(data_->asArray(), resources_).removeElement(index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
void removeMember(TAdaptedString key) {
|
void removeMember(TAdaptedString key) {
|
||||||
if (!data_)
|
ObjectImpl(data_, resources_).removeMember(key);
|
||||||
return;
|
|
||||||
ObjectImpl(data_->asObject(), resources_).removeMember(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setBoolean(bool value) {
|
bool setBoolean(bool value) {
|
||||||
@ -470,12 +455,9 @@ class VariantImpl {
|
|||||||
bool setLinkedString(const char* s);
|
bool setLinkedString(const char* s);
|
||||||
|
|
||||||
size_t size() {
|
size_t size() {
|
||||||
if (!data_)
|
auto size = CollectionImpl(data_, resources_).size();
|
||||||
return 0;
|
|
||||||
|
|
||||||
auto size = CollectionImpl(data_->asCollection(), resources_).size();
|
if (data_ && data_->type == VariantType::Object)
|
||||||
|
|
||||||
if (data_->type == VariantType::Object)
|
|
||||||
size /= 2;
|
size /= 2;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
@ -554,7 +536,7 @@ inline void VariantImpl::clear() {
|
|||||||
resources_->freeEightByte(data_->content.asSlotId);
|
resources_->freeEightByte(data_->content.asSlotId);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CollectionImpl(data_->asCollection(), resources_).clear();
|
CollectionImpl(data_, resources_).clear();
|
||||||
|
|
||||||
data_->type = VariantType::Null;
|
data_->type = VariantType::Null;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user