Ver código fonte

Extracted class JsonSerializer

Benoit Blanchon 9 anos atrás
pai
commit
a60b35f41c

+ 5 - 0
CHANGELOG.md

@@ -1,6 +1,11 @@
 ArduinoJson: change log
 =======================
 
+HEAD
+----
+
+* Fixed `array[idx].as<JsonVariant>()` and `object[key].as<JsonVariant>()`
+
 v5.6.6
 ------
 

+ 1 - 0
include/ArduinoJson.hpp

@@ -13,6 +13,7 @@
 #include "ArduinoJson/StaticJsonBuffer.hpp"
 
 #include "ArduinoJson/Internals/JsonParser.ipp"
+#include "ArduinoJson/Internals/JsonSerializer.ipp"
 #include "ArduinoJson/JsonArray.ipp"
 #include "ArduinoJson/JsonBuffer.ipp"
 #include "ArduinoJson/JsonObject.ipp"

+ 6 - 3
include/ArduinoJson/Internals/JsonPrintable.hpp

@@ -9,11 +9,12 @@
 
 #include "../Configuration.hpp"
 #include "DummyPrint.hpp"
+#include "DynamicStringBuilder.hpp"
 #include "IndentedPrint.hpp"
+#include "JsonSerializer.hpp"
 #include "JsonWriter.hpp"
 #include "Prettyfier.hpp"
 #include "StaticStringBuilder.hpp"
-#include "DynamicStringBuilder.hpp"
 
 #if ARDUINOJSON_ENABLE_STD_STREAM
 #include "StreamPrintAdapter.hpp"
@@ -31,7 +32,7 @@ class JsonPrintable {
  public:
   size_t printTo(Print &print) const {
     JsonWriter writer(print);
-    downcast().writeTo(writer);
+    JsonSerializer::serialize(downcast(), writer);
     return writer.bytesWritten();
   }
 
@@ -84,7 +85,9 @@ class JsonPrintable {
   }
 
  private:
-  const T &downcast() const { return *static_cast<const T *>(this); }
+  const T &downcast() const {
+    return *static_cast<const T *>(this);
+  }
 };
 
 #if ARDUINOJSON_ENABLE_STD_STREAM

+ 33 - 0
include/ArduinoJson/Internals/JsonSerializer.hpp

@@ -0,0 +1,33 @@
+// Copyright Benoit Blanchon 2014-2016
+// MIT License
+//
+// Arduino JSON library
+// https://github.com/bblanchon/ArduinoJson
+// If you like this project, please add a star!
+
+#pragma once
+
+#include "JsonWriter.hpp"
+
+namespace ArduinoJson {
+
+class JsonArray;
+class JsonArraySubscript;
+class JsonObject;
+template <typename TKey>
+class JsonObjectSubscript;
+class JsonVariant;
+
+namespace Internals {
+
+class JsonSerializer {
+ public:
+  static void serialize(const JsonArray &, JsonWriter &);
+  static void serialize(const JsonArraySubscript &, JsonWriter &);
+  static void serialize(const JsonObject &, JsonWriter &);
+  template <typename TKey>
+  static void serialize(const JsonObjectSubscript<TKey> &, JsonWriter &);
+  static void serialize(const JsonVariant &, JsonWriter &);
+};
+}
+}

+ 101 - 0
include/ArduinoJson/Internals/JsonSerializer.ipp

