Compare commits

..

5 Commits

Author SHA1 Message Date
cc73fec1cf JsonObject: replace ObjectData* member with VariantData* 2025-06-15 12:55:13 +02:00
535a9b3e86 JsonArray: replace ArrayData* member with VariantData* 2025-06-15 12:35:31 +02:00
72075e9ad2 JsonObjectConst: replace ObjectData* member with VariantData* 2025-06-15 12:34:38 +02:00
56b269bea8 JsonArrayConst: replace ArrayData* member with VariantData* 2025-06-15 12:32:37 +02:00
817998d0fe Add a pool dedicated to 8-byte values (double/int64_t/uint64_t)
This new pool replaced the "extension" slot where a secondary variant slot was used to store 8-byte values.
2025-06-02 19:39:27 +02:00
9 changed files with 98 additions and 78 deletions

View File

@ -10,7 +10,7 @@ static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN");
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE"); static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
static_assert(sizeof(VariantData) == 8, "slot size"); static_assert(sizeof(ArduinoJson::detail::VariantData) == 8, "slot size");
void setup() {} void setup() {}
void loop() {} void loop() {}

View File

@ -23,7 +23,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
JsonArray() : data_(0), resources_(0) {} JsonArray() : data_(0), resources_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
JsonArray(detail::ArrayData* data, detail::ResourceManager* resources) JsonArray(detail::VariantData* data, detail::ResourceManager* resources)
: data_(data), resources_(resources) {} : data_(data), resources_(resources) {}
// Returns a JsonVariant pointing to the array. // Returns a JsonVariant pointing to the array.
@ -37,7 +37,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Returns a read-only reference to the array. // Returns a read-only reference to the array.
// https://arduinojson.org/v7/api/jsonarrayconst/ // https://arduinojson.org/v7/api/jsonarrayconst/
operator JsonArrayConst() const { operator JsonArrayConst() const {
return JsonArrayConst(data_, resources_); return JsonArrayConst(getData(), resources_);
} }
// Appends a new (empty) element to the array. // Appends a new (empty) element to the array.
@ -55,7 +55,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
template <typename T, detail::enable_if_t< template <typename T, detail::enable_if_t<
detail::is_same<T, JsonVariant>::value, int> = 0> detail::is_same<T, JsonVariant>::value, int> = 0>
JsonVariant add() const { JsonVariant add() const {
return JsonVariant(detail::ArrayData::addElement(data_, resources_), return JsonVariant(detail::VariantData::addElement(data_, resources_),
resources_); resources_);
} }
@ -63,7 +63,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// https://arduinojson.org/v7/api/jsonarray/add/ // https://arduinojson.org/v7/api/jsonarray/add/
template <typename T> template <typename T>
bool add(const T& value) const { bool add(const T& value) const {
return detail::ArrayData::addValue(data_, value, resources_); return detail::VariantData::addValue(data_, value, resources_);
} }
// Appends a value to the array. // Appends a value to the array.
@ -71,15 +71,16 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
template <typename T, template <typename T,
detail::enable_if_t<!detail::is_const<T>::value, int> = 0> detail::enable_if_t<!detail::is_const<T>::value, int> = 0>
bool add(T* value) const { bool add(T* value) const {
return detail::ArrayData::addValue(data_, value, resources_); return detail::VariantData::addValue(data_, value, resources_);
} }
// Returns an iterator to the first element of the array. // Returns an iterator to the first element of the array.
// https://arduinojson.org/v7/api/jsonarray/begin/ // https://arduinojson.org/v7/api/jsonarray/begin/
iterator begin() const { iterator begin() const {
if (!data_) auto array = detail::VariantData::asArray(data_);
if (!array)
return iterator(); return iterator();
return iterator(data_->createIterator(resources_), resources_); return iterator(array->createIterator(resources_), resources_);
} }
// Returns an iterator following the last element of the array. // Returns an iterator following the last element of the array.
@ -106,13 +107,14 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Removes the element at the specified iterator. // Removes the element at the specified iterator.
// https://arduinojson.org/v7/api/jsonarray/remove/ // https://arduinojson.org/v7/api/jsonarray/remove/
void remove(iterator it) const { void remove(iterator it) const {
detail::ArrayData::remove(data_, it.iterator_, resources_); detail::ArrayData::remove(detail::VariantData::asArray(data_), it.iterator_,
resources_);
} }
// Removes the element at the specified index. // Removes the element at the specified index.
// https://arduinojson.org/v7/api/jsonarray/remove/ // https://arduinojson.org/v7/api/jsonarray/remove/
void remove(size_t index) const { void remove(size_t index) const {
detail::ArrayData::removeElement(data_, index, resources_); detail::VariantData::removeElement(data_, index, resources_);
} }
// Removes the element at the specified index. // Removes the element at the specified index.
@ -127,7 +129,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Removes all the elements of the array. // Removes all the elements of the array.
// https://arduinojson.org/v7/api/jsonarray/clear/ // https://arduinojson.org/v7/api/jsonarray/clear/
void clear() const { void clear() const {
detail::ArrayData::clear(data_, resources_); detail::ArrayData::clear(detail::VariantData::asArray(data_), resources_);
} }
// Gets or sets the element at the specified index. // Gets or sets the element at the specified index.
@ -150,25 +152,25 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
} }
operator JsonVariantConst() const { operator JsonVariantConst() const {
return JsonVariantConst(collectionToVariant(data_), resources_); return JsonVariantConst(data_, resources_);
} }
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
// https://arduinojson.org/v7/api/jsonarray/isnull/ // https://arduinojson.org/v7/api/jsonarray/isnull/
bool isNull() const { bool isNull() const {
return data_ == 0; return !data_ || !data_->isArray();
} }
// Returns true if the reference is bound. // Returns true if the reference is bound.
// https://arduinojson.org/v7/api/jsonarray/isnull/ // https://arduinojson.org/v7/api/jsonarray/isnull/
operator bool() const { operator bool() const {
return data_ != 0; return !isNull();
} }
// Returns the depth (nesting level) of the array. // Returns the depth (nesting level) of the array.
// https://arduinojson.org/v7/api/jsonarray/nesting/ // https://arduinojson.org/v7/api/jsonarray/nesting/
size_t nesting() const { size_t nesting() const {
return detail::VariantData::nesting(collectionToVariant(data_), resources_); return detail::VariantData::nesting(data_, resources_);
} }
// Returns the number of elements in the array. // Returns the number of elements in the array.
@ -205,14 +207,14 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
} }
detail::VariantData* getData() const { detail::VariantData* getData() const {
return collectionToVariant(data_); return data_;
} }
detail::VariantData* getOrCreateData() const { detail::VariantData* getOrCreateData() const {
return collectionToVariant(data_); return data_;
} }
detail::ArrayData* data_; detail::VariantData* data_;
detail::ResourceManager* resources_; detail::ResourceManager* resources_;
}; };

