Bladeren bron

Merge `ArrayImpl` into `VariantImpl`

Benoit Blanchon 4 maanden geleden
bovenliggende
commit
76eec98efd

+ 0 - 54
src/ArduinoJson/Array/ArrayData.hpp

@@ -1,54 +0,0 @@
-// ArduinoJson - https://arduinojson.org
-// Copyright © 2014-2025, Benoit BLANCHON
-// MIT License
-
-#pragma once
-
-#include <ArduinoJson/Collection/CollectionData.hpp>
-
-ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
-
-class ArrayImpl : public CollectionImpl {
- public:
-  ArrayImpl() {}
-
-  ArrayImpl(VariantData* data, ResourceManager* resources)
-      : CollectionImpl(data, resources) {}
-
-  bool isNull() const {
-    return !data_ || data_->type != VariantType::Array;
-  }
-
-  VariantData* addElement() {
-    if (isNull())
-      return nullptr;
-    return addElement(data_, resources_);
-  }
-
-  static VariantData* addElement(VariantData*, ResourceManager*);
-
-  template <typename T>
-  bool addValue(const T& value) {
-    if (isNull())
-      return false;
-    return addValue(value, data_, resources_);
-  }
-
-  template <typename T>
-  static bool addValue(const T& value, VariantData*, ResourceManager*);
-
-  VariantData* getOrAddElement(size_t index);
-
-  VariantData* getElement(size_t index) const;
-
-  void removeElement(size_t index);
-
-  void remove(iterator it) {
-    CollectionImpl::removeOne(it);
-  }
-
- private:
-  iterator at(size_t index) const;
-};
-
-ARDUINOJSON_END_PRIVATE_NAMESPACE

+ 10 - 11
src/ArduinoJson/Array/ArrayImpl.hpp

@@ -4,14 +4,13 @@
 
 #pragma once
 
-#include <ArduinoJson/Array/ArrayData.hpp>
 #include <ArduinoJson/Variant/VariantCompare.hpp>
-#include <ArduinoJson/Variant/VariantData.hpp>
+#include <ArduinoJson/Variant/VariantImpl.hpp>
 
 ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 