@@ -0,0 +1,101 @@
+// Copyright Benoit Blanchon 2014-2016
+// MIT License
+//
+// Arduino JSON library
+// https://github.com/bblanchon/ArduinoJson
+// If you like this project, please add a star!
+
+#pragma once
+
+#include "../JsonArray.hpp"
+#include "../JsonArraySubscript.hpp"
+#include "../JsonObject.hpp"
+#include "../JsonObjectSubscript.hpp"
+#include "../JsonVariant.hpp"
+#include "JsonSerializer.hpp"
+
+inline void ArduinoJson::Internals::JsonSerializer::serialize(
+    const JsonArray& array, JsonWriter& writer) {
+  writer.beginArray();
+
+  JsonArray::const_iterator it = array.begin();
+  while (it != array.end()) {
+    serialize(*it, writer);
+
+    ++it;
+    if (it == array.end()) break;
+
+    writer.writeComma();
+  }
+
+  writer.endArray();
+}
+
+inline void ArduinoJson::Internals::JsonSerializer::serialize(
+    const JsonArraySubscript& arraySubscript, JsonWriter& writer) {
+  serialize(arraySubscript.as<JsonVariant>(), writer);
+}
+
+inline void ArduinoJson::Internals::JsonSerializer::serialize(
+    const JsonObject& object, JsonWriter& writer) {
+  writer.beginObject();
+
+  JsonObject::const_iterator it = object.begin();
+  while (it != object.end()) {
+    writer.writeString(it->key);
+    writer.writeColon();
+    serialize(it->value, writer);
+
+    ++it;
+    if (it == object.end()) break;
+
+    writer.writeComma();
+  }
+
+  writer.endObject();
+}
+
+template <typename TKey>
+inline void ArduinoJson::Internals::JsonSerializer::serialize(
+    const JsonObjectSubscript<TKey>& objectSubscript, JsonWriter& writer) {
+  serialize(objectSubscript.template as<JsonVariant>(), writer);
+}
+
+inline void ArduinoJson::Internals::JsonSerializer::serialize(
+    const JsonVariant& variant, JsonWriter& writer) {
+  switch (variant._type) {
+    case JSON_UNDEFINED:
+      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('-');
+    case JSON_POSITIVE_INTEGER:
+      writer.writeInteger(variant._content.asInteger);
+      return;
+
+    case JSON_BOOLEAN:
+      writer.writeBoolean(variant._content.asInteger != 0);
+      return;
+
+    default:
+      uint8_t decimals =
+          static_cast<uint8_t>(variant._type - JSON_FLOAT_0_DECIMALS);
+      writer.writeFloat(variant._content.asFloat, decimals);
+  }
+}

+ 0 - 17
include/ArduinoJson/JsonArray.hpp

@@ -170,23 +170,6 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
     return instance;
   }
 
-  // Serialize the array to the specified JsonWriter.
-  void writeTo(Internals::JsonWriter &writer) const {
-    writer.beginArray();
-
-    const node_type *child = _firstNode;
-    while (child) {
-      child->content.writeTo(writer);
-
-      child = child->next;
-      if (!child) break;
-
-      writer.writeComma();
-    }
-
-    writer.endArray();
-  }
-
   // Imports a 1D array
   template <typename T, size_t N>
   bool copyFrom(T(&array)[N]) {

+ 0 - 4
include/ArduinoJson/JsonArraySubscript.hpp

@@ -60,10 +60,6 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
     return _array.is<T>(_index);
   }
 
-  void writeTo(Internals::JsonWriter& writer) const {
-    _array.get(_index).writeTo(writer);
-  }
-
   template <typename TValue>
   void set(TValue value) {
     _array.set(_index, value);

+ 0 - 19
include/ArduinoJson/JsonObject.hpp

@@ -144,25 +144,6 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
     return instance;
   }
 
