summaryrefslogtreecommitdiff
path: root/include/lib/ArduinoJson/Serialization
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2018-09-17 10:02:07 +0200
committerDaniel Friesel <derf@finalrewind.org>2018-09-17 10:02:07 +0200
commit4f6253aa9fec99260b8bb7b9b2e9003f5259b600 (patch)
tree2d0a3fdd10e258ecce5fb220547b1c43b870d6d2 /include/lib/ArduinoJson/Serialization
parent30c4f72770568749b4230a6b598e3fb87a065e91 (diff)
Import arduinojson and ubjson. Only partially working at the moment
Diffstat (limited to 'include/lib/ArduinoJson/Serialization')
-rw-r--r--include/lib/ArduinoJson/Serialization/DummyPrint.hpp22
-rw-r--r--include/lib/ArduinoJson/Serialization/DynamicStringBuilder.hpp35
-rw-r--r--include/lib/ArduinoJson/Serialization/FloatParts.hpp89
-rw-r--r--include/lib/ArduinoJson/Serialization/IndentedPrint.hpp68
-rw-r--r--include/lib/ArduinoJson/Serialization/JsonPrintable.hpp117
-rw-r--r--include/lib/ArduinoJson/Serialization/JsonSerializer.hpp32
-rw-r--r--include/lib/ArduinoJson/Serialization/JsonSerializerImpl.hpp103
-rw-r--r--include/lib/ArduinoJson/Serialization/JsonWriter.hpp155
-rw-r--r--include/lib/ArduinoJson/Serialization/Prettyfier.hpp133
-rw-r--r--include/lib/ArduinoJson/Serialization/StaticStringBuilder.hpp36
-rw-r--r--include/lib/ArduinoJson/Serialization/StreamPrintAdapter.hpp39
11 files changed, 829 insertions, 0 deletions
diff --git a/include/lib/ArduinoJson/Serialization/DummyPrint.hpp b/include/lib/ArduinoJson/Serialization/DummyPrint.hpp
new file mode 100644
index 0000000..9fdf2d6
--- /dev/null
+++ b/include/lib/ArduinoJson/Serialization/DummyPrint.hpp
@@ -0,0 +1,22 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2018
+// MIT License
+
+#pragma once
+
+namespace ArduinoJson {
+namespace Internals {
+
+// A dummy Print implementation used in JsonPrintable::measureLength()
+class DummyPrint {
+ public:
+ size_t print(char) {
+ return 1;
+ }
+
+ size_t print(const char* s) {
+ return strlen(s);
+ }
+};
+}
+}
diff --git a/include/lib/ArduinoJson/Serialization/DynamicStringBuilder.hpp b/include/lib/ArduinoJson/Serialization/DynamicStringBuilder.hpp
new file mode 100644
index 0000000..41be639
--- /dev/null
+++ b/include/lib/ArduinoJson/Serialization/DynamicStringBuilder.hpp
@@ -0,0 +1,35 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2018
+// MIT License
+
+#pragma once
+
+#include "../StringTraits/StringTraits.hpp"
+
+namespace ArduinoJson {
+namespace Internals {
+
+// A Print implementation that allows to write in a String
+template <typename TString>
+class DynamicStringBuilder {
+ public:
+ DynamicStringBuilder(TString &str) : _str(str) {}
+
+ size_t print(char c) {
+ StringTraits<TString>::append(_str, c);
+ return 1;
+ }
+
+ size_t print(const char *s) {
+ size_t initialLen = _str.length();
+ StringTraits<TString>::append(_str, s);
+ return _str.length() - initialLen;
+ }
+
+ private:
+ DynamicStringBuilder &operator=(const DynamicStringBuilder &);
+
+ TString &_str;
+};
+}
+}
diff --git a/include/lib/ArduinoJson/Serialization/FloatParts.hpp b/include/lib/ArduinoJson/Serialization/FloatParts.hpp
new file mode 100644
index 0000000..c14e3b5
--- /dev/null
+++ b/include/lib/ArduinoJson/Serialization/FloatParts.hpp
@@ -0,0 +1,89 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2018
+// MIT License
+
+#pragma once
+
+#include "../Configuration.hpp"
+#include "../Polyfills/math.hpp"
+#include "../TypeTraits/FloatTraits.hpp"
+
+namespace ArduinoJson {
+namespace Internals {
+
+template <typename TFloat>
+struct FloatParts {
+ uint32_t integral;
+ uint32_t decimal;
+ int16_t exponent;
+ int8_t decimalPlaces;
+
+ FloatParts(TFloat value) {
+ uint32_t maxDecimalPart = sizeof(TFloat) >= 8 ? 1000000000 : 1000000;
+ decimalPlaces = sizeof(TFloat) >= 8 ? 9 : 6;
+
+ exponent = normalize(value);
+
+ integral = uint32_t(value);
+ // reduce number of decimal places by the number of integral places
+ for (uint32_t tmp = integral; tmp >= 10; tmp /= 10) {
+ maxDecimalPart /= 10;
+ decimalPlaces--;
+ }
+
+ TFloat remainder = (value - TFloat(integral)) * TFloat(maxDecimalPart);
+
+ decimal = uint32_t(remainder);
+ remainder = remainder - TFloat(decimal);
+
+ // rounding:
+ // increment by 1 if remainder >= 0.5
+ decimal += uint32_t(remainder * 2);
+ if (decimal >= maxDecimalPart) {
+ decimal = 0;
+ integral++;
+ if (exponent && integral >= 10) {
+ exponent++;
+ integral = 1;
+ }
+ }
+
+ // remove trailing zeros
+ while (decimal % 10 == 0 && decimalPlaces > 0) {
+ decimal /= 10;
+ decimalPlaces--;
+ }
+ }
+
+ static int16_t normalize(TFloat& value) {
+ typedef FloatTraits<TFloat> traits;
+ int16_t powersOf10 = 0;
+
+ int8_t index = sizeof(TFloat) == 8 ? 8 : 5;
+ int bit = 1 << index;
+
+ if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
+ for (; index >= 0; index--) {
+ if (value >= traits::positiveBinaryPowerOfTen(index)) {
+ value *= traits::negativeBinaryPowerOfTen(index);
+ powersOf10 = int16_t(powersOf10 + bit);
+ }
+ bit >>= 1;
+ }
+ }
+
+ if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
+ for (; index >= 0; index--) {
+ if (value < traits::negativeBinaryPowerOfTenPlusOne(index)) {
+ value *= traits::positiveBinaryPowerOfTen(index);
+ powersOf10 = int16_t(powersOf10 - bit);
+ }
+ bit >>= 1;
+ }
+ }
+
+ return powersOf10;
+ }
+};
+}
+}
diff --git a/include/lib/ArduinoJson/Serialization/IndentedPrint.hpp b/include/lib/ArduinoJson/Serialization/IndentedPrint.hpp
new file mode 100644
index 0000000..864f9aa
--- /dev/null
+++ b/include/lib/ArduinoJson/Serialization/IndentedPrint.hpp
@@ -0,0 +1,68 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2018
+// MIT License
+
+#pragma once
+
+namespace ArduinoJson {
+namespace Internals {
+
+// Decorator on top of Print to allow indented output.
+// This class is used by JsonPrintable::prettyPrintTo() but can also be used
+// for your own purpose, like logging.
+template <typename Print>
+class IndentedPrint {
+ public:
+ explicit IndentedPrint(Print &p) : sink(&p) {
+ level = 0;
+ tabSize = 2;
+ isNewLine = true;
+ }
+
+ size_t print(char c) {
+ size_t n = 0;
+ if (isNewLine) n += writeTabs();
+ n += sink->print(c);
+ isNewLine = c == '\n';
+ return n;
+ }
+
+ size_t print(const char *s) {
+ // TODO: optimize
+ size_t n = 0;
+ while (*s) n += print(*s++);
+ return n;
+ }
+
+ // Adds one level of indentation
+ void indent() {
+ if (level < MAX_LEVEL) level++;
+ }
+
+ // Removes one level of indentation
+ void unindent() {
+ if (level > 0) level--;
+ }
+
+ // Set the number of space printed for each level of indentation
+ void setTabSize(uint8_t n) {
+ if (n < MAX_TAB_SIZE) tabSize = n & MAX_TAB_SIZE;
+ }
+
+ private:
+ Print *sink;
+ uint8_t level : 4;
+ uint8_t tabSize : 3;
+ bool isNewLine : 1;
+
+ size_t writeTabs() {
+ size_t n = 0;
+ for (int i = 0; i < level * tabSize; i++) n += sink->print(' ');
+ return n;
+ }
+
+ static const int MAX_LEVEL = 15; // because it's only 4 bits
+ static const int MAX_TAB_SIZE = 7; // because it's only 3 bits
+};
+}
+}
diff --git a/include/lib/ArduinoJson/Serialization/JsonPrintable.hpp b/include/lib/ArduinoJson/Serialization/JsonPrintable.hpp
new file mode 100644
index 0000000..43d413a
--- /dev/null
+++ b/include/lib/ArduinoJson/Serialization/JsonPrintable.hpp
@@ -0,0 +1,117 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2018
+// MIT License
+
+#pragma once
+
+#include "../Configuration.hpp"
+#include "../TypeTraits/EnableIf.hpp"
+#include "DummyPrint.hpp"
+#include "DynamicStringBuilder.hpp"
+#include "IndentedPrint.hpp"
+#include "JsonSerializer.hpp"
+#include "JsonWriter.hpp"
+#include "Prettyfier.hpp"
+#include "StaticStringBuilder.hpp"
+
+#if ARDUINOJSON_ENABLE_STD_STREAM
+#include "StreamPrintAdapter.hpp"
+#endif
+
+namespace ArduinoJson {
+namespace Internals {
+
+// Implements all the overloads of printTo() and prettyPrintTo()
+// Caution: this class use a template parameter to avoid virtual methods.
+// This is a bit curious but allows to reduce the size of JsonVariant, JsonArray
+// and JsonObject.
+template <typename T>
+class JsonPrintable {
+ public:
+ template <typename Print>
+ typename EnableIf<!StringTraits<Print>::has_append, size_t>::type printTo(
+ Print &print) const {
+ JsonWriter<Print> writer(print);
+ JsonSerializer<JsonWriter<Print> >::serialize(downcast(), writer);
+ return writer.bytesWritten();
+ }
+
+#if ARDUINOJSON_ENABLE_STD_STREAM
+ std::ostream &printTo(std::ostream &os) const {
+ StreamPrintAdapter adapter(os);
+ printTo(adapter);
+ return os;
+ }
+#endif
+
+ size_t printTo(char *buffer, size_t bufferSize) const {
+ StaticStringBuilder sb(buffer, bufferSize);
+ return printTo(sb);
+ }
+
+ template <size_t N>
+ size_t printTo(char (&buffer)[N]) const {
+ return printTo(buffer, N);
+ }
+
+ template <typename TString>
+ typename EnableIf<StringTraits<TString>::has_append, size_t>::type printTo(
+ TString &str) const {
+ DynamicStringBuilder<TString> sb(str);
+ return printTo(sb);
+ }
+
+ template <typename Print>
+ size_t prettyPrintTo(IndentedPrint<Print> &print) const {
+ Prettyfier<Print> p(print);
+ return printTo(p);
+ }
+
+ size_t prettyPrintTo(char *buffer, size_t bufferSize) const {
+ StaticStringBuilder sb(buffer, bufferSize);
+ return prettyPrintTo(sb);
+ }
+
+ template <size_t N>
+ size_t prettyPrintTo(char (&buffer)[N]) const {
+ return prettyPrintTo(buffer, N);
+ }
+
+ template <typename Print>
+ typename EnableIf<!StringTraits<Print>::has_append, size_t>::type
+ prettyPrintTo(Print &print) const {
+ IndentedPrint<Print> indentedPrint(print);
+ return prettyPrintTo(indentedPrint);
+ }
+
+ template <typename TString>
+ typename EnableIf<StringTraits<TString>::has_append, size_t>::type
+ prettyPrintTo(TString &str) const {
+ DynamicStringBuilder<TString> sb(str);
+ return prettyPrintTo(sb);
+ }
+
+ size_t measureLength() const {
+ DummyPrint dp;
+ return printTo(dp);
+ }
+
+ size_t measurePrettyLength() const {
+ DummyPrint dp;
+ return prettyPrintTo(dp);
+ }
+
+ private:
+ const T &downcast() const {
+ return *static_cast<const T *>(this);
+ }
+};
+
+#if ARDUINOJSON_ENABLE_STD_STREAM
+template <typename T>
+inline std::ostream &operator<<(std::ostream &os, const JsonPrintable<T> &v) {
+ return v.printTo(os);
+}
+#endif
+}
+}
diff --git a/include/lib/ArduinoJson/Serialization/JsonSerializer.hpp b/include/lib/ArduinoJson/Serialization/JsonSerializer.hpp
new file mode 100644
index 0000000..0cb537f
--- /dev/null
+++ b/include/lib/ArduinoJson/Serialization/JsonSerializer.hpp
@@ -0,0 +1,32 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2018
+// MIT License
+
+#pragma once
+
+#include "JsonWriter.hpp"
+
+namespace ArduinoJson {
+
+class JsonArray;
+class JsonObject;
+class JsonVariant;
+
+namespace Internals {
+
+class JsonArraySubscript;
+template <typename TKey>
+class JsonObjectSubscript;
+
+template <typename Writer>
+class JsonSerializer {
+ public:
+ static void serialize(const JsonArray &, Writer &);
+ static void serialize(const JsonArraySubscript &, Writer &);
+ static void serialize(const JsonObject &, Writer &);
+ template <typename TKey>
+ static void serialize(const JsonObjectSubscript<TKey> &, Writer &);
+ static void serialize(const JsonVariant &, Writer &);
+};
+}
+}
diff --git a/include/lib/ArduinoJson/Serialization/JsonSerializerImpl.hpp b/include/lib/ArduinoJson/Serialization/JsonSerializerImpl.hpp
new file mode 100644
index 0000000..0faae27
--- /dev/null
+++ b/include/lib/ArduinoJson/Serialization/JsonSerializerImpl.hpp
@@ -0,0 +1,103 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2018
+// MIT License
+
+#pragma once
+
+#include "../JsonArray.hpp"
+#include "../JsonArraySubscript.hpp"
+#include "../JsonObject.hpp"
+#include "../JsonObjectSubscript.hpp"
+#include "../JsonVariant.hpp"
+#include "JsonSerializer.hpp"
+
+template <typename Writer>
+inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
+ const JsonArray& array, Writer& 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();
+}
+
+template <typename Writer>
+inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
+ const JsonArraySubscript& arraySubscript, Writer& writer) {
+ serialize(arraySubscript.as<JsonVariant>(), writer);
+}
+
+template <typename Writer>
+inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
+ const JsonObject& object, Writer& 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 Writer>
+template <typename TKey>
+inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
+ const JsonObjectSubscript<TKey>& objectSubscript, Writer& writer) {
+ serialize(objectSubscript.template as<JsonVariant>(), writer);
+}
+
+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;
+ }
+}
diff --git a/include/lib/ArduinoJson/Serialization/JsonWriter.hpp b/include/lib/ArduinoJson/Serialization/JsonWriter.hpp
new file mode 100644
index 0000000..146d51d
--- /dev/null
+++ b/include/lib/ArduinoJson/Serialization/JsonWriter.hpp
@@ -0,0 +1,155 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2018
+// MIT License
+
+#pragma once
+
+#include <stdint.h>
+#include "../Data/Encoding.hpp"
+#include "../Data/JsonInteger.hpp"
+#include "../Polyfills/attributes.hpp"
+#include "../Serialization/FloatParts.hpp"
+
+namespace ArduinoJson {
+namespace Internals {
+
+// Writes the JSON tokens to a Print implementation
+// This class is used by:
+// - JsonArray::writeTo()
+// - JsonObject::writeTo()
+// - JsonVariant::writeTo()
+// Its derived by PrettyJsonWriter that overrides some members to add
+// indentation.
+template <typename Print>
+class JsonWriter {
+ public:
+ explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {}
+
+ // Returns the number of bytes sent to the Print implementation.
+ // This is very handy for implementations of printTo() that must return the
+ // number of bytes written.
+ size_t bytesWritten() const {
+ return _length;
+ }
+
+ void beginArray() {
+ writeRaw('[');
+ }
+ void endArray() {
+ writeRaw(']');
+ }
+
+ void beginObject() {
+ writeRaw('{');
+ }
+ void endObject() {
+ writeRaw('}');
+ }
+
+ void writeColon() {
+ writeRaw(':');
+ }
+ void writeComma() {
+ writeRaw(',');
+ }
+
+ void writeBoolean(bool value) {
+ writeRaw(value ? "true" : "false");
+ }
+
+ void writeString(const char *value) {
+ if (!value) {
+ writeRaw("null");
+ } else {
+ writeRaw('\"');
+ while (*value) writeChar(*value++);
+ writeRaw('\"');
+ }
+ }
+
+ void writeChar(char c) {
+ char specialChar = Encoding::escapeChar(c);
+ if (specialChar) {
+ writeRaw('\\');
+ writeRaw(specialChar);
+ } else {
+ writeRaw(c);
+ }
+ }
+
+ template <typename TFloat>
+ void writeFloat(TFloat value) {
+ if (isNaN(value)) return writeRaw("NaN");
+
+ if (value < 0.0) {
+ writeRaw('-');
+ value = -value;
+ }
+
+ if (isInfinity(value)) return writeRaw("Infinity");
+
+ FloatParts<TFloat> parts(value);
+
+ writeInteger(parts.integral);
+ if (parts.decimalPlaces) writeDecimals(parts.decimal, parts.decimalPlaces);
+
+ if (parts.exponent < 0) {
+ writeRaw("e-");
+ writeInteger(-parts.exponent);
+ }
+
+ if (parts.exponent > 0) {
+ writeRaw('e');
+ writeInteger(parts.exponent);
+ }
+ }
+
+ template <typename UInt>
+ void writeInteger(UInt value) {
+ char buffer[22];
+ char *end = buffer + sizeof(buffer) - 1;
+ char *ptr = end;
+
+ *ptr = 0;
+ do {
+ *--ptr = char(value % 10 + '0');
+ value = UInt(value / 10);
+ } while (value);
+
+ writeRaw(ptr);
+ }
+
+ void writeDecimals(uint32_t value, int8_t width) {
+ // buffer should be big enough for all digits, the dot and the null
+ // terminator
+ char buffer[16];
+ char *ptr = buffer + sizeof(buffer) - 1;
+
+ // write the string in reverse order
+ *ptr = 0;
+ while (width--) {
+ *--ptr = char(value % 10 + '0');
+ value /= 10;
+ }
+ *--ptr = '.';
+
+ // and dump it in the right order
+ writeRaw(ptr);
+ }
+
+ void writeRaw(const char *s) {
+ _length += _sink.print(s);
+ }
+ void writeRaw(char c) {
+ _length += _sink.print(c);
+ }
+
+ protected:
+ Print &_sink;
+ size_t _length;
+
+ private:
+ JsonWriter &operator=(const JsonWriter &); // cannot be assigned
+};
+}
+}
diff --git a/include/lib/ArduinoJson/Serialization/Prettyfier.hpp b/include/lib/ArduinoJson/Serialization/Prettyfier.hpp
new file mode 100644
index 0000000..8b4f0d2
--- /dev/null
+++ b/include/lib/ArduinoJson/Serialization/Prettyfier.hpp
@@ -0,0 +1,133 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2018
+// MIT License
+
+#pragma once
+
+#include "IndentedPrint.hpp"
+
+namespace ArduinoJson {
+namespace Internals {
+
+// Converts a compact JSON string into an indented one.
+template <typename Print>
+class Prettyfier {
+ public:
+ explicit Prettyfier(IndentedPrint<Print>& p) : _sink(p) {
+ _previousChar = 0;
+ _inString = false;
+ }
+
+ size_t print(char c) {
+ size_t n = _inString ? handleStringChar(c) : handleMarkupChar(c);
+ _previousChar = c;
+ return n;
+ }
+
+ size_t print(const char* s) {
+ // TODO: optimize
+ size_t n = 0;
+ while (*s) n += print(*s++);
+ return n;
+ }
+
+ private:
+ Prettyfier& operator=(const Prettyfier&); // cannot be assigned
+
+ bool inEmptyBlock() {
+ return _previousChar == '{' || _previousChar == '[';
+ }
+
+ size_t handleStringChar(char c) {
+ bool isQuote = c == '"' && _previousChar != '\\';
+
+ if (isQuote) _inString = false;
+
+ return _sink.print(c);
+ }
+
+ size_t handleMarkupChar(char c) {
+ switch (c) {
+ case '{':
+ case '[':
+ return writeBlockOpen(c);
+
+ case '}':
+ case ']':
+ return writeBlockClose(c);
+
+ case ':':
+ return writeColon();
+
+ case ',':
+ return writeComma();
+
+ case '"':
+ return writeQuoteOpen();
+
+ default:
+ return writeNormalChar(c);
+ }
+ }
+
+ size_t writeBlockClose(char c) {
+ size_t n = 0;
+ n += unindentIfNeeded();
+ n += _sink.print(c);
+ return n;
+ }
+
+ size_t writeBlockOpen(char c) {
+ size_t n = 0;
+ n += indentIfNeeded();
+ n += _sink.print(c);
+ return n;
+ }
+
+ size_t writeColon() {
+ size_t n = 0;
+ n += _sink.print(": ");
+ return n;
+ }
+
+ size_t writeComma() {
+ size_t n = 0;
+ n += _sink.print(",\r\n");
+ return n;
+ }
+
+ size_t writeQuoteOpen() {
+ _inString = true;
+ size_t n = 0;
+ n += indentIfNeeded();
+ n += _sink.print('"');
+ return n;
+ }
+
+ size_t writeNormalChar(char c) {
+ size_t n = 0;
+ n += indentIfNeeded();
+ n += _sink.print(c);
+ return n;
+ }
+
+ size_t indentIfNeeded() {
+ if (!inEmptyBlock()) return 0;
+
+ _sink.indent();
+ return _sink.print("\r\n");
+ }
+
+ size_t unindentIfNeeded() {
+ if (inEmptyBlock()) return 0;
+
+ _sink.unindent();
+ return _sink.print("\r\n");
+ }
+
+ char _previousChar;
+ IndentedPrint<Print>& _sink;
+ bool _inString;
+};
+}
+}
diff --git a/include/lib/ArduinoJson/Serialization/StaticStringBuilder.hpp b/include/lib/ArduinoJson/Serialization/StaticStringBuilder.hpp
new file mode 100644
index 0000000..9617bbd
--- /dev/null
+++ b/include/lib/ArduinoJson/Serialization/StaticStringBuilder.hpp
@@ -0,0 +1,36 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2018
+// MIT License
+
+#pragma once
+
+namespace ArduinoJson {
+namespace Internals {
+
+// A Print implementation that allows to write in a char[]
+class StaticStringBuilder {
+ public:
+ StaticStringBuilder(char *buf, size_t size) : end(buf + size - 1), p(buf) {
+ *p = '\0';
+ }
+
+ size_t print(char c) {
+ if (p >= end) return 0;
+ *p++ = c;
+ *p = '\0';
+ return 1;
+ }
+
+ size_t print(const char *s) {
+ char *begin = p;
+ while (p < end && *s) *p++ = *s++;
+ *p = '\0';
+ return size_t(p - begin);
+ }
+
+ private:
+ char *end;
+ char *p;
+};
+}
+}
diff --git a/include/lib/ArduinoJson/Serialization/StreamPrintAdapter.hpp b/include/lib/ArduinoJson/Serialization/StreamPrintAdapter.hpp
new file mode 100644
index 0000000..60f0af4
--- /dev/null
+++ b/include/lib/ArduinoJson/Serialization/StreamPrintAdapter.hpp
@@ -0,0 +1,39 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2018
+// MIT License
+
+#pragma once
+
+#include "../Configuration.hpp"
+
+#if ARDUINOJSON_ENABLE_STD_STREAM
+
+#include <ostream>
+
+namespace ArduinoJson {
+namespace Internals {
+
+class StreamPrintAdapter {
+ public:
+ explicit StreamPrintAdapter(std::ostream& os) : _os(os) {}
+
+ size_t print(char c) {
+ _os << c;
+ return 1;
+ }
+
+ size_t print(const char* s) {
+ _os << s;
+ return strlen(s);
+ }
+
+ private:
+ // cannot be assigned
+ StreamPrintAdapter& operator=(const StreamPrintAdapter&);
+
+ std::ostream& _os;
+};
+}
+}
+
+#endif // ARDUINOJSON_ENABLE_STD_STREAM