Эх сурвалжийг харах

VariantImpl: remove `addValue()`

This removes the two-way dependency between `JsonVariant` and `VariantImpl`
Benoit Blanchon 6 сар өмнө
parent
commit
f680598a2f

+ 14 - 18
src/ArduinoJson/Array/ArrayImpl.hpp

@@ -5,7 +5,6 @@
 #pragma once
 
 #include <ArduinoJson/Collection/CollectionIterator.hpp>
-#include <ArduinoJson/Variant/VariantCompare.hpp>
 #include <ArduinoJson/Variant/VariantImpl.hpp>
 
 ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
@@ -28,10 +27,23 @@ inline VariantData* VariantImpl::addElement() {
   auto slot = allocVariant();
   if (!slot)
     return nullptr;
-  VariantImpl::appendOne(slot);
+  addElement(slot);
   return slot.ptr();
 }
 
+inline void VariantImpl::addElement(Slot<VariantData> slot) {
+  auto coll = getCollectionData();
+
+  if (coll->tail != NULL_SLOT) {
+    auto tail = getVariant(coll->tail);
+    tail->next = slot.id();
+    coll->tail = slot.id();
+  } else {
+    coll->head = slot.id();
+    coll->tail = slot.id();
+  }
+}
+
 inline VariantData* VariantImpl::getOrAddElement(size_t index) {
   auto it = createIterator();
   while (!it.done() && index > 0) {
@@ -64,22 +76,6 @@ inline void VariantImpl::removeElement(size_t index) {
   removeElement(at(index));
 }
 
-template <typename T>
-inline bool VariantImpl::addValue(const T& value) {
-  if (!isArray())
-    return false;
-  auto slot = allocVariant();
-  if (!slot)
-    return false;
-  JsonVariant variant(slot.ptr(), resources_);
-  if (!variant.set(value)) {
-    freeVariant(slot);
-    return false;
-  }
-  appendOne(slot);
-  return true;
-}
-
 // Returns the size (in bytes) of an array with n elements.
 constexpr size_t sizeofArray(size_t n) {
   return n * sizeof(VariantData);

+ 27 - 2
src/ArduinoJson/Array/JsonArray.hpp

@@ -25,6 +25,10 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
   // INTERNAL USE ONLY
   JsonArray(detail::VariantImpl impl) : impl_(impl) {}
 
+  // INTERNAL USE ONLY
+  JsonArray(detail::VariantData* data, detail::ResourceManager* resources)
+      : impl_(data, resources) {}
+
   // Returns a JsonVariant pointing to the array.
   // https://arduinojson.org/v7/api/jsonvariant/
   operator JsonVariant() {
@@ -59,7 +63,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
   // https://arduinojson.org/v7/api/jsonarray/add/
   template <typename T>
   bool add(const T& value) const {
-    return impl_.addValue(value);
+    return doAdd(value);
   }
 
   // Appends a value to the array.
@@ -67,7 +71,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
   template <typename T,
             detail::enable_if_t<!detail::is_const<T>::value, int> = 0>
   bool add(T* value) const {
-    return impl_.addValue(value);
+    return doAdd(value);
   }
 
   // Returns an iterator to the first element of the array.
@@ -203,6 +207,27 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
     return impl_;
   }
 
+  template <typename T>
+  bool doAdd(const T& value) const {
+    if (!impl_.isArray())
+      return false;
+
+    auto resources = impl_.resources();
+    ARDUINOJSON_ASSERT(resources != nullptr);
+
+    auto slot = resources->allocVariant();
+    if (!slot)
+      return false;
+
+    if (!JsonVariant(slot.ptr(), resources).set(value)) {
+      detail::VariantImpl(slot.ptr(), resources).clear();
+      resources->freeVariant(slot);
+      return false;
+    }
+    impl_.addElement(slot);
+    return true;
+  }
+
   mutable detail::VariantImpl impl_;
 };
 

+ 0 - 13
src/ArduinoJson/Collection/CollectionImpl.hpp

@@ -18,19 +18,6 @@ inline VariantImpl::iterator VariantImpl::createIterator() const {
   return iterator(coll->head, resources_);
 }
 
-inline void VariantImpl::appendOne(Slot<VariantData> slot) {
-  auto coll = getCollectionData();
-
-  if (coll->tail != NULL_SLOT) {
-    auto tail = getVariant(coll->tail);
-    tail->next = slot.id();
-    coll->tail = slot.id();
-  } else {
-    coll->head = slot.id();
-    coll->tail = slot.id();
-  }
-}
-
 inline void VariantImpl::appendPair(Slot<VariantData> key,
                                     Slot<VariantData> value) {
   auto coll = getCollectionData();

+ 5 - 5
src/ArduinoJson/Document/JsonDocument.hpp

@@ -267,14 +267,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(getOrCreateArray().addElement(), &resources_);
+    return getOrCreateArray().add<T>();
   }
 
   // Appends a value to the root array.
   // https://arduinojson.org/v7/api/jsondocument/add/
   template <typename TValue>
   bool add(const TValue& value) {
-    return getOrCreateArray().addValue(value);
+    return getOrCreateArray().add(value);
   }
 
   // Appends a value to the root array.
@@ -282,7 +282,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 getOrCreateArray().addValue(value);
+    return getOrCreateArray().add(value);
   }
 
   // Removes an element of the root array.
@@ -396,8 +396,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
     return {&data_, &resources_};
   }
 
