瀏覽代碼

VariantImpl: change the visitor interface for arrays and objects

Benoit Blanchon 3 月之前
父節點
當前提交
3f62a2ca96

+ 10 - 4
src/ArduinoJson/Json/JsonSerializer.hpp

@@ -19,10 +19,13 @@ class JsonSerializer : public VariantDataVisitor<size_t> {
   JsonSerializer(TWriter writer, ResourceManager* resources)
       : formatter_(writer), resources_(resources) {}
 
-  size_t visit(const ArrayImpl& array) {
+  size_t visitArray(VariantData* array) {
+    ARDUINOJSON_ASSERT(array != nullptr);
+    ARDUINOJSON_ASSERT(array->isArray());
+
     write('[');
 
-    auto slotId = array.head();
+    auto slotId = array->content.asCollection.head;
 
     while (slotId != NULL_SLOT) {
       auto slot = resources_->getVariant(slotId);
@@ -39,10 +42,13 @@ class JsonSerializer : public VariantDataVisitor<size_t> {
     return bytesWritten();
   }
 
-  size_t visit(const ObjectImpl& object) {
+  size_t visitObject(VariantData* object) {
+    ARDUINOJSON_ASSERT(object != nullptr);
+    ARDUINOJSON_ASSERT(object->isObject());
+
     write('{');
 
-    auto slotId = object.head();
+    auto slotId = object->content.asCollection.head;
 
     bool isKey = true;
 

+ 22 - 14
src/ArduinoJson/Json/PrettyJsonSerializer.hpp

@@ -19,17 +19,21 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
   PrettyJsonSerializer(TWriter writer, ResourceManager* resources)
       : base(writer, resources), nesting_(0) {}
 
-  size_t visit(const ArrayImpl& array) {
-    auto it = array.createIterator();
-    if (!it.done()) {
+  size_t visitArray(VariantData* array) {
+    ARDUINOJSON_ASSERT(array != nullptr);
+    ARDUINOJSON_ASSERT(array->isArray());
+
+    auto slotId = array->content.asCollection.head;
+    if (slotId != NULL_SLOT) {
       base::write("[\r\n");
       nesting_++;
-      while (!it.done()) {
+      while (slotId != NULL_SLOT) {
         indent();
-        VariantImpl::accept(*this, it.data(), base::resources_);
+        auto slot = base::resources_->getVariant(slotId);
+        VariantImpl::accept(*this, slot, base::resources_);
 
-        it.next(base::resources_);
-        base::write(it.done() ? "\r\n" : ",\r\n");
+        slotId = slot->next;
+        base::write(slotId == NULL_SLOT ? "\r\n" : ",\r\n");
       }
       nesting_--;
       indent();
@@ -40,21 +44,25 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
     return this->bytesWritten();
   }
 
-  size_t visit(const ObjectImpl& object) {
-    auto it = object.createIterator();
-    if (!it.done()) {
+  size_t visitObject(VariantData* object) {
+    ARDUINOJSON_ASSERT(object != nullptr);
+    ARDUINOJSON_ASSERT(object->isObject());
+
+    auto slotId = object->content.asCollection.head;
+    if (slotId != NULL_SLOT) {
       base::write("{\r\n");
       nesting_++;
       bool isKey = true;
-      while (!it.done()) {
+      while (slotId != NULL_SLOT) {
         if (isKey)
           indent();
-        VariantImpl::accept(*this, it.data(), base::resources_);
-        it.next(base::resources_);
+        auto slot = base::resources_->getVariant(slotId);
+        VariantImpl::accept(*this, slot, base::resources_);
+        slotId = slot->next;
         if (isKey)
           base::write(": ");
         else
-          base::write(it.done() ? "\r\n" : ",\r\n");
+          base::write(slotId == NULL_SLOT ? "\r\n" : ",\r\n");
         isKey = !isKey;
       }
       nesting_--;

+ 12 - 6
src/ArduinoJson/MsgPack/MsgPackSerializer.hpp

@@ -47,8 +47,11 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
     return bytesWritten();
   }
 
-  size_t visit(const ArrayImpl& array) {
-    size_t n = array.size();
+  size_t visitArray(VariantData* array) {
+    ARDUINOJSON_ASSERT(array != nullptr);
+    ARDUINOJSON_ASSERT(array->isArray());
+
+    auto n = VariantImpl::size(array, resources_);
     if (n < 0x10) {
       writeByte(uint8_t(0x90 + n));
     } else if (n < 0x10000) {
@@ -59,7 +62,7 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
       writeInteger(uint32_t(n));
     }
 
-    auto slotId = array.head();
+    auto slotId = array->content.asCollection.head;
     while (slotId != NULL_SLOT) {
       auto slot = resources_->getVariant(slotId);
       VariantImpl::accept(*this, slot, resources_);
@@ -69,8 +72,11 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
     return bytesWritten();
   }
 
-  size_t visit(const ObjectImpl& object) {
-    size_t n = object.size();
+  size_t visitObject(VariantData* object) {
+    ARDUINOJSON_ASSERT(object != nullptr);
+    ARDUINOJSON_ASSERT(object->isObject());
+
+    auto n = VariantImpl::size(object, resources_);
     if (n < 0x10) {
       writeByte(uint8_t(0x80 + n));
     } else if (n < 0x10000) {
@@ -81,7 +87,7 @@ class MsgPackSerializer : public VariantDataVisitor<size_t> {
       writeInteger(uint32_t(n));
     }
 
-    auto slotId = object.head();
+    auto slotId = object->content.asCollection.head;
     while (slotId != NULL_SLOT) {
       auto slot = resources_->getVariant(slotId);
       VariantImpl::accept(*this, slot, resources_);

+ 9 - 6
src/ArduinoJson/Variant/JsonVariantVisitor.hpp

@@ -26,14 +26,15 @@ class VisitorAdapter {
  public:
   using result_type = typename TVisitor::result_type;
 
-  VisitorAdapter(TVisitor& visitor) : visitor_(&visitor) {}
+  VisitorAdapter(TVisitor& visitor, ResourceManager* resources)
+      : visitor_(&visitor), resources_(resources) {}
 
-  result_type visit(const ArrayImpl& array) {
-    return visitor_->visit(JsonArrayConst(array));
+  result_type visitArray(VariantData* data) {
+    return visitor_->visit(JsonArrayConst(data, resources_));
   }
 
-  result_type visit(const ObjectImpl& object) {
-    return visitor_->visit(JsonObjectConst(object));
+  result_type visitObject(VariantData* data) {
+    return visitor_->visit(JsonObjectConst(data, resources_));
   }
 
   template <typename T>
@@ -43,12 +44,14 @@ class VisitorAdapter {
 
  private:
   TVisitor* visitor_;
+  ResourceManager* resources_;
 };
 
 template <typename TVisitor>
 typename TVisitor::result_type accept(JsonVariantConst variant,
                                       TVisitor& visit) {
-  VisitorAdapter<TVisitor> adapter(visit);
+  VisitorAdapter<TVisitor> adapter(
+      visit, VariantAttorney::getResourceManager(variant));
   return VariantAttorney::getVariantImpl(variant).accept(adapter);
 }
 

+ 8 - 2
src/ArduinoJson/Variant/VariantDataVisitor.hpp

@@ -4,10 +4,8 @@
 
 #pragma once
 
-#include <ArduinoJson/Array/ArrayData.hpp>
 #include <ArduinoJson/Numbers/JsonFloat.hpp>
 #include <ArduinoJson/Numbers/JsonInteger.hpp>
-#include <ArduinoJson/Object/ObjectData.hpp>
 
 ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 
@@ -19,6 +17,14 @@ struct VariantDataVisitor {
   TResult visit(const T&) {
     return TResult();
   }
+
+  TResult visitArray(VariantData*) {
+    return TResult();
+  }
+
+  TResult visitObject(VariantData*) {
+    return TResult();
+  }
 };
 
 ARDUINOJSON_END_PRIVATE_NAMESPACE

+ 2 - 2
src/ArduinoJson/Variant/VariantImpl.hpp

@@ -57,10 +57,10 @@ class VariantImpl {
 #endif
 
       case VariantType::Array:
-        return visit.visit(ArrayImpl(data, resources));
+        return visit.visitArray(data);
 
       case VariantType::Object:
-        return visit.visit(ObjectImpl(data, resources));
+        return visit.visitObject(data);
 
       case VariantType::TinyString:
         return visit.visit(JsonString(data->content.asTinyString));