forked from bblanchon/ArduinoJson
Manage resources in CollectionData
This commit is contained in:
@ -5,6 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Array/JsonArrayIterator.hpp>
|
#include <ArduinoJson/Array/JsonArrayIterator.hpp>
|
||||||
|
#include <ArduinoJson/Collection/CollectionFunctions.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantAttorney.hpp>
|
#include <ArduinoJson/Variant/VariantAttorney.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
|||||||
// 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(data_ ? slotData(data_->get(index)) : 0);
|
return JsonVariantConst(collectionGetElement(data_, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
operator JsonVariantConst() const {
|
operator JsonVariantConst() const {
|
||||||
|
@ -15,16 +15,46 @@ class VariantData;
|
|||||||
class VariantSlot;
|
class VariantSlot;
|
||||||
|
|
||||||
class CollectionData {
|
class CollectionData {
|
||||||
VariantSlot* head_;
|
VariantSlot* head_ = 0;
|
||||||
VariantSlot* tail_;
|
VariantSlot* tail_ = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void clear();
|
// Placement new
|
||||||
|
static void* operator new(size_t, void* p) noexcept {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void operator delete(void*, void*) noexcept {}
|
||||||
|
|
||||||
size_t memoryUsage() const;
|
size_t memoryUsage() const;
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
|
|
||||||
void add(VariantSlot*);
|
VariantData* addElement(ResourceManager* resources);
|
||||||
void remove(VariantSlot* slot);
|
|
||||||
|
VariantData* addMember(StringNode* key, ResourceManager* resources);
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
VariantData* addMember(TAdaptedString key, ResourceManager* resources);
|
||||||
|
|
||||||
|
void clear(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>
|
||||||
|
VariantData* getOrAddMember(TAdaptedString key, ResourceManager* resources);
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
VariantData* getMember(TAdaptedString key) const;
|
||||||
|
|
||||||
|
void removeSlot(VariantSlot* slot, ResourceManager* resources);
|
||||||
|
|
||||||
|
void removeElement(size_t index, ResourceManager* resources);
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
void removeMember(TAdaptedString key, ResourceManager* resources);
|
||||||
|
|
||||||
VariantSlot* head() const {
|
VariantSlot* head() const {
|
||||||
return head_;
|
return head_;
|
||||||
@ -32,13 +62,15 @@ class CollectionData {
|
|||||||
|
|
||||||
void movePointers(ptrdiff_t variantDistance);
|
void movePointers(ptrdiff_t variantDistance);
|
||||||
|
|
||||||
VariantSlot* get(size_t index) const;
|
private:
|
||||||
|
void addSlot(VariantSlot*);
|
||||||
|
|
||||||
|
VariantSlot* getPreviousSlot(VariantSlot*) const;
|
||||||
|
|
||||||
|
VariantSlot* getSlot(size_t index) const;
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
VariantSlot* get(TAdaptedString key) const;
|
VariantSlot* getSlot(TAdaptedString key) const;
|
||||||
|
|
||||||
private:
|
|
||||||
VariantSlot* getPrevious(VariantSlot*) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const VariantData* collectionToVariant(
|
inline const VariantData* collectionToVariant(
|
||||||
|
@ -12,39 +12,20 @@ inline VariantData* collectionAddElement(CollectionData* array,
|
|||||||
ResourceManager* resources) {
|
ResourceManager* resources) {
|
||||||
if (!array)
|
if (!array)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
auto slot = resources->allocVariant();
|
return array->addElement(resources);
|
||||||
if (!slot)
|
|
||||||
return nullptr;
|
|
||||||
array->add(slot);
|
|
||||||
return slot->data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
inline VariantData* collectionAddMember(CollectionData* obj, TAdaptedString key,
|
inline VariantData* collectionAddMember(CollectionData* obj, TAdaptedString key,
|
||||||
ResourceManager* resources) {
|
ResourceManager* resources) {
|
||||||
ARDUINOJSON_ASSERT(!key.isNull());
|
|
||||||
ARDUINOJSON_ASSERT(obj != nullptr);
|
ARDUINOJSON_ASSERT(obj != nullptr);
|
||||||
auto slot = resources->allocVariant();
|
return obj->addMember(key, resources);
|
||||||
if (!slot)
|
|
||||||
return nullptr;
|
|
||||||
if (key.isLinked())
|
|
||||||
slot->setKey(key.data());
|
|
||||||
else {
|
|
||||||
auto storedKey = resources->saveString(key);
|
|
||||||
if (!storedKey)
|
|
||||||
return nullptr;
|
|
||||||
slot->setKey(storedKey);
|
|
||||||
}
|
|
||||||
obj->add(slot);
|
|
||||||
return slot->data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void collectionClear(CollectionData* c, ResourceManager* resources) {
|
inline void collectionClear(CollectionData* c, ResourceManager* resources) {
|
||||||
if (!c)
|
if (!c)
|
||||||
return;
|
return;
|
||||||
for (auto slot = c->head(); slot; slot = slot->next())
|
c->clear(resources);
|
||||||
slotRelease(slot, resources);
|
|
||||||
c->clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool collectionCopy(CollectionData* dst, const CollectionData* src,
|
inline bool collectionCopy(CollectionData* dst, const CollectionData* src,
|
||||||
@ -52,21 +33,14 @@ inline bool collectionCopy(CollectionData* dst, const CollectionData* src,
|
|||||||
if (!dst || !src)
|
if (!dst || !src)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
collectionClear(dst, resources);
|
return dst->copyFrom(*src, resources);
|
||||||
|
}
|
||||||
|
|
||||||
for (VariantSlot* s = src->head(); s; s = s->next()) {
|
inline VariantData* collectionGetElement(const CollectionData* obj,
|
||||||
VariantData* var;
|
size_t index) {
|
||||||
if (s->key() != 0) {
|
if (!obj)
|
||||||
JsonString key(s->key(),
|
return nullptr;
|
||||||
s->ownsKey() ? JsonString::Copied : JsonString::Linked);
|
return obj->getElement(index);
|
||||||
var = collectionAddMember(dst, adaptString(key), resources);
|
|
||||||
} else {
|
|
||||||
var = collectionAddElement(dst, resources);
|
|
||||||
}
|
|
||||||
if (!variantCopyFrom(var, s->data(), resources))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
@ -74,22 +48,21 @@ inline VariantData* collectionGetMember(const CollectionData* obj,
|
|||||||
TAdaptedString key) {
|
TAdaptedString key) {
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return slotData(obj->get(key));
|
return obj->getMember(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void collectionRemove(CollectionData* data, VariantSlot* slot,
|
inline void collectionRemove(CollectionData* data, VariantSlot* slot,
|
||||||
ResourceManager* resources) {
|
ResourceManager* resources) {
|
||||||
if (!data || !slot)
|
if (!data)
|
||||||
return;
|
return;
|
||||||
data->remove(slot);
|
data->removeSlot(slot, resources);
|
||||||
slotRelease(slot, resources);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void collectionRemoveElement(CollectionData* array, size_t index,
|
inline void collectionRemoveElement(CollectionData* array, size_t index,
|
||||||
ResourceManager* resources) {
|
ResourceManager* resources) {
|
||||||
if (!array)
|
if (!array)
|
||||||
return;
|
return;
|
||||||
collectionRemove(array, array->get(index), resources);
|
array->removeElement(index, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
@ -97,7 +70,7 @@ inline void collectionRemoveMember(CollectionData* obj, TAdaptedString key,
|
|||||||
ResourceManager* resources) {
|
ResourceManager* resources) {
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return;
|
return;
|
||||||
collectionRemove(obj, obj->get(key), resources);
|
obj->removeMember(key, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
inline void CollectionData::add(VariantSlot* slot) {
|
inline void CollectionData::addSlot(VariantSlot* slot) {
|
||||||
ARDUINOJSON_ASSERT(slot != nullptr);
|
ARDUINOJSON_ASSERT(slot != nullptr);
|
||||||
|
|
||||||
if (tail_) {
|
if (tail_) {
|
||||||
@ -23,13 +23,110 @@ inline void CollectionData::add(VariantSlot* slot) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CollectionData::clear() {
|
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,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
ARDUINOJSON_ASSERT(key != nullptr);
|
||||||
|
auto slot = resources->allocVariant();
|
||||||
|
if (!slot)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
slot->setKey(key);
|
||||||
|
addSlot(slot);
|
||||||
|
return slot->data();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
inline VariantData* CollectionData::addMember(TAdaptedString key,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
ARDUINOJSON_ASSERT(!key.isNull());
|
||||||
|
auto slot = resources->allocVariant();
|
||||||
|
if (!slot)
|
||||||
|
return nullptr;
|
||||||
|
if (key.isLinked())
|
||||||
|
slot->setKey(key.data());
|
||||||
|
else {
|
||||||
|
auto storedKey = resources->saveString(key);
|
||||||
|
if (!storedKey)
|
||||||
|
return nullptr;
|
||||||
|
slot->setKey(storedKey);
|
||||||
|
}
|
||||||
|
addSlot(slot);
|
||||||
|
return slot->data();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
inline VariantData* CollectionData::getMember(TAdaptedString key) const {
|
||||||
|
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>
|
||||||
|
VariantData* CollectionData::getOrAddMember(TAdaptedString key,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
auto slot = getSlot(key);
|
||||||
|
if (slot)
|
||||||
|
return slot->data();
|
||||||
|
return addMember(key, resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline VariantData* CollectionData::getElement(size_t index) const {
|
||||||
|
return slotData(getSlot(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CollectionData::clear(ResourceManager* resources) {
|
||||||
|
for (auto slot = head_; slot; slot = slot->next())
|
||||||
|
slotRelease(slot, resources);
|
||||||
head_ = 0;
|
head_ = 0;
|
||||||
tail_ = 0;
|
tail_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool CollectionData::copyFrom(const CollectionData& src,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
clear(resources);
|
||||||
|
|
||||||
|
for (VariantSlot* s = src.head(); s; s = s->next()) {
|
||||||
|
VariantData* var;
|
||||||
|
if (s->key() != 0) {
|
||||||
|
JsonString key(s->key(),
|
||||||
|
s->ownsKey() ? JsonString::Copied : JsonString::Linked);
|
||||||
|
var = addMember(adaptString(key), resources);
|
||||||
|
} else {
|
||||||
|
var = addElement(resources);
|
||||||
|
}
|
||||||
|
if (!variantCopyFrom(var, s->data(), resources))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
inline VariantSlot* CollectionData::get(TAdaptedString key) const {
|
inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
|
||||||
if (key.isNull())
|
if (key.isNull())
|
||||||
return 0;
|
return 0;
|
||||||
VariantSlot* slot = head_;
|
VariantSlot* slot = head_;
|
||||||
@ -41,13 +138,13 @@ inline VariantSlot* CollectionData::get(TAdaptedString key) const {
|
|||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantSlot* CollectionData::get(size_t index) const {
|
inline VariantSlot* CollectionData::getSlot(size_t index) const {
|
||||||
if (!head_)
|
if (!head_)
|
||||||
return 0;
|
return 0;
|
||||||
return head_->next(index);
|
return head_->next(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantSlot* CollectionData::getPrevious(VariantSlot* target) const {
|
inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
|
||||||
VariantSlot* current = head_;
|
VariantSlot* current = head_;
|
||||||
while (current) {
|
while (current) {
|
||||||
VariantSlot* next = current->next();
|
VariantSlot* next = current->next();
|
||||||
@ -58,9 +155,11 @@ inline VariantSlot* CollectionData::getPrevious(VariantSlot* target) const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CollectionData::remove(VariantSlot* slot) {
|
inline void CollectionData::removeSlot(VariantSlot* slot,
|
||||||
ARDUINOJSON_ASSERT(slot != nullptr);
|
ResourceManager* resources) {
|
||||||
VariantSlot* prev = getPrevious(slot);
|
if (!slot)
|
||||||
|
return;
|
||||||
|
VariantSlot* prev = getPreviousSlot(slot);
|
||||||
VariantSlot* next = slot->next();
|
VariantSlot* next = slot->next();
|
||||||
if (prev)
|
if (prev)
|
||||||
prev->setNext(next);
|
prev->setNext(next);
|
||||||
@ -68,6 +167,18 @@ inline void CollectionData::remove(VariantSlot* slot) {
|
|||||||
head_ = next;
|
head_ = next;
|
||||||
if (!next)
|
if (!next)
|
||||||
tail_ = prev;
|
tail_ = prev;
|
||||||
|
slotRelease(slot, resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CollectionData::removeElement(size_t index,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
removeSlot(getSlot(index), resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
inline void CollectionData::removeMember(TAdaptedString key,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
removeSlot(getSlot(key), resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t CollectionData::memoryUsage() const {
|
inline size_t CollectionData::memoryUsage() const {
|
||||||
@ -128,10 +239,10 @@ inline bool arrayEquals(const CollectionData* lhs, const CollectionData* 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()) {
|
||||||
auto b = rhs.get(adaptString(a->key()));
|
auto b = rhs.getMember(adaptString(a->key()));
|
||||||
if (!b)
|
if (!b)
|
||||||
return false;
|
return false;
|
||||||
if (compare(a->data(), b->data()) != COMPARE_RESULT_EQUAL)
|
if (compare(a->data(), b) != COMPARE_RESULT_EQUAL)
|
||||||
return false;
|
return false;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
@ -273,25 +273,21 @@ class JsonDeserializer {
|
|||||||
TFilter memberFilter = filter[key.c_str()];
|
TFilter memberFilter = filter[key.c_str()];
|
||||||
|
|
||||||
if (memberFilter.allow()) {
|
if (memberFilter.allow()) {
|
||||||
VariantSlot* slot = object.get(adaptString(key.c_str()));
|
auto member = object.getMember(adaptString(key.c_str()));
|
||||||
if (!slot) {
|
if (!member) {
|
||||||
// Save key in memory pool.
|
// Save key in memory pool.
|
||||||
auto savedKey = stringBuilder_.save();
|
auto savedKey = stringBuilder_.save();
|
||||||
|
|
||||||
// Allocate slot in object
|
// Allocate slot in object
|
||||||
slot = resources_->allocVariant();
|
member = object.addMember(savedKey, resources_);
|
||||||
if (!slot)
|
if (!member)
|
||||||
return DeserializationError::NoMemory;
|
return DeserializationError::NoMemory;
|
||||||
|
|
||||||
slot->setKey(savedKey);
|
|
||||||
object.add(slot);
|
|
||||||
} else {
|
} else {
|
||||||
slot->data()->setNull(resources_);
|
member->setNull(resources_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse value
|
// Parse value
|
||||||
err =
|
err = parseVariant(*member, memberFilter, nestingLimit.decrement());
|
||||||
parseVariant(*slot->data(), memberFilter, nestingLimit.decrement());
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
} else {
|
} else {
|
||||||
|
@ -495,14 +495,9 @@ class MsgPackDeserializer {
|
|||||||
// Save key in memory pool.
|
// Save key in memory pool.
|
||||||
auto savedKey = stringBuilder_.save();
|
auto savedKey = stringBuilder_.save();
|
||||||
|
|
||||||
VariantSlot* slot = resources_->allocVariant();
|
member = object->addMember(savedKey, resources_);
|
||||||
if (!slot)
|
if (!member)
|
||||||
return DeserializationError::NoMemory;
|
return DeserializationError::NoMemory;
|
||||||
|
|
||||||
slot->setKey(savedKey);
|
|
||||||
object->add(slot);
|
|
||||||
|
|
||||||
member = slot->data();
|
|
||||||
} else {
|
} else {
|
||||||
member = 0;
|
member = 0;
|
||||||
}
|
}
|
||||||
|
@ -201,11 +201,6 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
|||||||
return detail::collectionToVariant(data_);
|
return detail::collectionToVariant(data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
void removeMember(TAdaptedString key) const {
|
|
||||||
collectionRemove(data_, data_->get(key), resources_);
|
|
||||||
}
|
|
||||||
|
|
||||||
detail::CollectionData* data_;
|
detail::CollectionData* data_;
|
||||||
detail::ResourceManager* resources_;
|
detail::ResourceManager* resources_;
|
||||||
};
|
};
|
||||||
|
@ -38,6 +38,8 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
union VariantContent {
|
union VariantContent {
|
||||||
|
VariantContent() {}
|
||||||
|
|
||||||
JsonFloat asFloat;
|
JsonFloat asFloat;
|
||||||
bool asBoolean;
|
bool asBoolean;
|
||||||
JsonUInt asUnsignedInteger;
|
JsonUInt asUnsignedInteger;
|
||||||
|
@ -211,7 +211,7 @@ class VariantData {
|
|||||||
auto array = asArray();
|
auto array = asArray();
|
||||||
if (!array)
|
if (!array)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return slotData(array->get(index));
|
return array->getElement(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
@ -219,28 +219,14 @@ class VariantData {
|
|||||||
auto object = asObject();
|
auto object = asObject();
|
||||||
if (!object)
|
if (!object)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return slotData(object->get(key));
|
return object->getMember(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantData* getOrAddElement(size_t index, ResourceManager* resources) {
|
VariantData* getOrAddElement(size_t index, ResourceManager* resources) {
|
||||||
auto array = isNull() ? &toArray() : asArray();
|
auto array = isNull() ? &toArray() : asArray();
|
||||||
if (!array)
|
if (!array)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
VariantSlot* slot = array->head();
|
return array->getOrAddElement(index, resources);
|
||||||
while (slot && index > 0) {
|
|
||||||
slot = slot->next();
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
if (!slot)
|
|
||||||
index++;
|
|
||||||
while (index > 0) {
|
|
||||||
slot = resources->allocVariant();
|
|
||||||
if (!slot)
|
|
||||||
return nullptr;
|
|
||||||
array->add(slot);
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
return slot->data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
@ -250,10 +236,7 @@ class VariantData {
|
|||||||
auto obj = isNull() ? &toObject() : asObject();
|
auto obj = isNull() ? &toObject() : asObject();
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
auto slot = obj->get(key);
|
return obj->getOrAddMember(key, resources);
|
||||||
if (slot)
|
|
||||||
return slot->data();
|
|
||||||
return collectionAddMember(obj, key, resources);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isArray() const {
|
bool isArray() const {
|
||||||
@ -446,7 +429,7 @@ class VariantData {
|
|||||||
|
|
||||||
CollectionData& toArray() {
|
CollectionData& toArray() {
|
||||||
setType(VALUE_IS_ARRAY);
|
setType(VALUE_IS_ARRAY);
|
||||||
content_.asCollection.clear();
|
new (&content_.asCollection) CollectionData();
|
||||||
return content_.asCollection;
|
return content_.asCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,7 +440,7 @@ class VariantData {
|
|||||||
|
|
||||||
CollectionData& toObject() {
|
CollectionData& toObject() {
|
||||||
setType(VALUE_IS_OBJECT);
|
setType(VALUE_IS_OBJECT);
|
||||||
content_.asCollection.clear();
|
new (&content_.asCollection) CollectionData();
|
||||||
return content_.asCollection;
|
return content_.asCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user