-inline ArrayImpl::iterator ArrayImpl::at(size_t index) const {
-  if (isNull())
+inline VariantImpl::iterator VariantImpl::at(size_t index) const {
+  if (!isArray())
     return iterator();
 
   auto it = createIterator();
@@ -22,8 +21,8 @@ inline ArrayImpl::iterator ArrayImpl::at(size_t index) const {
   return it;
 }
 
-inline VariantData* ArrayImpl::addElement(VariantData* data,
-                                          ResourceManager* resources) {
+inline VariantData* VariantImpl::addElement(VariantData* data,
+                                            ResourceManager* resources) {
   ARDUINOJSON_ASSERT(data != nullptr);
   ARDUINOJSON_ASSERT(data->isArray());
   ARDUINOJSON_ASSERT(resources != nullptr);
@@ -35,7 +34,7 @@ inline VariantData* ArrayImpl::addElement(VariantData* data,
   return slot.ptr();
 }
 
-inline VariantData* ArrayImpl::getOrAddElement(size_t index) {
+inline VariantData* VariantImpl::getOrAddElement(size_t index) {
   auto it = createIterator();
   while (!it.done() && index > 0) {
     it.next(resources_);
@@ -53,17 +52,17 @@ inline VariantData* ArrayImpl::getOrAddElement(size_t index) {
   return element;
 }
 
-inline VariantData* ArrayImpl::getElement(size_t index) const {
+inline VariantData* VariantImpl::getElement(size_t index) const {
   return at(index).data();
 }
 
-inline void ArrayImpl::removeElement(size_t index) {
+inline void VariantImpl::removeElement(size_t index) {
   remove(at(index));
 }
 
 template <typename T>
-inline bool ArrayImpl::addValue(const T& value, VariantData* data,
-                                ResourceManager* resources) {
+inline bool VariantImpl::addValue(const T& value, VariantData* data,
+                                  ResourceManager* resources) {
   ARDUINOJSON_ASSERT(data != nullptr);
   ARDUINOJSON_ASSERT(resources != nullptr);
   auto slot = resources->allocVariant();

+ 5 - 2
src/ArduinoJson/Array/ElementProxy.hpp

@@ -59,8 +59,11 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
   }
 
   VariantData* getOrCreateData() const {
-    return VariantAttorney::getOrCreateVariantImpl(upstream_).getOrAddElement(
-        index_);
+    auto data = VariantAttorney::getOrCreateData(upstream_);
+    auto resources = VariantAttorney::getResourceManager(upstream_);
+    if (data && data->type == VariantType::Null)
+      data->toArray();
+    return VariantImpl(data, resources).getOrAddElement(index_);
   }
 
   TUpstream upstream_;

+ 3 - 6
src/ArduinoJson/Array/JsonArray.hpp

@@ -27,7 +27,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
       : impl_(data, resources) {}
 
   // INTERNAL USE ONLY
-  JsonArray(const detail::ArrayImpl& impl) : impl_(impl) {}
+  JsonArray(const detail::VariantImpl& impl) : impl_(impl) {}
 
   // Returns a JsonVariant pointing to the array.
   // https://arduinojson.org/v7/api/jsonvariant/
@@ -89,9 +89,6 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
   // Copies an array.
   // https://arduinojson.org/v7/api/jsonarray/set/
   bool set(JsonArrayConst src) const {
-    if (isNull())
-      return false;
-
     clear();
     for (auto element : src) {
       if (!add(element))
@@ -125,7 +122,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
   // Removes all the elements of the array.
   // https://arduinojson.org/v7/api/jsonarray/clear/
   void clear() const {
-    impl_.clear();
+    impl_.empty();
   }
 
   // Gets or sets the element at the specified index.
@@ -210,7 +207,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
     return impl_.getData();
   }
 
-  mutable detail::ArrayImpl impl_;
+  mutable detail::VariantImpl impl_;
 };
 
 ARDUINOJSON_END_PUBLIC_NAMESPACE

+ 2 - 2
src/ArduinoJson/Array/JsonArrayConst.hpp

@@ -41,7 +41,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
       : impl_(data, resources) {}
 
   // INTERNAL USE ONLY
-  JsonArrayConst(const detail::ArrayImpl& impl) : impl_(impl) {}
+  JsonArrayConst(const detail::VariantImpl& impl) : impl_(impl) {}
 
   // Returns the element at the specified index.
   // https://arduinojson.org/v7/api/jsonarrayconst/subscript/
@@ -102,7 +102,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
     return impl_.getData();
   }
 
-  detail::ArrayImpl impl_;
+  detail::VariantImpl impl_;
 };
 
 // Compares the content of two arrays.

+ 4 - 4
src/ArduinoJson/Array/JsonArrayIterator.hpp

@@ -30,7 +30,7 @@ class JsonArrayIterator {
 
  public:
   JsonArrayIterator() {}
-  explicit JsonArrayIterator(detail::ArrayImpl::iterator iterator,
+  explicit JsonArrayIterator(detail::CollectionIterator iterator,
                              detail::ResourceManager* resources)
       : iterator_(iterator), resources_(resources) {}
 
@@ -55,7 +55,7 @@ class JsonArrayIterator {
   }
 
  private:
-  detail::ArrayImpl::iterator iterator_;
+  detail::CollectionIterator iterator_;
   detail::ResourceManager* resources_;
 };
 
@@ -64,7 +64,7 @@ class JsonArrayConstIterator {
 
  public:
   JsonArrayConstIterator() {}
-  explicit JsonArrayConstIterator(detail::ArrayImpl::iterator iterator,
+  explicit JsonArrayConstIterator(detail::CollectionIterator iterator,
                                   detail::ResourceManager* resources)
       : iterator_(iterator), resources_(resources) {}
 
@@ -89,7 +89,7 @@ class JsonArrayConstIterator {
   }
 
  private:
-  mutable detail::ArrayImpl::iterator iterator_;
+  mutable detail::CollectionIterator iterator_;
   mutable detail::ResourceManager* resources_;
 };
 

+ 0 - 1
src/ArduinoJson/Collection/CollectionData.hpp

@@ -120,7 +120,6 @@ class CollectionImpl {
     return data_->content.asCollection.head;
   }
 
- protected:
   static void appendOne(Slot<VariantData> slot, VariantData*, ResourceManager*);
 
   static void appendPair(Slot<VariantData> key, Slot<VariantData> value,

+ 9 - 3
src/ArduinoJson/Document/JsonDocument.hpp

@@ -287,14 +287,14 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
   template <typename T, detail::enable_if_t<
                             detail::is_same<T, JsonVariant>::value, int> = 0>
   JsonVariant add() {
-    return JsonVariant(getVariantImpl().addElement(), &resources_);
+    return JsonVariant(getOrCreateArray().addElement(), &resources_);
   }
 
   // Appends a value to the root array.
   // https://arduinojson.org/v7/api/jsondocument/add/
   template <typename TValue>
   bool add(const TValue& value) {
-    return getVariantImpl().addValue(value);
+    return getOrCreateArray().addValue(value);
   }
 
   // Appends a value to the root array.
@@ -302,7 +302,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
   template <typename TChar,
             detail::enable_if_t<!detail::is_const<TChar>::value, int> = 0>
   bool add(TChar* value) {
-    return getVariantImpl().addValue(value);
+    return getOrCreateArray().addValue(value);
   }
 
   // Removes an element of the root array.
@@ -412,6 +412,12 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
     return detail::VariantImpl(&data_, &resources_);
   }
 
+  detail::VariantImpl getOrCreateArray() const {
+    if (data_.type == detail::VariantType::Null)
+      data_.toArray();
+    return detail::VariantImpl(&data_, &resources_);
+  }
+
   JsonVariant getVariant() {
     return JsonVariant(&data_, &resources_);
   }

+ 1 - 1
src/ArduinoJson/Json/JsonDeserializer.hpp

@@ -174,7 +174,7 @@ class JsonDeserializer {
     for (;;) {
       if (elementFilter.allow()) {
         // Allocate slot in array
-        VariantData* value = ArrayImpl::addElement(array, resources_);
+        VariantData* value = VariantImpl::addElement(array, resources_);
         if (!value)
           return DeserializationError::NoMemory;
 

+ 1 - 1
src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp

@@ -360,7 +360,7 @@ class MsgPackDeserializer {
       VariantData* value;
 
       if (elementFilter.allow()) {
-        value = ArrayImpl::addElement(variant, resources_);
+        value = VariantImpl::addElement(variant, resources_);
         if (!value)
           return DeserializationError::NoMemory;
       } else {

+ 34 - 48
src/ArduinoJson/Variant/VariantImpl.hpp

@@ -4,7 +4,6 @@
 
 #pragma once
 
-#include <ArduinoJson/Array/ArrayData.hpp>
 #include <ArduinoJson/Memory/ResourceManager.hpp>
 #include <ArduinoJson/Misc/SerializedValue.hpp>
 #include <ArduinoJson/Numbers/convertNumber.hpp>
@@ -19,6 +18,8 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 // to the compiler to optimize the `this` pointer away.
 class VariantImpl {
  public:
+  using iterator = CollectionIterator;
+
   VariantImpl() : data_(nullptr), resources_(nullptr) {}
 
   VariantImpl(VariantData* data, ResourceManager* resources)
@@ -96,32 +97,22 @@ class VariantImpl {
   }
 
   VariantData* addElement() {
+    if (!isArray())
+      return nullptr;
     return addElement(data_, resources_);
   }
 
-  static VariantData* addElement(VariantData* data,
-                                 ResourceManager* resources) {
-    if (!data)
-      return nullptr;
-    auto array = data->type == VariantType::Null ? toArray(data, resources)
-                                                 : asArray(data, resources);
-    return array.addElement();
-  }
+  static VariantData* addElement(VariantData*, ResourceManager*);
 
   template <typename T>
   bool addValue(const T& value) {
+    if (!isArray())
+      return false;
     return addValue(value, data_, resources_);
   }
 
   template <typename T>
-  static bool addValue(const T& value, VariantData* data,
-                       ResourceManager* resources) {
-    if (!data)
-      return false;
-    auto array = data->type == VariantType::Null ? toArray(data, resources)
-                                                 : asArray(data, resources);
-    return array.addValue(value);
-  }
+  static bool addValue(const T& value, VariantData*, ResourceManager*);
 
   bool asBoolean() const {
     return asBoolean(data_, resources_);
@@ -158,15 +149,7 @@ class VariantImpl {
     }
   }
 
-  ArrayImpl asArray() {
-    return asArray(data_, resources_);
-  }
-
-  static ArrayImpl asArray(VariantData* data, ResourceManager* resources) {
-    return ArrayImpl(data, resources);
-  }
-
-  CollectionImpl asCollection() {
+  CollectionImpl asCollection() const {
     return CollectionImpl(data_, resources_);
   }
 
@@ -274,6 +257,12 @@ class VariantImpl {
     return ObjectImpl(data, resources);
   }
 
+  iterator at(size_t index) const;
+
+  iterator createIterator() const {
+    return asCollection().createIterator();
+  }
+
 #if ARDUINOJSON_USE_8_BYTE_POOL
   static const EightByteValue* getEightByte(VariantData* data,
                                             ResourceManager* resources) {
@@ -285,20 +274,15 @@ class VariantImpl {
   }
 #endif
 
-  VariantData* getElement(size_t index) {
-    return asArray().getElement(index);
-  }
+  VariantData* getOrAddElement(size_t index);
+
+  VariantData* getElement(size_t index) const;
 
   template <typename TAdaptedString>
   VariantData* getMember(TAdaptedString key) {
     return asObject().getMember(key);
   }
 
-  VariantData* getOrAddElement(size_t index) {
-    auto array = isNull() ? toArray() : asArray();
-    return array.getOrAddElement(index);
-  }
-
   template <typename TAdaptedString>
   VariantData* getOrAddMember(TAdaptedString key) {
     return getOrAddMember(key, data_, resources_);
@@ -367,12 +351,14 @@ class VariantImpl {
     return type() == VariantType::Object;
   }
 
-  size_t nesting() {
+  size_t nesting() const {
     return asCollection().nesting();
   }
 
-  void removeElement(size_t index) {
-    asArray().removeElement(index);
+  void removeElement(size_t index);
+
+  void remove(CollectionIterator it) {
+    asCollection().removeOne(it);
   }
 
   template <typename TAdaptedString>
@@ -536,7 +522,7 @@ class VariantImpl {
     return false;
   }
 
-  size_t size() {
+  size_t size() const {
     if (!data_)
       return 0;
 
@@ -557,18 +543,12 @@ class VariantImpl {
     return n;
   }
 
-  ArrayImpl toArray() {
+  bool toArray() {
     if (!data_)
-      return ArrayImpl();
+      return false;
     clear(data_, resources_);
-    return toArray(data_, resources_);
-  }
-
-  static ArrayImpl toArray(VariantData* data, ResourceManager* resources) {
-    ARDUINOJSON_ASSERT(data != nullptr);
-    ARDUINOJSON_ASSERT(resources != nullptr);
-    data->toArray();
-    return ArrayImpl(data, resources);
+    data_->toArray();
+    return true;
   }
 
   ObjectImpl toObject() {
@@ -613,8 +593,14 @@ class VariantImpl {
     data->type = VariantType::Null;
   }
 
+  void empty() {
+    if (isCollection())
+      CollectionImpl::clear(data_, resources_);
+  }
+
  private:
   VariantData* data_;
   ResourceManager* resources_;
 };
+
 ARDUINOJSON_END_PRIVATE_NAMESPACE

+ 11 - 3
src/ArduinoJson/Variant/VariantRefBase.hpp

@@ -119,20 +119,20 @@ class VariantRefBase : public VariantTag {
   // https://arduinojson.org/v7/api/jsonvariant/add/
   template <typename T>
   bool add(const T& value) const {
-    return getOrCreateVariantImpl().addValue(value);
+    return getOrCreateArray().addValue(value);
   }
 
   // Appends a value to the array.
   // https://arduinojson.org/v7/api/jsonvariant/add/
   template <typename T, enable_if_t<!is_const<T>::value, int> = 0>
   bool add(T* value) const {
-    return getOrCreateVariantImpl().addValue(value);
+    return getOrCreateArray().addValue(value);
   }
 
   // Removes an element of the array.
   // https://arduinojson.org/v7/api/jsonvariant/remove/
   void remove(size_t index) const {
-    getVariantImpl().removeElement(index);
+    getOrCreateArray().removeElement(index);
   }
 
   // Removes a member of the object.
@@ -278,6 +278,14 @@ class VariantRefBase : public VariantTag {
     return VariantImpl(getOrCreateData(), getResourceManager());
   }
 
+  VariantImpl getOrCreateArray() const {
+    auto data = getOrCreateData();
+    auto resources = getResourceManager();
+    if (data && data->type == VariantType::Null)
+      data->toArray();
+    return VariantImpl(data, resources);
+  }
+
   FORCE_INLINE ArduinoJson::JsonVariant getVariant() const;
 
   FORCE_INLINE ArduinoJson::JsonVariantConst getVariantConst() const {

+ 4 - 3
src/ArduinoJson/Variant/VariantRefBaseImpl.hpp

@@ -69,8 +69,7 @@ inline void convertToJson(const VariantRefBase<TDerived>& src,
 template <typename TDerived>
 template <typename T, enable_if_t<is_same<T, JsonVariant>::value, int>>
 inline T VariantRefBase<TDerived>::add() const {
-  return JsonVariant(getOrCreateVariantImpl().addElement(),
-                     getResourceManager());
+  return JsonVariant(getOrCreateArray().addElement(), getResourceManager());
 }
 
 template <typename TDerived>
@@ -147,7 +146,9 @@ inline bool VariantRefBase<TDerived>::doSet(const T& value, true_type) const {
 template <typename TDerived>
 template <typename T, enable_if_t<is_same<T, JsonArray>::value, int>>
 inline JsonArray VariantRefBase<TDerived>::to() const {
-  return JsonArray(getOrCreateVariantImpl().toArray());
+  auto impl = getOrCreateVariantImpl();
+  impl.toArray();
+  return JsonArray(impl);
 }
 
 template <typename TDerived>