Skip to content

Commit

Permalink
Implement JsonArray from JsonVariant
Browse files Browse the repository at this point in the history
  • Loading branch information
bblanchon committed May 26, 2023
1 parent 24bc28c commit b36eb28
Showing 1 changed file with 40 additions and 37 deletions.
77 changes: 40 additions & 37 deletions src/ArduinoJson/Array/JsonArray.hpp
Expand Up @@ -21,52 +21,51 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
typedef JsonArrayIterator iterator;

// Constructs an unbound reference.
FORCE_INLINE JsonArray() : data_(0), pool_(0) {}
FORCE_INLINE JsonArray() {}

// INTERNAL USE ONLY
FORCE_INLINE JsonArray(detail::MemoryPool* pool, detail::CollectionData* data)
: data_(data), pool_(pool) {}
// Constructs a JsonArray from a JsonVariant
FORCE_INLINE JsonArray(JsonVariant variant) : variant_(variant) {}

// Returns a JsonVariant pointing to the array.
// https://arduinojson.org/v6/api/jsonvariant/
operator JsonVariant() {
void* data = data_; // prevent warning cast-align
return JsonVariant(pool_, reinterpret_cast<detail::VariantData*>(data));
return variant_;
}

// Returns a read-only reference to the array.
// https://arduinojson.org/v6/api/jsonarrayconst/
operator JsonArrayConst() const {
return JsonArrayConst(data_);
return JsonArrayConst(getArrayData());
}

// Appends a new (null) element to the array.
// Returns a reference to the new element.
// https://arduinojson.org/v6/api/jsonarray/add/
JsonVariant add() const {
return JsonVariant(pool_, collectionAddElement(data_, pool_));
return variant_.add();
}

// Appends a value to the array.
// https://arduinojson.org/v6/api/jsonarray/add/
template <typename T>
FORCE_INLINE bool add(const T& value) const {
return add().set(value);
return variant_.add(value);
}

// Appends a value to the array.
// https://arduinojson.org/v6/api/jsonarray/add/
template <typename T>
FORCE_INLINE bool add(T* value) const {
return add().set(value);
return variant_.add(value);
}

// Returns an iterator to the first element of the array.
// https://arduinojson.org/v6/api/jsonarray/begin/
FORCE_INLINE iterator begin() const {
if (!data_)
auto data = getArrayData();
if (!data)
return iterator();
return iterator(pool_, data_->head());
return iterator(getPool(), data->head());
}

// Returns an iterator following the last element of the array.
Expand All @@ -78,39 +77,40 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Copies an array.
// https://arduinojson.org/v6/api/jsonarray/set/
FORCE_INLINE bool set(JsonArrayConst src) const {
return collectionCopy(data_, src.data_, pool_);
return variant_.set(src);
}

// Compares the content of two arrays.
FORCE_INLINE bool operator==(JsonArray rhs) const {
return JsonArrayConst(data_) == JsonArrayConst(rhs.data_);
return JsonArrayConst(getArrayData()) == JsonArrayConst(rhs.getArrayData());
}

// Removes the element at the specified iterator.
// 鈿狅笍 Doesn't release the memory associated with the removed element.
// https://arduinojson.org/v6/api/jsonarray/remove/
FORCE_INLINE void remove(iterator it) const {
collectionRemove(data_, it.slot_, pool_);
collectionRemove(getArrayData(), it.slot_, getPool());
}

// Removes the element at the specified index.
// 鈿狅笍 Doesn't release the memory associated with the removed element.
// https://arduinojson.org/v6/api/jsonarray/remove/
FORCE_INLINE void remove(size_t index) const {
collectionRemoveElement(data_, index, pool_);
variant_.remove(index);
}

// Removes all the elements of the array.
// 鈿狅笍 Doesn't release the memory associated with the removed elements.
// https://arduinojson.org/v6/api/jsonarray/clear/
void clear() const {
collectionClear(data_, pool_);
variant_.to<JsonArray>();
}

// Gets or sets the element at the specified index.
// https://arduinojson.org/v6/api/jsonarray/subscript/
FORCE_INLINE detail::ElementProxy<JsonArray> operator[](size_t index) const {
return {*this, index};
FORCE_INLINE detail::ElementProxy<JsonVariant> operator[](
size_t index) const {
return variant_[index];
}

// Creates an object and appends it to the array.
Expand All @@ -120,58 +120,62 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Creates an array and appends it to the array.
// https://arduinojson.org/v6/api/jsonarray/createnestedarray/
FORCE_INLINE JsonArray createNestedArray() const {
return add().to<JsonArray>();
return variant_.createNestedArray();
}

operator JsonVariantConst() const {
return JsonVariantConst(collectionToVariant(data_));
return variant_;
}

// Returns true if the reference is unbound.
// Returns true if the reference is null or unbound.
// https://arduinojson.org/v6/api/jsonarray/isnull/
FORCE_INLINE bool isNull() const {
return data_ == 0;
return !getArrayData();
}

// Returns true if the reference is bound.
// Returns true if the reference points to an Array.
// https://arduinojson.org/v6/api/jsonarray/isnull/
FORCE_INLINE operator bool() const {
return data_ != 0;
return !isNull();
}

// Returns the number of bytes occupied by the array.
// https://arduinojson.org/v6/api/jsonarray/memoryusage/
FORCE_INLINE size_t memoryUsage() const {
return data_ ? data_->memoryUsage() : 0;
return variant_.memoryUsage();
}

// Returns the depth (nesting level) of the array.
// https://arduinojson.org/v6/api/jsonarray/nesting/
FORCE_INLINE size_t nesting() const {
return variantNesting(collectionToVariant(data_));
return variant_.nesting();
}

// Returns the number of elements in the array.
// https://arduinojson.org/v6/api/jsonarray/size/
FORCE_INLINE size_t size() const {
return data_ ? data_->size() : 0;
return variant_.size();
}

private:
detail::MemoryPool* getPool() const {
return pool_;
return detail::VariantAttorney::getPool(variant_);
}

detail::VariantData* getData() const {
return collectionToVariant(data_);
return detail::VariantAttorney::getData(variant_);
}

detail::VariantData* getOrCreateData() const {
return collectionToVariant(data_);
return detail::VariantAttorney::getOrCreateData(variant_);
}

detail::CollectionData* data_;
detail::MemoryPool* pool_;
detail::CollectionData* getArrayData() const {
auto data = getData();
return data ? data->asArray() : nullptr;
}

JsonVariant variant_;
};

template <>
Expand All @@ -181,9 +185,7 @@ struct Converter<JsonArray> : private detail::VariantAttorney {
}

static JsonArray fromJson(JsonVariant src) {
auto data = getData(src);
auto pool = getPool(src);
return JsonArray(pool, data != 0 ? data->asArray() : 0);
return JsonArray(src);
}

static detail::InvalidConversion<JsonVariantConst, JsonArray> fromJson(
Expand All @@ -207,7 +209,8 @@ template <typename TDerived>
template <typename T>
inline typename enable_if<is_same<T, JsonArray>::value, JsonArray>::type
VariantRefBase<TDerived>::to() const {
return JsonArray(getPool(), variantToArray(getOrCreateData(), getPool()));
variantToArray(getOrCreateData(), getPool());
return JsonArray(getVariant());
}

ARDUINOJSON_END_PRIVATE_NAMESPACE

0 comments on commit b36eb28

Please sign in to comment.