From a60b35f41cb9fc4ac4b574d43c7d20e6c035bdbd Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Sun, 11 Sep 2016 13:43:21 +0200 Subject: [PATCH] Extracted class JsonSerializer --- CHANGELOG.md | 5 + include/ArduinoJson.hpp | 1 + .../ArduinoJson/Internals/JsonPrintable.hpp | 9 +- .../ArduinoJson/Internals/JsonSerializer.hpp | 33 ++++++ .../ArduinoJson/Internals/JsonSerializer.ipp | 101 ++++++++++++++++++ include/ArduinoJson/JsonArray.hpp | 17 --- include/ArduinoJson/JsonArraySubscript.hpp | 4 - include/ArduinoJson/JsonObject.hpp | 19 ---- include/ArduinoJson/JsonObjectSubscript.hpp | 4 - include/ArduinoJson/JsonVariant.hpp | 20 ++-- include/ArduinoJson/JsonVariant.ipp | 38 ------- include/ArduinoJson/JsonVariantBase.hpp | 3 - 12 files changed, 160 insertions(+), 94 deletions(-) create mode 100644 include/ArduinoJson/Internals/JsonSerializer.hpp create mode 100644 include/ArduinoJson/Internals/JsonSerializer.ipp diff --git a/CHANGELOG.md b/CHANGELOG.md index 29b66fd1..3ef8b7ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ ArduinoJson: change log ======================= +HEAD +---- + +* Fixed `array[idx].as()` and `object[key].as()` + v5.6.6 ------ diff --git a/include/ArduinoJson.hpp b/include/ArduinoJson.hpp index 1573cb3b..0326578c 100644 --- a/include/ArduinoJson.hpp +++ b/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" diff --git a/include/ArduinoJson/Internals/JsonPrintable.hpp b/include/ArduinoJson/Internals/JsonPrintable.hpp index 279c6de7..620f79b9 100644 --- a/include/ArduinoJson/Internals/JsonPrintable.hpp +++ b/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(this); } + const T &downcast() const { + return *static_cast(this); + } }; #if ARDUINOJSON_ENABLE_STD_STREAM diff --git a/include/ArduinoJson/Internals/JsonSerializer.hpp b/include/ArduinoJson/Internals/JsonSerializer.hpp new file mode 100644 index 00000000..ec59d9b4 --- /dev/null +++ b/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 +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 + static void serialize(const JsonObjectSubscript &, JsonWriter &); + static void serialize(const JsonVariant &, JsonWriter &); +}; +} +} diff --git a/include/ArduinoJson/Internals/JsonSerializer.ipp b/include/ArduinoJson/Internals/JsonSerializer.ipp new file mode 100644 index 00000000..53e9e429 --- /dev/null +++ b/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(), 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 +inline void ArduinoJson::Internals::JsonSerializer::serialize( + const JsonObjectSubscript& objectSubscript, JsonWriter& writer) { + serialize(objectSubscript.template as(), 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(variant._type - JSON_FLOAT_0_DECIMALS); + writer.writeFloat(variant._content.asFloat, decimals); + } +} diff --git a/include/ArduinoJson/JsonArray.hpp b/include/ArduinoJson/JsonArray.hpp index 9055f4be..9f4344f6 100644 --- a/include/ArduinoJson/JsonArray.hpp +++ b/include/ArduinoJson/JsonArray.hpp @@ -170,23 +170,6 @@ class JsonArray : public Internals::JsonPrintable, 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 bool copyFrom(T(&array)[N]) { diff --git a/include/ArduinoJson/JsonArraySubscript.hpp b/include/ArduinoJson/JsonArraySubscript.hpp index d9397111..3151ec6a 100644 --- a/include/ArduinoJson/JsonArraySubscript.hpp +++ b/include/ArduinoJson/JsonArraySubscript.hpp @@ -60,10 +60,6 @@ class JsonArraySubscript : public JsonVariantBase { return _array.is(_index); } - void writeTo(Internals::JsonWriter& writer) const { - _array.get(_index).writeTo(writer); - } - template void set(TValue value) { _array.set(_index, value); diff --git a/include/ArduinoJson/JsonObject.hpp b/include/ArduinoJson/JsonObject.hpp index 101da1a4..6e098d22 100644 --- a/include/ArduinoJson/JsonObject.hpp +++ b/include/ArduinoJson/JsonObject.hpp @@ -144,25 +144,6 @@ class JsonObject : public Internals::JsonPrintable, 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 { diff --git a/include/ArduinoJson/JsonObjectSubscript.hpp b/include/ArduinoJson/JsonObjectSubscript.hpp index d3c68045..37827759 100644 --- a/include/ArduinoJson/JsonObjectSubscript.hpp +++ b/include/ArduinoJson/JsonObjectSubscript.hpp @@ -77,10 +77,6 @@ class JsonObjectSubscript : public JsonVariantBase > { return _object.get(_key); } - void writeTo(Internals::JsonWriter& writer) const { - _object.get(_key).writeTo(writer); - } - private: JsonObject& _object; TKey _key; diff --git a/include/ArduinoJson/JsonVariant.hpp b/include/ArduinoJson/JsonVariant.hpp index e1ed9558..9627fdeb 100644 --- a/include/ArduinoJson/JsonVariant.hpp +++ b/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 { + friend void Internals::JsonSerializer::serialize(const JsonVariant &, + JsonWriter &); + public: template struct IsConstructibleFrom; @@ -211,6 +214,14 @@ class JsonVariant : public JsonVariantBase { as() const { return asObject(); } + // + // JsonVariant as const; + template + typename TypeTraits::EnableIf::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 { return isArray(); } // - // JsonObject& as const; - // JsonObject& as const; - // JsonObject& as const; + // bool is const; + // bool is const; + // bool is const; template typename TypeTraits::EnableIf< TypeTraits::IsSame< @@ -285,9 +296,6 @@ class JsonVariant : public JsonVariantBase { 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 static typename Internals::JsonVariantAs::type defaultValue() { diff --git a/include/ArduinoJson/JsonVariant.ipp b/include/ArduinoJson/JsonVariant.ipp index bd0663f5..a9446ac1 100644 --- a/include/ArduinoJson/JsonVariant.ipp +++ b/include/ArduinoJson/JsonVariant.ipp @@ -133,44 +133,6 @@ inline bool JsonVariant::isFloat() const { return *end == '\0' && errno == 0 && !is(); } -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(_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); diff --git a/include/ArduinoJson/JsonVariantBase.hpp b/include/ArduinoJson/JsonVariantBase.hpp index 6dfca048..e1e6e536 100644 --- a/include/ArduinoJson/JsonVariantBase.hpp +++ b/include/ArduinoJson/JsonVariantBase.hpp @@ -82,9 +82,6 @@ class JsonVariantBase : public Internals::JsonPrintable { FORCE_INLINE const JsonObjectSubscript 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(this);