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