View File

@ -24,9 +24,10 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
// Returns an iterator to the first element of the array. // Returns an iterator to the first element of the array.
// https://arduinojson.org/v7/api/jsonarrayconst/begin/ // https://arduinojson.org/v7/api/jsonarrayconst/begin/
iterator begin() const { iterator begin() const {
if (!data_) auto array = detail::VariantData::asArray(data_);
if (!array)
return iterator(); return iterator();
return iterator(data_->createIterator(resources_), resources_); return iterator(array->createIterator(resources_), resources_);
} }
// Returns an iterator to the element following the last element of the array. // Returns an iterator to the element following the last element of the array.
@ -39,7 +40,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
JsonArrayConst() : data_(0), resources_(0) {} JsonArrayConst() : data_(0), resources_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
JsonArrayConst(const detail::ArrayData* data, JsonArrayConst(const detail::VariantData* data,
const detail::ResourceManager* resources) const detail::ResourceManager* resources)
: data_(data), resources_(resources) {} : data_(data), resources_(resources) {}
@ -49,7 +50,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
detail::enable_if_t<detail::is_integral<T>::value, int> = 0> detail::enable_if_t<detail::is_integral<T>::value, int> = 0>
JsonVariantConst operator[](T index) const { JsonVariantConst operator[](T index) const {
return JsonVariantConst( return JsonVariantConst(
detail::ArrayData::getElement(data_, size_t(index), resources_), detail::VariantData::getElement(data_, size_t(index), resources_),
resources_); resources_);
} }
@ -71,13 +72,13 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
// https://arduinojson.org/v7/api/jsonarrayconst/isnull/ // https://arduinojson.org/v7/api/jsonarrayconst/isnull/
bool isNull() const { bool isNull() const {
return data_ == 0; return !data_ || !data_->isArray();
} }
// Returns true if the reference is bound. // Returns true if the reference is bound.
// https://arduinojson.org/v7/api/jsonarrayconst/isnull/ // https://arduinojson.org/v7/api/jsonarrayconst/isnull/
operator bool() const { operator bool() const {
return data_ != 0; return !isNull();
} }
// Returns the depth (nesting level) of the array. // Returns the depth (nesting level) of the array.
@ -100,10 +101,10 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
private: private:
const detail::VariantData* getData() const { const detail::VariantData* getData() const {
return collectionToVariant(data_); return data_;
} }
const detail::ArrayData* data_; const detail::VariantData* data_;
const detail::ResourceManager* resources_; const detail::ResourceManager* resources_;
}; };

