mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-17 04:22:18 +02:00
Refactored the serialization
This commit is contained in:
72
srcs/Internals/JsonNode.cpp
Normal file
72
srcs/Internals/JsonNode.cpp
Normal file
@ -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();
|
||||
}
|
@ -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&);
|
||||
};
|
@ -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);
|
||||
}
|
@ -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);
|
||||
};
|
||||
|
66
srcs/Internals/JsonWriter.cpp
Normal file
66
srcs/Internals/JsonWriter.cpp
Normal file
@ -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;
|
||||
}
|
42
srcs/Internals/JsonWriter.h
Normal file
42
srcs/Internals/JsonWriter.h
Normal file
@ -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(',');
|
||||
}
|
||||
};
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -78,7 +78,7 @@
|
||||
<ClInclude Include="JsonArray.h" />
|
||||
<ClInclude Include="JsonBuffer.h" />
|
||||
<ClInclude Include="Internals\JsonNode.h" />
|
||||
<ClInclude Include="Internals\JsonNodeSerializer.h" />
|
||||
<ClInclude Include="Internals\JsonWriter.h" />
|
||||
<ClInclude Include="JsonContainer.h" />
|
||||
<ClInclude Include="Internals\JsonNodeIterator.h" />
|
||||
<ClInclude Include="JsonObject.h" />
|
||||
@ -90,9 +90,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Internals\EscapedString.cpp" />
|
||||
<ClCompile Include="Internals\JsonNode.cpp" />
|
||||
<ClCompile Include="JsonArray.cpp" />
|
||||
<ClCompile Include="JsonBuffer.cpp" />
|
||||
<ClCompile Include="Internals\JsonNodeSerializer.cpp" />
|
||||
<ClCompile Include="Internals\JsonWriter.cpp" />
|
||||
<ClCompile Include="JsonContainer.cpp" />
|
||||
<ClCompile Include="JsonObject.cpp" />
|
||||
<ClCompile Include="JsonValue.cpp" />
|
||||
|
@ -33,9 +33,6 @@
|
||||
<ClInclude Include="Internals\JsonNode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Internals\JsonNodeSerializer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Internals\StringBuilder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -54,6 +51,9 @@
|
||||
<ClInclude Include="JsonArray.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Internals\JsonWriter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="JsonObject.cpp">
|
||||
@ -68,9 +68,6 @@
|
||||
<ClCompile Include="Internals\EscapedString.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Internals\JsonNodeSerializer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Internals\StringBuilder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -83,5 +80,11 @@
|
||||
<ClCompile Include="JsonArray.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Internals\JsonNode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Internals\JsonWriter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
Reference in New Issue
Block a user