Bladeren bron

Removed friend relationship between JsonVariant and JsonSerializer

Benoit Blanchon 8 jaren geleden
bovenliggende
commit
923d3e8a84

+ 33 - 7
src/ArduinoJson/JsonVariant.hpp

@@ -27,10 +27,6 @@ namespace ArduinoJson {
 // Forward declarations.
 class JsonArray;
 class JsonObject;
-namespace Internals {
-template <typename Print>
-class JsonSerializer;
-}
 
 // A variant that can be a any value serializable to a JSON value.
 //
@@ -40,9 +36,6 @@ class JsonSerializer;
 // - a string (const char*)
 // - a reference to a JsonArray or JsonObject
 class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
-  template <typename Print>
-  friend class Internals::JsonSerializer;
-
  public:
   // Creates an uninitialized JsonVariant
   JsonVariant() : _type(Internals::JSON_UNDEFINED) {}
@@ -317,6 +310,39 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
     return _type != Internals::JSON_UNDEFINED;
   }
 
+  template <typename Visitor>
+  void visit(Visitor visitor) const {
+    using namespace Internals;
+    switch (_type) {
+      case JSON_FLOAT:
+        return visitor.acceptFloat(_content.asFloat);
+
+      case JSON_ARRAY:
+        return visitor.acceptArray(*_content.asArray);
+
+      case JSON_OBJECT:
+        return visitor.acceptObject(*_content.asObject);
+
+      case JSON_STRING:
+        return visitor.acceptString(_content.asString);
+
+      case JSON_UNPARSED:
+        return visitor.acceptRawJson(_content.asString);
+
+      case JSON_NEGATIVE_INTEGER:
+        return visitor.acceptNegativeInteger(_content.asInteger);
+
+      case JSON_POSITIVE_INTEGER:
+        return visitor.acceptPositiveInteger(_content.asInteger);
+
+      case JSON_BOOLEAN:
+        return visitor.acceptBoolean(_content.asInteger != 0);
+
+      default:  // JSON_UNDEFINED
+        return visitor.acceptUndefined();
+    }
+  }
+
  private:
   JsonArray &variantAsArray() const;
   JsonObject &variantAsObject() const;

+ 41 - 0
src/ArduinoJson/Serialization/JsonSerializer.hpp

@@ -36,6 +36,47 @@ class JsonSerializer {
   template <typename TKey>
   static void serialize(const JsonObjectSubscript<TKey> &, Writer &);
   static void serialize(const JsonVariant &, Writer &);
+
+  struct Visitor {
+    Visitor(Writer *writer) : _writer(writer) {}
+
+    void acceptFloat(JsonFloat value) {
+      _writer->writeFloat(value);
+    }
+
+    void acceptArray(const JsonArray &value) {
+      serialize(value, *_writer);
+    }
+
+    void acceptObject(const JsonObject &value) {
+      serialize(value, *_writer);
+    }
+
+    void acceptString(const char *value) {
+      _writer->writeString(value);
+    }
+
+    void acceptRawJson(const char *value) {
+      _writer->writeRaw(value);
+    }
+
+    void acceptNegativeInteger(JsonUInt value) {
+      _writer->writeRaw('-');
+      _writer->writeInteger(value);
+    }
+
+    void acceptPositiveInteger(JsonUInt value) {
+      _writer->writeInteger(value);
+    }
+
+    void acceptBoolean(bool value) {
+      _writer->writeBoolean(value);
+    }
+
+    void acceptUndefined() {}
+
+    Writer *_writer;
+  };
 };
 }  // namespace Internals
 

+ 1 - 35
src/ArduinoJson/Serialization/JsonSerializerImpl.hpp

@@ -65,39 +65,5 @@ inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
 template <typename Writer>
 inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
     const JsonVariant& variant, Writer& writer) {
-  switch (variant._type) {
-    case JSON_FLOAT:
-      writer.writeFloat(variant._content.asFloat);
-      return;
-
-    case JSON_ARRAY:
-      serialize(*variant._content.asArray, writer);
-      return;
-
-    case JSON_OBJECT:
-      serialize(*variant._content.asObject, writer);
-      return;
-
-    case JSON_STRING:
-      writer.writeString(variant._content.asString);
-      return;
-
-    case JSON_UNPARSED:
-      writer.writeRaw(variant._content.asString);
-      return;
-
-    case JSON_NEGATIVE_INTEGER:
-      writer.writeRaw('-');  // Falls through.
-
-    case JSON_POSITIVE_INTEGER:
-      writer.writeInteger(variant._content.asInteger);
-      return;
-
-    case JSON_BOOLEAN:
-      writer.writeBoolean(variant._content.asInteger != 0);
-      return;
-
-    default:  // JSON_UNDEFINED
-      return;
-  }
+  variant.visit(Visitor(&writer));
 }