-  detail::VariantImpl getOrCreateArray() {
-    return detail::VariantImpl(data_.getOrCreateArray(), &resources_);
+  JsonArray getOrCreateArray() {
+    return JsonArray(data_.getOrCreateArray(), &resources_);
   }
 
   JsonVariant getVariant() {

+ 1 - 4
src/ArduinoJson/Variant/VariantImpl.hpp

@@ -97,9 +97,7 @@ class VariantImpl {
   }
 
   VariantData* addElement();
-
-  template <typename T>
-  bool addValue(const T& value);
+  void addElement(Slot<VariantData> slot);
 
   bool asBoolean() const {
     if (!data_)
@@ -550,7 +548,6 @@ class VariantImpl {
 
   iterator at(size_t index) const;
 
-  void appendOne(Slot<VariantData> slot);
   void appendPair(Slot<VariantData> key, Slot<VariantData> value);
 
   void removeOne(iterator it);

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

@@ -120,14 +120,14 @@ class VariantRefBase : public VariantTag {
   // https://arduinojson.org/v7/api/jsonvariant/add/
   template <typename T>
   bool add(const T& value) const {
-    return getOrCreateArray().addValue(value);
+    return getOrCreateArray().add(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 getOrCreateArray().addValue(value);
+    return getOrCreateArray().add(value);
   }
 
   // Removes an element of the array.
@@ -267,13 +267,7 @@ class VariantRefBase : public VariantTag {
     return VariantAttorney::getOrCreateImpl(derived());
   }
 
-  VariantImpl getOrCreateArray() const {
-    auto impl = getOrCreateImpl();
-    auto data = impl.data();
-    if (data)
-      data->getOrCreateArray();
-    return impl;
-  }
+  JsonArray getOrCreateArray() const;
 
   FORCE_INLINE ArduinoJson::JsonVariant getVariant() const;
 

+ 10 - 2
src/ArduinoJson/Variant/VariantRefBaseImpl.hpp

@@ -69,8 +69,7 @@ inline bool 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 {
-  auto impl = getOrCreateArray();
-  return JsonVariant(impl.addElement(), impl.resources());
+  return getOrCreateArray().template add<T>();
 }
 
 template <typename TDerived>
@@ -141,6 +140,15 @@ inline bool VariantRefBase<TDerived>::doSet(const T& value, true_type) const {
   return TConverter::toJson(value, JsonVariant(impl));
 }
 
+template <typename TDerived>
+inline JsonArray VariantRefBase<TDerived>::getOrCreateArray() const {
+  auto impl = getOrCreateImpl();
+  auto data = impl.data();
+  if (data)
+    data->getOrCreateArray();
+  return JsonArray(impl);
+}
+
 template <typename TDerived>
 template <typename T, enable_if_t<is_same<T, JsonArray>::value, int>>
 inline JsonArray VariantRefBase<TDerived>::to() const {