View File

@ -23,7 +23,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
JsonObject() : data_(0), resources_(0) {} JsonObject() : data_(0), resources_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
JsonObject(detail::ObjectData* data, detail::ResourceManager* resource) JsonObject(detail::VariantData* data, detail::ResourceManager* resource)
: data_(data), resources_(resource) {} : data_(data), resources_(resource) {}
operator JsonVariant() const { operator JsonVariant() const {
@ -37,25 +37,25 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
} }
operator JsonVariantConst() const { operator JsonVariantConst() const {
return JsonVariantConst(collectionToVariant(data_), resources_); return JsonVariantConst(data_, resources_);
} }
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
// https://arduinojson.org/v7/api/jsonobject/isnull/ // https://arduinojson.org/v7/api/jsonobject/isnull/
bool isNull() const { bool isNull() const {
return data_ == 0; return !data_ || !data_->isObject();
} }
// Returns true if the reference is bound. // Returns true if the reference is bound.
// https://arduinojson.org/v7/api/jsonobject/isnull/ // https://arduinojson.org/v7/api/jsonobject/isnull/
operator bool() const { operator bool() const {
return data_ != 0; return !isNull();
} }
// Returns the depth (nesting level) of the object. // Returns the depth (nesting level) of the object.
// https://arduinojson.org/v7/api/jsonobject/nesting/ // https://arduinojson.org/v7/api/jsonobject/nesting/
size_t nesting() const { size_t nesting() const {
return detail::VariantData::nesting(collectionToVariant(data_), resources_); return detail::VariantData::nesting(data_, resources_);
} }
// Returns the number of members in the object. // Returns the number of members in the object.
@ -67,9 +67,10 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Returns an iterator to the first key-value pair of the object. // Returns an iterator to the first key-value pair of the object.
// https://arduinojson.org/v7/api/jsonobject/begin/ // https://arduinojson.org/v7/api/jsonobject/begin/
iterator begin() const { iterator begin() const {
if (!data_) auto obj = detail::VariantData::asObject(data_);
if (!obj)
return iterator(); return iterator();
return iterator(data_->createIterator(resources_), resources_); return iterator(obj->createIterator(resources_), resources_);
} }
// Returns an iterator following the last key-value pair of the object. // Returns an iterator following the last key-value pair of the object.
@ -81,7 +82,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Removes all the members of the object. // Removes all the members of the object.
// https://arduinojson.org/v7/api/jsonobject/clear/ // https://arduinojson.org/v7/api/jsonobject/clear/
void clear() const { void clear() const {
detail::ObjectData::clear(data_, resources_); detail::ObjectData::clear(detail::VariantData::asObject(data_), resources_);
} }
// Copies an object. // Copies an object.
@ -131,7 +132,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Removes the member at the specified iterator. // Removes the member at the specified iterator.
// https://arduinojson.org/v7/api/jsonobject/remove/ // https://arduinojson.org/v7/api/jsonobject/remove/
FORCE_INLINE void remove(iterator it) const { FORCE_INLINE void remove(iterator it) const {
detail::ObjectData::remove(data_, it.iterator_, resources_); detail::ObjectData::remove(detail::VariantData::asObject(data_),
it.iterator_, resources_);
} }
// Removes the member with the specified key. // Removes the member with the specified key.
@ -139,8 +141,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
template <typename TString, template <typename TString,
detail::enable_if_t<detail::IsString<TString>::value, int> = 0> detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
void remove(const TString& key) const { void remove(const TString& key) const {
detail::ObjectData::removeMember(data_, detail::adaptString(key), detail::VariantData::removeMember(data_, detail::adaptString(key),
resources_); resources_);
} }
// Removes the member with the specified key. // Removes the member with the specified key.
@ -156,8 +158,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// https://arduinojson.org/v7/api/jsonobject/remove/ // https://arduinojson.org/v7/api/jsonobject/remove/
template <typename TChar> template <typename TChar>
FORCE_INLINE void remove(TChar* key) const { FORCE_INLINE void remove(TChar* key) const {
detail::ObjectData::removeMember(data_, detail::adaptString(key), detail::VariantData::removeMember(data_, detail::adaptString(key),
resources_); resources_);
} }
// DEPRECATED: use obj[key].is<T>() instead // DEPRECATED: use obj[key].is<T>() instead
@ -166,8 +168,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
detail::enable_if_t<detail::IsString<TString>::value, int> = 0> detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
ARDUINOJSON_DEPRECATED("use obj[key].is<T>() instead") ARDUINOJSON_DEPRECATED("use obj[key].is<T>() instead")
bool containsKey(const TString& key) const { bool containsKey(const TString& key) const {
return detail::ObjectData::getMember(data_, detail::adaptString(key), return detail::VariantData::getMember(data_, detail::adaptString(key),
resources_) != 0; resources_) != 0;
} }
// DEPRECATED: use obj["key"].is<T>() instead // DEPRECATED: use obj["key"].is<T>() instead
@ -178,8 +180,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
int> = 0> int> = 0>
ARDUINOJSON_DEPRECATED("use obj[\"key\"].is<T>() instead") ARDUINOJSON_DEPRECATED("use obj[\"key\"].is<T>() instead")
bool containsKey(TChar* key) const { bool containsKey(TChar* key) const {
return detail::ObjectData::getMember(data_, detail::adaptString(key), return detail::VariantData::getMember(data_, detail::adaptString(key),
resources_) != 0; resources_) != 0;
} }
// DEPRECATED: use obj[key].is<T>() instead // DEPRECATED: use obj[key].is<T>() instead
@ -231,14 +233,14 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
} }
detail::VariantData* getData() const { detail::VariantData* getData() const {
return detail::collectionToVariant(data_); return data_;
} }
detail::VariantData* getOrCreateData() const { detail::VariantData* getOrCreateData() const {
return detail::collectionToVariant(data_); return data_;
} }
detail::ObjectData* data_; detail::VariantData* data_;
detail::ResourceManager* resources_; detail::ResourceManager* resources_;
}; };