-  // Serialize the object to the specified JsonWriter
-  void writeTo(Internals::JsonWriter& writer) const {
-    writer.beginObject();
-
-    const node_type* node = _firstNode;
-    while (node) {
-      writer.writeString(node->content.key);
-      writer.writeColon();
-      node->content.value.writeTo(writer);
-
-      node = node->next;
-      if (!node) break;
-
-      writer.writeComma();
-    }
-
-    writer.endObject();
-  }
-
  private:
   // Returns the list node that matches the specified key.
   node_type* getNodeAt(const char* key) const {

+ 0 - 4
include/ArduinoJson/JsonObjectSubscript.hpp

@@ -77,10 +77,6 @@ class JsonObjectSubscript : public JsonVariantBase<JsonObjectSubscript<TKey> > {
     return _object.get(_key);
   }
 
-  void writeTo(Internals::JsonWriter& writer) const {
-    _object.get(_key).writeTo(writer);
-  }
-
  private:
   JsonObject& _object;
   TKey _key;

+ 14 - 6
include/ArduinoJson/JsonVariant.hpp

@@ -36,6 +36,9 @@ class JsonObject;
 // - a string (const char*)
 // - a reference to a JsonArray or JsonObject
 class JsonVariant : public JsonVariantBase<JsonVariant> {
+  friend void Internals::JsonSerializer::serialize(const JsonVariant &,
+                                                   JsonWriter &);
+
  public:
   template <typename T>
   struct IsConstructibleFrom;
@@ -211,6 +214,14 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
   as() const {
     return asObject();
   }
+  //
+  // JsonVariant as<JsonVariant> const;
+  template <typename T>
+  typename TypeTraits::EnableIf<TypeTraits::IsSame<T, JsonVariant>::value,
+                                T>::type
+  as() const {
+    return *this;
+  }
 
   // Tells weither the variant has the specified type.
   // Returns true if the variant has type type T, false otherwise.
@@ -266,9 +277,9 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
     return isArray();
   }
   //
-  // JsonObject& as<JsonObject> const;
-  // JsonObject& as<JsonObject&> const;
-  // JsonObject& as<const JsonObject&> const;
+  // bool is<JsonObject> const;
+  // bool is<JsonObject&> const;
+  // bool is<const JsonObject&> const;
   template <typename T>
   typename TypeTraits::EnableIf<
       TypeTraits::IsSame<
@@ -285,9 +296,6 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
     return _type != Internals::JSON_UNDEFINED;
   }
 
-  // Serialize the variant to a JsonWriter
-  void writeTo(Internals::JsonWriter &writer) const;
-
   // Value returned if the variant has an incompatible type
   template <typename T>
   static typename Internals::JsonVariantAs<T>::type defaultValue() {

+ 0 - 38
include/ArduinoJson/JsonVariant.ipp

@@ -133,44 +133,6 @@ inline bool JsonVariant::isFloat() const {
   return *end == '\0' && errno == 0 && !is<long>();
 }
 
-inline void JsonVariant::writeTo(Internals::JsonWriter &writer) const {
-  using namespace Internals;
-  switch (_type) {
-    case JSON_UNDEFINED:
-      return;
-
-    case JSON_ARRAY:
-      _content.asArray->writeTo(writer);
-      return;
-
-    case JSON_OBJECT:
-      _content.asObject->writeTo(writer);
-      return;
-
-    case JSON_STRING:
-      writer.writeString(_content.asString);
-      return;
-
-    case JSON_UNPARSED:
-      writer.writeRaw(_content.asString);
-      return;
-
-    case JSON_NEGATIVE_INTEGER:
-      writer.writeRaw('-');
-    case JSON_POSITIVE_INTEGER:
-      writer.writeInteger(_content.asInteger);
-      return;
-
-    case JSON_BOOLEAN:
-      writer.writeBoolean(_content.asInteger != 0);
-      return;
-
-    default:
-      uint8_t decimals = static_cast<uint8_t>(_type - JSON_FLOAT_0_DECIMALS);
-      writer.writeFloat(_content.asFloat, decimals);
-  }
-}
-
 #if ARDUINOJSON_ENABLE_STD_STREAM
 inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) {
   return source.printTo(os);

+ 0 - 3
include/ArduinoJson/JsonVariantBase.hpp

@@ -82,9 +82,6 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
   FORCE_INLINE const JsonObjectSubscript<const String &> operator[](
       const String &key) const;
 
-  // Serialize the variant to a JsonWriter
-  void writeTo(Internals::JsonWriter &writer) const;
-
  private:
   const TImpl *impl() const {
     return static_cast<const TImpl *>(this);