summaryrefslogtreecommitdiff
path: root/include/lib/ArduinoJson/Serialization/JsonWriter.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/lib/ArduinoJson/Serialization/JsonWriter.hpp')
-rw-r--r--include/lib/ArduinoJson/Serialization/JsonWriter.hpp155
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
+};
+}
+}