View File

@ -22,7 +22,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
JsonObjectConst() : data_(0), resources_(0) {} JsonObjectConst() : data_(0), resources_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
JsonObjectConst(const detail::ObjectData* data, JsonObjectConst(const detail::VariantData* data,
const detail::ResourceManager* resources) const detail::ResourceManager* resources)
: data_(data), resources_(resources) {} : data_(data), resources_(resources) {}
@ -33,13 +33,13 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
// https://arduinojson.org/v7/api/jsonobjectconst/isnull/ // https://arduinojson.org/v7/api/jsonobjectconst/isnull/
bool isNull() const { bool isNull() const {
return data_ == 0; return !data_ || !data_->isObject();
} }
// Returns true if the reference is bound. // Returns true if the reference is bound.
// https://arduinojson.org/v7/api/jsonobjectconst/isnull/ // https://arduinojson.org/v7/api/jsonobjectconst/isnull/
operator bool() const { operator bool() const {
return data_ != 0; return !isNull();
} }
// Returns the depth (nesting level) of the object. // Returns the depth (nesting level) of the object.
@ -57,9 +57,10 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
// Returns an iterator to the first key-value pair of the object. // Returns an iterator to the first key-value pair of the object.
// https://arduinojson.org/v7/api/jsonobjectconst/begin/ // https://arduinojson.org/v7/api/jsonobjectconst/begin/
iterator begin() const { iterator begin() const {
if (!data_) auto obj = detail::VariantData::asObject(data_);
if (!obj)
return iterator(); return iterator();
return iterator(data_->createIterator(resources_), resources_); return iterator(obj->createIterator(resources_), resources_);
} }
// Returns an iterator following the last key-value pair of the object. // Returns an iterator following the last key-value pair of the object.
@ -74,8 +75,8 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
detail::enable_if_t<detail::IsString<TString>::value, int> = 0> detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
ARDUINOJSON_DEPRECATED("use obj[key].is<T>() instead") ARDUINOJSON_DEPRECATED("use obj[key].is<T>() instead")
bool containsKey(const TString& key) const { bool containsKey(const TString& key) const {
return detail::ObjectData::getMember(data_, detail::adaptString(key), return detail::VariantData::getMember(data_, detail::adaptString(key),
resources_) != 0; resources_) != 0;
} }
// DEPRECATED: use obj["key"].is<T>() instead // DEPRECATED: use obj["key"].is<T>() instead
@ -83,8 +84,8 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
template <typename TChar> template <typename TChar>
ARDUINOJSON_DEPRECATED("use obj[\"key\"].is<T>() instead") ARDUINOJSON_DEPRECATED("use obj[\"key\"].is<T>() instead")
bool containsKey(TChar* key) const { bool containsKey(TChar* key) const {
return detail::ObjectData::getMember(data_, detail::adaptString(key), return detail::VariantData::getMember(data_, detail::adaptString(key),
resources_) != 0; resources_) != 0;
} }
// DEPRECATED: use obj[key].is<T>() instead // DEPRECATED: use obj[key].is<T>() instead
@ -101,7 +102,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
template <typename TString, template <typename TString,
detail::enable_if_t<detail::IsString<TString>::value, int> = 0> detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
JsonVariantConst operator[](const TString& key) const { JsonVariantConst operator[](const TString& key) const {
return JsonVariantConst(detail::ObjectData::getMember( return JsonVariantConst(detail::VariantData::getMember(
data_, detail::adaptString(key), resources_), data_, detail::adaptString(key), resources_),
resources_); resources_);
} }
@ -113,7 +114,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
!detail::is_const<TChar>::value, !detail::is_const<TChar>::value,
int> = 0> int> = 0>
JsonVariantConst operator[](TChar* key) const { JsonVariantConst operator[](TChar* key) const {
return JsonVariantConst(detail::ObjectData::getMember( return JsonVariantConst(detail::VariantData::getMember(
data_, detail::adaptString(key), resources_), data_, detail::adaptString(key), resources_),
resources_); resources_);
} }
@ -137,10 +138,10 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
private: private:
const detail::VariantData* getData() const { const detail::VariantData* getData() const {
return collectionToVariant(data_); return data_;
} }
const detail::ObjectData* data_; const detail::VariantData* data_;
const detail::ResourceManager* resources_; const detail::ResourceManager* resources_;
}; };

