diff options
Diffstat (limited to 'include/lib/ArduinoJson/Serialization/JsonWriter.hpp')
-rw-r--r-- | include/lib/ArduinoJson/Serialization/JsonWriter.hpp | 155 |
1 files changed, 155 insertions, 0 deletions
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 +}; +} +} |