forked from bblanchon/ArduinoJson
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.
|
// etc.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class JsonWriter;
|
||||||
|
|
||||||
struct JsonNode
|
struct JsonNode
|
||||||
{
|
{
|
||||||
JsonNode* next;
|
JsonNode* next;
|
||||||
JsonNodeType type;
|
JsonNodeType type; // <- TODO: hide
|
||||||
|
|
||||||
|
void writeTo(JsonWriter&);
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
@ -49,4 +53,8 @@ struct JsonNode
|
|||||||
} asProxy;
|
} asProxy;
|
||||||
|
|
||||||
} content;
|
} 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 "JsonContainer.h"
|
||||||
|
|
||||||
#include "JsonBuffer.h"
|
#include "JsonBuffer.h"
|
||||||
#include "Internals/JsonNodeSerializer.h"
|
#include "Internals/JsonWriter.h"
|
||||||
#include "Internals/StringBuilder.h"
|
#include "Internals/StringBuilder.h"
|
||||||
|
|
||||||
size_t JsonContainer::printTo(char* buffer, size_t bufferSize) const
|
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
|
size_t JsonContainer::printTo(Print& p) const
|
||||||
{
|
{
|
||||||
JsonNodeSerializer serializer(p);
|
JsonWriter writer(p);
|
||||||
return serializer.serialize(_node);
|
_node->writeTo(writer);
|
||||||
|
return writer.bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode* JsonContainer::createNode(JsonNodeType type)
|
JsonNode* JsonContainer::createNode(JsonNodeType type)
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include "JsonValue.h"
|
#include "JsonValue.h"
|
||||||
#include "Internals/EscapedString.h"
|
#include "Internals/EscapedString.h"
|
||||||
#include "Internals/JsonNode.h"
|
#include "Internals/JsonNode.h"
|
||||||
#include "Internals/JsonNodeSerializer.h"
|
|
||||||
#include "Internals/StringBuilder.h"
|
#include "Internals/StringBuilder.h"
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
@ -78,7 +78,7 @@
|
|||||||
<ClInclude Include="JsonArray.h" />
|
<ClInclude Include="JsonArray.h" />
|
||||||
<ClInclude Include="JsonBuffer.h" />
|
<ClInclude Include="JsonBuffer.h" />
|
||||||
<ClInclude Include="Internals\JsonNode.h" />
|
<ClInclude Include="Internals\JsonNode.h" />
|
||||||
<ClInclude Include="Internals\JsonNodeSerializer.h" />
|
<ClInclude Include="Internals\JsonWriter.h" />
|
||||||
<ClInclude Include="JsonContainer.h" />
|
<ClInclude Include="JsonContainer.h" />
|
||||||
<ClInclude Include="Internals\JsonNodeIterator.h" />
|
<ClInclude Include="Internals\JsonNodeIterator.h" />
|
||||||
<ClInclude Include="JsonObject.h" />
|
<ClInclude Include="JsonObject.h" />
|
||||||
@ -90,9 +90,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Internals\EscapedString.cpp" />
|
<ClCompile Include="Internals\EscapedString.cpp" />
|
||||||
|
<ClCompile Include="Internals\JsonNode.cpp" />
|
||||||
<ClCompile Include="JsonArray.cpp" />
|
<ClCompile Include="JsonArray.cpp" />
|
||||||
<ClCompile Include="JsonBuffer.cpp" />
|
<ClCompile Include="JsonBuffer.cpp" />
|
||||||
<ClCompile Include="Internals\JsonNodeSerializer.cpp" />
|
<ClCompile Include="Internals\JsonWriter.cpp" />
|
||||||
<ClCompile Include="JsonContainer.cpp" />
|
<ClCompile Include="JsonContainer.cpp" />
|
||||||
<ClCompile Include="JsonObject.cpp" />
|
<ClCompile Include="JsonObject.cpp" />
|
||||||
<ClCompile Include="JsonValue.cpp" />
|
<ClCompile Include="JsonValue.cpp" />
|
||||||
|
@ -33,9 +33,6 @@
|
|||||||
<ClInclude Include="Internals\JsonNode.h">
|
<ClInclude Include="Internals\JsonNode.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Internals\JsonNodeSerializer.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Internals\StringBuilder.h">
|
<ClInclude Include="Internals\StringBuilder.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -54,6 +51,9 @@
|
|||||||
<ClInclude Include="JsonArray.h">
|
<ClInclude Include="JsonArray.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Internals\JsonWriter.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="JsonObject.cpp">
|
<ClCompile Include="JsonObject.cpp">
|
||||||
@ -68,9 +68,6 @@
|
|||||||
<ClCompile Include="Internals\EscapedString.cpp">
|
<ClCompile Include="Internals\EscapedString.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Internals\JsonNodeSerializer.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Internals\StringBuilder.cpp">
|
<ClCompile Include="Internals\StringBuilder.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -83,5 +80,11 @@
|
|||||||
<ClCompile Include="JsonArray.cpp">
|
<ClCompile Include="JsonArray.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Internals\JsonNode.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Internals\JsonWriter.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Reference in New Issue
Block a user