View File

@ -329,9 +329,7 @@ struct Converter<JsonArrayConst> : private detail::VariantAttorney {
} }
static JsonArrayConst fromJson(JsonVariantConst src) { static JsonArrayConst fromJson(JsonVariantConst src) {
auto data = getData(src); return JsonArrayConst(getData(src), getResourceManager(src));
auto array = data ? data->asArray() : nullptr;
return JsonArrayConst(array, getResourceManager(src));
} }
static bool checkJson(JsonVariantConst src) { static bool checkJson(JsonVariantConst src) {
@ -350,9 +348,7 @@ struct Converter<JsonArray> : private detail::VariantAttorney {
} }
static JsonArray fromJson(JsonVariant src) { static JsonArray fromJson(JsonVariant src) {
auto data = getData(src); return JsonArray(getData(src), getResourceManager(src));
auto resources = getResourceManager(src);
return JsonArray(data != 0 ? data->asArray() : 0, resources);
} }
static bool checkJson(JsonVariant src) { static bool checkJson(JsonVariant src) {
@ -371,9 +367,7 @@ struct Converter<JsonObjectConst> : private detail::VariantAttorney {
} }
static JsonObjectConst fromJson(JsonVariantConst src) { static JsonObjectConst fromJson(JsonVariantConst src) {
auto data = getData(src); return JsonObjectConst(getData(src), getResourceManager(src));
auto object = data != 0 ? data->asObject() : nullptr;
return JsonObjectConst(object, getResourceManager(src));
} }
static bool checkJson(JsonVariantConst src) { static bool checkJson(JsonVariantConst src) {
@ -392,9 +386,7 @@ struct Converter<JsonObject> : private detail::VariantAttorney {
} }
static JsonObject fromJson(JsonVariant src) { static JsonObject fromJson(JsonVariant src) {
auto data = getData(src); return JsonObject(getData(src), getResourceManager(src));
auto resources = getResourceManager(src);
return JsonObject(data != 0 ? data->asObject() : 0, resources);
} }
static bool checkJson(JsonVariant src) { static bool checkJson(JsonVariant src) {

View File

@ -30,11 +30,13 @@ class VisitorAdapter {
: visitor_(&visitor), resources_(resources) {} : visitor_(&visitor), resources_(resources) {}
result_type visit(const ArrayData& value) { result_type visit(const ArrayData& value) {
return visitor_->visit(JsonArrayConst(&value, resources_)); return visitor_->visit(
JsonArrayConst(collectionToVariant(&value), resources_));
} }
result_type visit(const ObjectData& value) { result_type visit(const ObjectData& value) {
return visitor_->visit(JsonObjectConst(&value, resources_)); return visitor_->visit(
JsonObjectConst(collectionToVariant(&value), resources_));
} }
template <typename T> template <typename T>

View File

@ -16,7 +16,9 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
enum class VariantTypeBits : uint8_t { enum class VariantTypeBits : uint8_t {
OwnedStringBit = 0x01, // 0000 0001 OwnedStringBit = 0x01, // 0000 0001
NumberBit = 0x08, // 0000 1000 NumberBit = 0x08, // 0000 1000
EightByteBit = 0x10, // 0001 0000 #if ARDUINOJSON_USE_8_BYTE_POOL
EightByteBit = 0x10, // 0001 0000
#endif
CollectionMask = 0x60, CollectionMask = 0x60,
}; };

View File

@ -182,6 +182,14 @@ class VariantData {
return const_cast<VariantData*>(this)->asArray(); return const_cast<VariantData*>(this)->asArray();
} }
static ArrayData* asArray(VariantData* var) {
return var ? var->asArray() : 0;
}
static const ArrayData* asArray(const VariantData* var) {
return var ? var->asArray() : 0;
}
CollectionData* asCollection() { CollectionData* asCollection() {
return isCollection() ? &content_.asCollection : 0; return isCollection() ? &content_.asCollection : 0;
} }
@ -288,6 +296,14 @@ class VariantData {
return const_cast<VariantData*>(this)->asObject(); return const_cast<VariantData*>(this)->asObject();
} }
static ObjectData* asObject(VariantData* var) {
return var ? var->asObject() : 0;
}
static const ObjectData* asObject(const VariantData* var) {
return var ? var->asObject() : 0;
}
JsonString asRawString() const { JsonString asRawString() const {
switch (type_) { switch (type_) {
case VariantType::RawString: case VariantType::RawString:
@ -568,11 +584,12 @@ class VariantData {
return content_.asArray; return content_.asArray;
} }
static ArrayData* toArray(VariantData* var, ResourceManager* resources) { static VariantData* toArray(VariantData* var, ResourceManager* resources) {
if (!var) if (!var)
return 0; return 0;
var->clear(resources); var->clear(resources);
return &var->toArray(); var->toArray();
return var;
} }
ObjectData& toObject() { ObjectData& toObject() {
@ -582,11 +599,12 @@ class VariantData {
return content_.asObject; return content_.asObject;
} }
static ObjectData* toObject(VariantData* var, ResourceManager* resources) { static VariantData* toObject(VariantData* var, ResourceManager* resources) {
if (!var) if (!var)
return 0; return 0;
var->clear(resources); var->clear(resources);
return &var->toObject(); var->toObject();
return var;
} }
VariantType type() const { VariantType type() const {