diff --git a/srcs/Internals/JsonNode.cpp b/srcs/Internals/JsonNode.cpp
new file mode 100644
index 00000000..004b8d17
--- /dev/null
+++ b/srcs/Internals/JsonNode.cpp
@@ -0,0 +1,72 @@
+#include "JsonNode.h"
+
+#include "JsonWriter.h"
+#include "../JsonArray.h"
+#include "../JsonObject.h"
+
+void JsonNode::writeTo(JsonWriter& writer)
+{
+ switch (type)
+ {
+ case JSON_ARRAY:
+ writeArrayTo(writer);
+ break;
+
+ case JSON_OBJECT:
+ writeObjectTo(writer);
+ break;
+
+ case JSON_STRING:
+ writer.writeValue(content.asString);
+ break;
+
+ case JSON_INTEGER:
+ writer.writeValue(content.asInteger);
+ break;
+
+ case JSON_BOOLEAN:
+ writer.writeValue(content.asBoolean);
+ break;
+
+ case JSON_PROXY:
+ content.asProxy.target->writeTo(writer);
+ break;
+
+ default: // >= JSON_DOUBLE_0_DECIMALS
+ writer.writeValue(content.asDouble, type - JSON_DOUBLE_0_DECIMALS);
+ break;
+ }
+}
+
+void JsonNode::writeArrayTo(JsonWriter& writer)
+{
+ writer.beginArray();
+
+ JsonNode* child = content.asContainer.child;
+
+ while(child)
+ {
+ child->writeTo(writer);
+
+ child = child->next;
+ }
+
+ writer.endArray();
+}
+
+void JsonNode::writeObjectTo(JsonWriter& writer)
+{
+ writer.beginObject();
+
+ JsonNode* child = content.asContainer.child;
+
+ while (child)
+ {
+ writer.writeKey(child->content.asKey.key);
+ child->content.asKey.value->writeTo(writer);
+
+ child = child->next;
+ }
+
+ writer.endObject();
+}
\ No newline at end of file
diff --git a/srcs/Internals/JsonNode.h b/srcs/Internals/JsonNode.h
index efa897b2..b11dac02 100644
--- a/srcs/Internals/JsonNode.h
+++ b/srcs/Internals/JsonNode.h
@@ -19,10 +19,14 @@ enum JsonNodeType
// etc.
};
+class JsonWriter;
+
struct JsonNode
{
- JsonNode* next;
- JsonNodeType type;
+ JsonNode* next;
+ JsonNodeType type; // <- TODO: hide
+
+ void writeTo(JsonWriter&);
union
{
@@ -49,4 +53,8 @@ struct JsonNode
} asProxy;
} content;
+
+private:
+ inline void writeArrayTo(JsonWriter&);
+ inline void writeObjectTo(JsonWriter&);
};
\ No newline at end of file
diff --git a/srcs/Internals/JsonNodeSerializer.cpp b/srcs/Internals/JsonNodeSerializer.cpp
deleted file mode 100644
index effb5979..00000000
--- a/srcs/Internals/JsonNodeSerializer.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-#include "JsonNodeSerializer.h"
-
-#include "EscapedString.h"
-#include "JsonNode.h"
-
-using namespace ArduinoJson::Internals;
-
-size_t JsonNodeSerializer::serialize(const JsonNode* node)
-{
- if (!node) return 0;
-
- switch (node->type)
- {
- case JSON_ARRAY:
- return serializeArray(node);
-
- case JSON_OBJECT:
- return serializeObject(node);
-
- case JSON_STRING:
- return EscapedString::printTo(node->content.asString, _sink);
-
- case JSON_INTEGER:
- return _sink.print(node->content.asInteger);
-
- case JSON_BOOLEAN:
- return _sink.print(node->content.asBoolean ? "true" : "false");
-
- case JSON_PROXY:
- return serialize(node->content.asProxy.target);
- }
-
- if (node->type >= JSON_DOUBLE_0_DECIMALS)
- {
- return _sink.print(node->content.asDouble, node->type - JSON_DOUBLE_0_DECIMALS);
- }
-
- return 0;
-}
-
-size_t JsonNodeSerializer::serializeArray(JsonNode const* node)
-{
- size_t n = 0;
-
- n += _sink.write('[');
-
- JsonNode* firstChild = node->content.asContainer.child;
-
- for (JsonNode* child = firstChild; child; child = child->next)
- {
- n += serialize(child);
-
- if (child->next)
- {
- n += _sink.write(',');
- }
- }
-
- n += _sink.write(']');
-
- return n;
-}
-
-size_t JsonNodeSerializer::serializeObject(const JsonNode* node)
-{
- size_t n = 0;
-
- n += _sink.write('{');
-
- JsonNode* firstChild = node->content.asContainer.child;
-
- for (JsonNode* child = firstChild; child; child = child->next)
- {
- n += serializeKeyValue(child);
-
- if (child->next)
- {
- n += _sink.write(',');
- }
- }
-
- n += _sink.write('}');
-
- return n;
-}
-
-size_t JsonNodeSerializer::serializeKeyValue(JsonNode const* node)
-{
- const char* childKey = node->content.asKey.key;
- JsonNode* childValue = node->content.asKey.value;
-
- return
- EscapedString::printTo(childKey, _sink) +
- _sink.write(':') +
- serialize(childValue);
-}
\ No newline at end of file
diff --git a/srcs/Internals/JsonNodeSerializer.h b/srcs/Internals/JsonNodeSerializer.h
deleted file mode 100644
index ef1309e1..00000000
--- a/srcs/Internals/JsonNodeSerializer.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-class Print;
-struct JsonNode;
-
-class JsonNodeSerializer
-{
-public:
- explicit JsonNodeSerializer(Print& sink)
- : _sink(sink)
- {
- }
-
- size_t serialize(const JsonNode* node);
-
-private:
- Print& _sink;
-
- size_t serializeArray(const JsonNode* node);
- size_t serializeObject(const JsonNode* node);
- size_t serializeKeyValue(const JsonNode* node);
-};
-
diff --git a/srcs/Internals/JsonWriter.cpp b/srcs/Internals/JsonWriter.cpp
new file mode 100644
index 00000000..536bda63
--- /dev/null
+++ b/srcs/Internals/JsonWriter.cpp
@@ -0,0 +1,66 @@
+#include "JsonWriter.h"
+#include "EscapedString.h"
+
+using namespace ArduinoJson::Internals;
+
+void JsonWriter::beginArray()
+{
+ writeCommaIfNeeded();
+ _length += _sink.write('[');
+ _isCommaNeeded = false;
+}
+
+void JsonWriter::endArray()
+{
+ _length += _sink.write(']');
+ _isCommaNeeded = true;
+}
+
+void JsonWriter::beginObject()
+{
+ writeCommaIfNeeded();
+ _length += _sink.write('{');
+ _isCommaNeeded = false;
+}
+
+void JsonWriter::endObject()
+{
+ _length += _sink.write('}');
+ _isCommaNeeded = true;
+}
+
+void JsonWriter::writeKey(char const* key)
+{
+ writeCommaIfNeeded();
+ _length += EscapedString::printTo(key, _sink);
+ _length += _sink.write(':');
+ _isCommaNeeded = false;
+}
+
+void JsonWriter::writeValue(char const* value)
+{
+ writeCommaIfNeeded();
+ _length += EscapedString::printTo(value, _sink);
+ _isCommaNeeded = true;
+}
+
+void JsonWriter::writeValue(long value)
+{
+ writeCommaIfNeeded();
+ _length += _sink.print(value);
+ _isCommaNeeded = true;
+}
+
+void JsonWriter::writeValue(bool value)
+{
+ writeCommaIfNeeded();
+ _length += _sink.print(value ? "true" : "false");
+ _isCommaNeeded = true;
+}
+
+void JsonWriter::writeValue(double value, int decimals)
+{
+ writeCommaIfNeeded();
+ _length += _sink.print(value, decimals);
+ _isCommaNeeded = true;
+}
\ No newline at end of file
diff --git a/srcs/Internals/JsonWriter.h b/srcs/Internals/JsonWriter.h
new file mode 100644
index 00000000..7a65b3a2
--- /dev/null
+++ b/srcs/Internals/JsonWriter.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include "../Arduino/Print.h"
+
+class JsonWriter
+{
+public:
+ explicit JsonWriter(Print& sink)
+ : _sink(sink), _length(0), _isCommaNeeded(false)
+ {
+ }
+
+ size_t bytesWritten()
+ {
+ return _length;
+ }
+
+ void beginArray();
+ void endArray();
+
+ void beginObject();
+ void endObject();
+
+ void writeKey(const char* key);
+
+ void writeValue(const char* value);
+ void writeValue(long value);
+ void writeValue(bool value);
+ void writeValue(double value, int decimals);
+
+private:
+ Print& _sink;
+ size_t _length;
+ bool _isCommaNeeded;
+
+ void writeCommaIfNeeded()
+ {
+ if (_isCommaNeeded)
+ _length += _sink.write(',');
+ }
+};
+
diff --git a/srcs/JsonContainer.cpp b/srcs/JsonContainer.cpp
index 33ef4fa7..77628861 100644
--- a/srcs/JsonContainer.cpp
+++ b/srcs/JsonContainer.cpp
@@ -1,7 +1,7 @@
#include "JsonContainer.h"
#include "JsonBuffer.h"
-#include "Internals/JsonNodeSerializer.h"
+#include "Internals/JsonWriter.h"
#include "Internals/StringBuilder.h"
size_t JsonContainer::printTo(char* buffer, size_t bufferSize) const
@@ -12,8 +12,9 @@ size_t JsonContainer::printTo(char* buffer, size_t bufferSize) const
size_t JsonContainer::printTo(Print& p) const
{
- JsonNodeSerializer serializer(p);
- return serializer.serialize(_node);
+ JsonWriter writer(p);
+ _node->writeTo(writer);
+ return writer.bytesWritten();
}
JsonNode* JsonContainer::createNode(JsonNodeType type)
diff --git a/srcs/JsonObject.cpp b/srcs/JsonObject.cpp
index fc570c40..eedfd48f 100644
--- a/srcs/JsonObject.cpp
+++ b/srcs/JsonObject.cpp
@@ -6,7 +6,6 @@
#include "JsonValue.h"
#include "Internals/EscapedString.h"
#include "Internals/JsonNode.h"
-#include "Internals/JsonNodeSerializer.h"
#include "Internals/StringBuilder.h"
using namespace ArduinoJson::Internals;
diff --git a/srcs/srcs.vcxproj b/srcs/srcs.vcxproj
index 3b029490..36440c22 100644
--- a/srcs/srcs.vcxproj
+++ b/srcs/srcs.vcxproj
@@ -78,7 +78,7 @@
-
+
@@ -90,9 +90,10 @@
+
-
+
diff --git a/srcs/srcs.vcxproj.filters b/srcs/srcs.vcxproj.filters
index 5ad72fd5..35f07402 100644
--- a/srcs/srcs.vcxproj.filters
+++ b/srcs/srcs.vcxproj.filters
@@ -33,9 +33,6 @@
Header Files
-
- Header Files
-
Header Files
@@ -54,6 +51,9 @@
Header Files
+
+ Header Files
+
@@ -68,9 +68,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -83,5 +80,11 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
\ No newline at end of file