mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-20 05:52:30 +02:00
Extract ObjectData
from CollectionData
This commit is contained in:
@ -40,6 +40,7 @@
|
|||||||
#include "ArduinoJson/Memory/VariantPoolImpl.hpp"
|
#include "ArduinoJson/Memory/VariantPoolImpl.hpp"
|
||||||
#include "ArduinoJson/Object/JsonObjectImpl.hpp"
|
#include "ArduinoJson/Object/JsonObjectImpl.hpp"
|
||||||
#include "ArduinoJson/Object/MemberProxy.hpp"
|
#include "ArduinoJson/Object/MemberProxy.hpp"
|
||||||
|
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
||||||
#include "ArduinoJson/Variant/ConverterImpl.hpp"
|
#include "ArduinoJson/Variant/ConverterImpl.hpp"
|
||||||
#include "ArduinoJson/Variant/VariantCompare.hpp"
|
#include "ArduinoJson/Variant/VariantCompare.hpp"
|
||||||
|
|
||||||
|
@ -29,25 +29,10 @@ class CollectionData {
|
|||||||
size_t memoryUsage() const;
|
size_t memoryUsage() const;
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
|
|
||||||
VariantData* addMember(StringNode* key, ResourceManager* resources);
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
VariantData* addMember(TAdaptedString key, ResourceManager* resources);
|
|
||||||
|
|
||||||
void clear(ResourceManager* resources);
|
void clear(ResourceManager* resources);
|
||||||
bool copyFrom(const CollectionData& src, ResourceManager* resources);
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
VariantData* getOrAddMember(TAdaptedString key, ResourceManager* resources);
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
VariantData* getMember(TAdaptedString key) const;
|
|
||||||
|
|
||||||
void removeSlot(VariantSlot* slot, ResourceManager* resources);
|
void removeSlot(VariantSlot* slot, ResourceManager* resources);
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
void removeMember(TAdaptedString key, ResourceManager* resources);
|
|
||||||
|
|
||||||
VariantSlot* head() const {
|
VariantSlot* head() const {
|
||||||
return head_;
|
return head_;
|
||||||
}
|
}
|
||||||
@ -57,9 +42,6 @@ class CollectionData {
|
|||||||
protected:
|
protected:
|
||||||
void addSlot(VariantSlot*);
|
void addSlot(VariantSlot*);
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
VariantSlot* getSlot(TAdaptedString key) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VariantSlot* getPreviousSlot(VariantSlot*) const;
|
VariantSlot* getPreviousSlot(VariantSlot*) const;
|
||||||
};
|
};
|
||||||
@ -75,9 +57,4 @@ inline VariantData* collectionToVariant(CollectionData* collection) {
|
|||||||
return reinterpret_cast<VariantData*>(data);
|
return reinterpret_cast<VariantData*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool objectEquals(const detail::CollectionData& lhs,
|
|
||||||
const detail::CollectionData& rhs);
|
|
||||||
bool objectEquals(const detail::CollectionData* lhs,
|
|
||||||
const detail::CollectionData* rhs);
|
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
@ -14,22 +14,6 @@ inline void collectionClear(CollectionData* c, ResourceManager* resources) {
|
|||||||
c->clear(resources);
|
c->clear(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool collectionCopy(CollectionData* dst, const CollectionData* src,
|
|
||||||
ResourceManager* resources) {
|
|
||||||
if (!dst || !src)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return dst->copyFrom(*src, resources);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
inline VariantData* collectionGetMember(const CollectionData* obj,
|
|
||||||
TAdaptedString key) {
|
|
||||||
if (!obj)
|
|
||||||
return nullptr;
|
|
||||||
return obj->getMember(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void collectionRemove(CollectionData* data, VariantSlot* slot,
|
inline void collectionRemove(CollectionData* data, VariantSlot* slot,
|
||||||
ResourceManager* resources) {
|
ResourceManager* resources) {
|
||||||
if (!data)
|
if (!data)
|
||||||
@ -37,12 +21,4 @@ inline void collectionRemove(CollectionData* data, VariantSlot* slot,
|
|||||||
data->removeSlot(slot, resources);
|
data->removeSlot(slot, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
inline void collectionRemoveMember(CollectionData* obj, TAdaptedString key,
|
|
||||||
ResourceManager* resources) {
|
|
||||||
if (!obj)
|
|
||||||
return;
|
|
||||||
obj->removeMember(key, resources);
|
|
||||||
}
|
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
@ -23,51 +23,6 @@ inline void CollectionData::addSlot(VariantSlot* slot) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
VariantData* CollectionData::getOrAddMember(TAdaptedString key,
|
|
||||||
ResourceManager* resources) {
|
|
||||||
auto slot = getSlot(key);
|
|
||||||
if (slot)
|
|
||||||
return slot->data();
|
|
||||||
return addMember(key, resources);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
@ -75,34 +30,6 @@ inline void CollectionData::clear(ResourceManager* resources) {
|
|||||||
tail_ = 0;
|
tail_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool CollectionData::copyFrom(const CollectionData& src,
|
|
||||||
ResourceManager* resources) {
|
|
||||||
clear(resources);
|
|
||||||
|
|
||||||
for (VariantSlot* s = src.head(); s; s = s->next()) {
|
|
||||||
ARDUINOJSON_ASSERT(s->key() != 0);
|
|
||||||
JsonString key(s->key(),
|
|
||||||
s->ownsKey() ? JsonString::Copied : JsonString::Linked);
|
|
||||||
auto var = addMember(adaptString(key), resources);
|
|
||||||
if (!variantCopyFrom(var, s->data(), resources))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
|
|
||||||
if (key.isNull())
|
|
||||||
return 0;
|
|
||||||
VariantSlot* slot = head_;
|
|
||||||
while (slot) {
|
|
||||||
if (stringEquals(key, adaptString(slot->key())))
|
|
||||||
break;
|
|
||||||
slot = slot->next();
|
|
||||||
}
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
|
inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
|
||||||
VariantSlot* current = head_;
|
VariantSlot* current = head_;
|
||||||
while (current) {
|
while (current) {
|
||||||
@ -129,12 +56,6 @@ inline void CollectionData::removeSlot(VariantSlot* slot,
|
|||||||
slotRelease(slot, resources);
|
slotRelease(slot, 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 {
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
for (VariantSlot* s = head_; s; s = s->next()) {
|
for (VariantSlot* s = head_; s; s = s->next()) {
|
||||||
@ -165,27 +86,4 @@ inline void CollectionData::movePointers(ptrdiff_t variantDistance) {
|
|||||||
slot->data()->movePointers(variantDistance);
|
slot->data()->movePointers(variantDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool objectEquals(const CollectionData& lhs, const CollectionData& rhs) {
|
|
||||||
size_t count = 0;
|
|
||||||
for (auto a = lhs.head(); a; a = a->next()) {
|
|
||||||
auto b = rhs.getMember(adaptString(a->key()));
|
|
||||||
if (!b)
|
|
||||||
return false;
|
|
||||||
if (compare(a->data(), b) != COMPARE_RESULT_EQUAL)
|
|
||||||
return false;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
return count == rhs.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool objectEquals(const CollectionData* lhs, const CollectionData* rhs) {
|
|
||||||
if (lhs == rhs)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (!lhs || !rhs)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return objectEquals(*lhs, *rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
@ -232,7 +232,7 @@ class JsonDeserializer {
|
|||||||
|
|
||||||
template <typename TFilter>
|
template <typename TFilter>
|
||||||
DeserializationError::Code parseObject(
|
DeserializationError::Code parseObject(
|
||||||
CollectionData& object, TFilter filter,
|
ObjectData& object, TFilter filter,
|
||||||
DeserializationOption::NestingLimit nestingLimit) {
|
DeserializationOption::NestingLimit nestingLimit) {
|
||||||
DeserializationError::Code err;
|
DeserializationError::Code err;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class JsonSerializer : public Visitor<size_t> {
|
|||||||
return bytesWritten();
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t visitObject(const CollectionData& object) {
|
size_t visitObject(const ObjectData& object) {
|
||||||
write('{');
|
write('{');
|
||||||
|
|
||||||
const VariantSlot* slot = object.head();
|
const VariantSlot* slot = object.head();
|
||||||
|
@ -39,7 +39,7 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
|||||||
return this->bytesWritten();
|
return this->bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t visitObject(const CollectionData& object) {
|
size_t visitObject(const ObjectData& object) {
|
||||||
const VariantSlot* slot = object.head();
|
const VariantSlot* slot = object.head();
|
||||||
if (slot) {
|
if (slot) {
|
||||||
base::write("{\r\n");
|
base::write("{\r\n");
|
||||||
|
@ -472,7 +472,7 @@ class MsgPackDeserializer {
|
|||||||
if (nestingLimit.reached())
|
if (nestingLimit.reached())
|
||||||
return DeserializationError::TooDeep;
|
return DeserializationError::TooDeep;
|
||||||
|
|
||||||
CollectionData* object;
|
ObjectData* object;
|
||||||
if (filter.allowObject()) {
|
if (filter.allowObject()) {
|
||||||
ARDUINOJSON_ASSERT(variant != 0);
|
ARDUINOJSON_ASSERT(variant != 0);
|
||||||
object = &variant->toObject();
|
object = &variant->toObject();
|
||||||
|
@ -61,7 +61,7 @@ class MsgPackSerializer : public Visitor<size_t> {
|
|||||||
return bytesWritten();
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t visitObject(const CollectionData& object) {
|
size_t visitObject(const ObjectData& object) {
|
||||||
size_t n = object.size();
|
size_t n = object.size();
|
||||||
if (n < 0x10) {
|
if (n < 0x10) {
|
||||||
writeByte(uint8_t(0x80 + n));
|
writeByte(uint8_t(0x80 + n));
|
||||||
|
@ -23,7 +23,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
|||||||
FORCE_INLINE JsonObject() : data_(0), resources_(0) {}
|
FORCE_INLINE JsonObject() : data_(0), resources_(0) {}
|
||||||
|
|
||||||
// INTERNAL USE ONLY
|
// INTERNAL USE ONLY
|
||||||
FORCE_INLINE JsonObject(detail::CollectionData* data,
|
FORCE_INLINE JsonObject(detail::ObjectData* data,
|
||||||
detail::ResourceManager* resource)
|
detail::ResourceManager* resource)
|
||||||
: data_(data), resources_(resource) {}
|
: data_(data), resources_(resource) {}
|
||||||
|
|
||||||
@ -95,12 +95,12 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
|||||||
// Copies an object.
|
// Copies an object.
|
||||||
// https://arduinojson.org/v6/api/jsonobject/set/
|
// https://arduinojson.org/v6/api/jsonobject/set/
|
||||||
FORCE_INLINE bool set(JsonObjectConst src) {
|
FORCE_INLINE bool set(JsonObjectConst src) {
|
||||||
return collectionCopy(data_, src.data_, resources_);
|
return detail::ObjectData::copy(data_, src.data_, resources_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compares the content of two objects.
|
// Compares the content of two objects.
|
||||||
FORCE_INLINE bool operator==(JsonObject rhs) const {
|
FORCE_INLINE bool operator==(JsonObject rhs) const {
|
||||||
return objectEquals(data_, rhs.data_);
|
return detail::ObjectData::equals(data_, rhs.data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets or sets the member with specified key.
|
// Gets or sets the member with specified key.
|
||||||
@ -135,7 +135,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
|||||||
// https://arduinojson.org/v6/api/jsonobject/remove/
|
// https://arduinojson.org/v6/api/jsonobject/remove/
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE void remove(const TString& key) const {
|
FORCE_INLINE void remove(const TString& key) const {
|
||||||
collectionRemoveMember(data_, detail::adaptString(key), resources_);
|
detail::ObjectData::removeMember(data_, detail::adaptString(key),
|
||||||
|
resources_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes the member with the specified key.
|
// Removes the member with the specified key.
|
||||||
@ -143,7 +144,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
|||||||
// https://arduinojson.org/v6/api/jsonobject/remove/
|
// https://arduinojson.org/v6/api/jsonobject/remove/
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE void remove(TChar* key) const {
|
FORCE_INLINE void remove(TChar* key) const {
|
||||||
collectionRemoveMember(data_, detail::adaptString(key), resources_);
|
detail::ObjectData::removeMember(data_, detail::adaptString(key),
|
||||||
|
resources_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the object contains the specified key.
|
// Returns true if the object contains the specified key.
|
||||||
@ -152,7 +154,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
|||||||
FORCE_INLINE
|
FORCE_INLINE
|
||||||
typename detail::enable_if<detail::IsString<TString>::value, bool>::type
|
typename detail::enable_if<detail::IsString<TString>::value, bool>::type
|
||||||
containsKey(const TString& key) const {
|
containsKey(const TString& key) const {
|
||||||
return collectionGetMember(data_, detail::adaptString(key)) != 0;
|
return detail::ObjectData::getMember(data_, detail::adaptString(key)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the object contains the specified key.
|
// Returns true if the object contains the specified key.
|
||||||
@ -161,7 +163,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
|||||||
FORCE_INLINE
|
FORCE_INLINE
|
||||||
typename detail::enable_if<detail::IsString<TChar*>::value, bool>::type
|
typename detail::enable_if<detail::IsString<TChar*>::value, bool>::type
|
||||||
containsKey(TChar* key) const {
|
containsKey(TChar* key) const {
|
||||||
return collectionGetMember(data_, detail::adaptString(key)) != 0;
|
return detail::ObjectData::getMember(data_, detail::adaptString(key)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an array and adds it to the object.
|
// Creates an array and adds it to the object.
|
||||||
@ -201,7 +203,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
|||||||
return detail::collectionToVariant(data_);
|
return detail::collectionToVariant(data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::CollectionData* data_;
|
detail::ObjectData* data_;
|
||||||
detail::ResourceManager* resources_;
|
detail::ResourceManager* resources_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
|||||||
JsonObjectConst() : data_(0) {}
|
JsonObjectConst() : data_(0) {}
|
||||||
|
|
||||||
// INTERNAL USE ONLY
|
// INTERNAL USE ONLY
|
||||||
JsonObjectConst(const detail::CollectionData* data) : data_(data) {}
|
JsonObjectConst(const detail::ObjectData* data) : data_(data) {}
|
||||||
|
|
||||||
operator JsonVariantConst() const {
|
operator JsonVariantConst() const {
|
||||||
return JsonVariantConst(collectionToVariant(data_));
|
return JsonVariantConst(collectionToVariant(data_));
|
||||||
@ -76,14 +76,14 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
|||||||
// https://arduinojson.org/v6/api/jsonobjectconst/containskey/
|
// https://arduinojson.org/v6/api/jsonobjectconst/containskey/
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE bool containsKey(const TString& key) const {
|
FORCE_INLINE bool containsKey(const TString& key) const {
|
||||||
return collectionGetMember(data_, detail::adaptString(key)) != 0;
|
return detail::ObjectData::getMember(data_, detail::adaptString(key)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the object contains the specified key.
|
// Returns true if the object contains the specified key.
|
||||||
// https://arduinojson.org/v6/api/jsonobjectconst/containskey/
|
// https://arduinojson.org/v6/api/jsonobjectconst/containskey/
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE bool containsKey(TChar* key) const {
|
FORCE_INLINE bool containsKey(TChar* key) const {
|
||||||
return collectionGetMember(data_, detail::adaptString(key)) != 0;
|
return detail::ObjectData::getMember(data_, detail::adaptString(key)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the member with specified key.
|
// Gets the member with specified key.
|
||||||
@ -93,7 +93,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
|||||||
JsonVariantConst>::type
|
JsonVariantConst>::type
|
||||||
operator[](const TString& key) const {
|
operator[](const TString& key) const {
|
||||||
return JsonVariantConst(
|
return JsonVariantConst(
|
||||||
collectionGetMember(data_, detail::adaptString(key)));
|
detail::ObjectData::getMember(data_, detail::adaptString(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the member with specified key.
|
// Gets the member with specified key.
|
||||||
@ -103,12 +103,12 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
|||||||
JsonVariantConst>::type
|
JsonVariantConst>::type
|
||||||
operator[](TChar* key) const {
|
operator[](TChar* key) const {
|
||||||
return JsonVariantConst(
|
return JsonVariantConst(
|
||||||
collectionGetMember(data_, detail::adaptString(key)));
|
detail::ObjectData::getMember(data_, detail::adaptString(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compares objects.
|
// Compares objects.
|
||||||
FORCE_INLINE bool operator==(JsonObjectConst rhs) const {
|
FORCE_INLINE bool operator==(JsonObjectConst rhs) const {
|
||||||
return objectEquals(data_, rhs.data_);
|
return detail::ObjectData::equals(data_, rhs.data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -116,7 +116,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
|||||||
return collectionToVariant(data_);
|
return collectionToVariant(data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
const detail::CollectionData* data_;
|
const detail::ObjectData* data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
69
src/ArduinoJson/Object/ObjectData.hpp
Normal file
69
src/ArduinoJson/Object/ObjectData.hpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright © 2014-2023, Benoit BLANCHON
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||||
|
|
||||||
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
|
class ObjectData : public CollectionData {
|
||||||
|
public:
|
||||||
|
VariantData* addMember(StringNode* key, ResourceManager* resources);
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
VariantData* addMember(TAdaptedString key, ResourceManager* resources);
|
||||||
|
|
||||||
|
bool copyFrom(const ObjectData& src, ResourceManager* resources);
|
||||||
|
|
||||||
|
static bool copy(ObjectData* dst, const ObjectData* src,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
if (!dst || !src)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return dst->copyFrom(*src, resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equals(const ObjectData& other) const;
|
||||||
|
|
||||||
|
static bool equals(const ObjectData* lhs, const ObjectData* rhs) {
|
||||||
|
if (lhs == rhs)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!lhs || !rhs)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return lhs->equals(*rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
VariantData* getOrAddMember(TAdaptedString key, ResourceManager* resources);
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
VariantData* getMember(TAdaptedString key) const;
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
static VariantData* getMember(const ObjectData* object, TAdaptedString key) {
|
||||||
|
if (!object)
|
||||||
|
return nullptr;
|
||||||
|
return object->getMember(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
void removeMember(TAdaptedString key, ResourceManager* resources);
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
static void removeMember(ObjectData* obj, TAdaptedString key,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
if (!obj)
|
||||||
|
return;
|
||||||
|
obj->removeMember(key, resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
VariantSlot* getSlot(TAdaptedString key) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
104
src/ArduinoJson/Object/ObjectImpl.hpp
Normal file
104
src/ArduinoJson/Object/ObjectImpl.hpp
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright © 2014-2023, Benoit BLANCHON
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Object/ObjectData.hpp>
|
||||||
|
#include <ArduinoJson/Variant/VariantCompare.hpp>
|
||||||
|
|
||||||
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
|
inline VariantData* ObjectData::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* ObjectData::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();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool ObjectData::copyFrom(const ObjectData& src,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
clear(resources);
|
||||||
|
|
||||||
|
for (VariantSlot* s = src.head(); s; s = s->next()) {
|
||||||
|
ARDUINOJSON_ASSERT(s->key() != 0);
|
||||||
|
JsonString key(s->key(),
|
||||||
|
s->ownsKey() ? JsonString::Copied : JsonString::Linked);
|
||||||
|
auto var = addMember(adaptString(key), resources);
|
||||||
|
if (!variantCopyFrom(var, s->data(), resources))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool ObjectData::equals(const ObjectData& other) const {
|
||||||
|
size_t count = 0;
|
||||||
|
for (auto a = head(); a; a = a->next()) {
|
||||||
|
auto b = other.getMember(adaptString(a->key()));
|
||||||
|
if (!b)
|
||||||
|
return false;
|
||||||
|
if (compare(a->data(), b) != COMPARE_RESULT_EQUAL)
|
||||||
|
return false;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count == other.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
inline VariantData* ObjectData::getMember(TAdaptedString key) const {
|
||||||
|
return slotData(getSlot(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
VariantData* ObjectData::getOrAddMember(TAdaptedString key,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
auto slot = getSlot(key);
|
||||||
|
if (slot)
|
||||||
|
return slot->data();
|
||||||
|
return addMember(key, resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
inline VariantSlot* ObjectData::getSlot(TAdaptedString key) const {
|
||||||
|
if (key.isNull())
|
||||||
|
return 0;
|
||||||
|
VariantSlot* slot = head();
|
||||||
|
while (slot) {
|
||||||
|
if (stringEquals(key, adaptString(slot->key())))
|
||||||
|
break;
|
||||||
|
slot = slot->next();
|
||||||
|
}
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
inline void ObjectData::removeMember(TAdaptedString key,
|
||||||
|
ResourceManager* resources) {
|
||||||
|
removeSlot(getSlot(key), resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
@ -92,12 +92,12 @@ struct ArrayComparer : ComparerBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ObjectComparer : ComparerBase {
|
struct ObjectComparer : ComparerBase {
|
||||||
const CollectionData* rhs_;
|
const ObjectData* rhs_;
|
||||||
|
|
||||||
explicit ObjectComparer(const CollectionData& rhs) : rhs_(&rhs) {}
|
explicit ObjectComparer(const ObjectData& rhs) : rhs_(&rhs) {}
|
||||||
|
|
||||||
CompareResult visitObject(const CollectionData& lhs) {
|
CompareResult visitObject(const ObjectData& lhs) {
|
||||||
if (objectEquals(lhs, *rhs_))
|
if (rhs_->equals(lhs))
|
||||||
return COMPARE_RESULT_EQUAL;
|
return COMPARE_RESULT_EQUAL;
|
||||||
else
|
else
|
||||||
return COMPARE_RESULT_DIFFER;
|
return COMPARE_RESULT_DIFFER;
|
||||||
@ -133,7 +133,7 @@ struct VariantComparer : ComparerBase {
|
|||||||
return accept(comparer);
|
return accept(comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompareResult visitObject(const CollectionData& lhs) {
|
CompareResult visitObject(const ObjectData& lhs) {
|
||||||
ObjectComparer comparer(lhs);
|
ObjectComparer comparer(lhs);
|
||||||
return accept(comparer);
|
return accept(comparer);
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,9 @@
|
|||||||
#include <stddef.h> // size_t
|
#include <stddef.h> // size_t
|
||||||
|
|
||||||
#include <ArduinoJson/Array/ArrayData.hpp>
|
#include <ArduinoJson/Array/ArrayData.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>
|
||||||
|
#include <ArduinoJson/Object/ObjectData.hpp>
|
||||||
|
|
||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
@ -46,8 +45,9 @@ union VariantContent {
|
|||||||
bool asBoolean;
|
bool asBoolean;
|
||||||
JsonUInt asUnsignedInteger;
|
JsonUInt asUnsignedInteger;
|
||||||
JsonInteger asSignedInteger;
|
JsonInteger asSignedInteger;
|
||||||
CollectionData asCollection;
|
|
||||||
ArrayData asArray;
|
ArrayData asArray;
|
||||||
|
ObjectData asObject;
|
||||||
|
CollectionData asCollection;
|
||||||
const char* asLinkedString;
|
const char* asLinkedString;
|
||||||
struct StringNode* asOwnedString;
|
struct StringNode* asOwnedString;
|
||||||
};
|
};
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
|
|
||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
bool collectionCopy(CollectionData* dst, const CollectionData* src,
|
|
||||||
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);
|
||||||
@ -37,7 +35,7 @@ class VariantData {
|
|||||||
return visitor.visitArray(content_.asArray);
|
return visitor.visitArray(content_.asArray);
|
||||||
|
|
||||||
case VALUE_IS_OBJECT:
|
case VALUE_IS_OBJECT:
|
||||||
return visitor.visitObject(content_.asCollection);
|
return visitor.visitObject(content_.asObject);
|
||||||
|
|
||||||
case VALUE_IS_LINKED_STRING:
|
case VALUE_IS_LINKED_STRING:
|
||||||
return visitor.visitString(content_.asLinkedString,
|
return visitor.visitString(content_.asLinkedString,
|
||||||
@ -139,11 +137,11 @@ class VariantData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionData* asObject() {
|
ObjectData* asObject() {
|
||||||
return isObject() ? &content_.asCollection : 0;
|
return isObject() ? &content_.asObject : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CollectionData* asObject() const {
|
const ObjectData* asObject() const {
|
||||||
return const_cast<VariantData*>(this)->asObject();
|
return const_cast<VariantData*>(this)->asObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +177,7 @@ class VariantData {
|
|||||||
case VALUE_IS_ARRAY:
|
case VALUE_IS_ARRAY:
|
||||||
return toArray().copyFrom(*src->asArray(), resources);
|
return toArray().copyFrom(*src->asArray(), resources);
|
||||||
case VALUE_IS_OBJECT:
|
case VALUE_IS_OBJECT:
|
||||||
return collectionCopy(&toObject(), src->asObject(), resources);
|
return toObject().copyFrom(*src->asObject(), resources);
|
||||||
case VALUE_IS_OWNED_STRING: {
|
case VALUE_IS_OWNED_STRING: {
|
||||||
auto str = adaptString(src->asString());
|
auto str = adaptString(src->asString());
|
||||||
auto dup = resources->saveString(str);
|
auto dup = resources->saveString(str);
|
||||||
@ -320,7 +318,7 @@ class VariantData {
|
|||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
void removeMember(TAdaptedString key, ResourceManager* resources) {
|
void removeMember(TAdaptedString key, ResourceManager* resources) {
|
||||||
collectionRemoveMember(asObject(), key, resources);
|
ObjectData::removeMember(asObject(), key, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
@ -434,13 +432,13 @@ class VariantData {
|
|||||||
return toArray();
|
return toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionData& toObject() {
|
ObjectData& toObject() {
|
||||||
setType(VALUE_IS_OBJECT);
|
setType(VALUE_IS_OBJECT);
|
||||||
new (&content_.asCollection) CollectionData();
|
new (&content_.asObject) ObjectData();
|
||||||
return content_.asCollection;
|
return content_.asObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionData& toObject(ResourceManager* resources) {
|
ObjectData& toObject(ResourceManager* resources) {
|
||||||
release(resources);
|
release(resources);
|
||||||
return toObject();
|
return toObject();
|
||||||
}
|
}
|
||||||
@ -596,7 +594,7 @@ inline ArrayData* variantToArray(VariantData* var, ResourceManager* resources) {
|
|||||||
return &var->toArray(resources);
|
return &var->toArray(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline CollectionData* variantToObject(VariantData* var,
|
inline ObjectData* variantToObject(VariantData* var,
|
||||||
ResourceManager* resources) {
|
ResourceManager* resources) {
|
||||||
if (!var)
|
if (!var)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
#include <ArduinoJson/Array/ArrayData.hpp>
|
||||||
#include <ArduinoJson/Numbers/JsonFloat.hpp>
|
#include <ArduinoJson/Numbers/JsonFloat.hpp>
|
||||||
#include <ArduinoJson/Numbers/JsonInteger.hpp>
|
#include <ArduinoJson/Numbers/JsonInteger.hpp>
|
||||||
|
#include <ArduinoJson/Object/ObjectData.hpp>
|
||||||
|
|
||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ struct Visitor {
|
|||||||
return TResult();
|
return TResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
TResult visitObject(const CollectionData&) {
|
TResult visitObject(const ObjectData&) {
|
||||||
return TResult();
|
return TResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user