forked from bblanchon/ArduinoJson
Pulled up code from JsonObject to JsonContainer
This commit is contained in:
37
srcs/Internals/JsonNodeIterator.h
Normal file
37
srcs/Internals/JsonNodeIterator.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "JsonNode.h"
|
||||||
|
|
||||||
|
class JsonNodeIterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit JsonNodeIterator(JsonNode* node)
|
||||||
|
: node(node)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!= (const JsonNodeIterator& other) const
|
||||||
|
{
|
||||||
|
return node != other.node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator++()
|
||||||
|
{
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode* operator*() const
|
||||||
|
{
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode* operator->() const
|
||||||
|
{
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
JsonNode* node;
|
||||||
|
};
|
||||||
|
|
@ -9,7 +9,7 @@ struct JsonNode;
|
|||||||
|
|
||||||
class JsonBuffer
|
class JsonBuffer
|
||||||
{
|
{
|
||||||
friend class JsonObject;
|
friend class JsonContainer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// virtual ~JsonBuffer() = 0;
|
// virtual ~JsonBuffer() = 0;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "JsonContainer.h"
|
#include "JsonContainer.h"
|
||||||
|
|
||||||
|
#include "JsonBuffer.h"
|
||||||
#include "Internals/JsonNodeSerializer.h"
|
#include "Internals/JsonNodeSerializer.h"
|
||||||
#include "Internals/StringBuilder.h"
|
#include "Internals/StringBuilder.h"
|
||||||
|
|
||||||
@ -13,4 +14,49 @@ size_t JsonContainer::printTo(Print& p) const
|
|||||||
{
|
{
|
||||||
JsonNodeSerializer serializer(p);
|
JsonNodeSerializer serializer(p);
|
||||||
return serializer.serialize(_node);
|
return serializer.serialize(_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JsonNode* JsonContainer::createNode(JsonNodeType type)
|
||||||
|
{
|
||||||
|
JsonBuffer* buffer = _node->content.asContainer.buffer;
|
||||||
|
return buffer->createNode(JSON_UNDEFINED);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JsonContainer::checkNodeType(JsonNodeType expectedType)
|
||||||
|
{
|
||||||
|
return _node && _node->type == expectedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JsonContainer::operator==(const JsonContainer & other) const
|
||||||
|
{
|
||||||
|
return _node == other._node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonContainer::insertChildAfter(JsonNode* newChild, JsonNode* previous)
|
||||||
|
{
|
||||||
|
if (previous)
|
||||||
|
previous->next = newChild;
|
||||||
|
else
|
||||||
|
_node->content.asContainer.child = newChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonContainer::removeChildAfter(JsonNode* child, JsonNode* previous)
|
||||||
|
{
|
||||||
|
if (previous)
|
||||||
|
previous->next = child->next;
|
||||||
|
else
|
||||||
|
_node->content.asContainer.child = child->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t JsonContainer::size() const
|
||||||
|
{
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
for (JsonNodeIterator it = beginChildren(); it != endChildren(); ++it)
|
||||||
|
{
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Arduino\Printable.h"
|
#include "Arduino/Printable.h"
|
||||||
|
#include "Internals/JsonNodeIterator.h"
|
||||||
|
#include "Internals/JsonNode.h"
|
||||||
|
|
||||||
struct JsonNode;
|
struct JsonNode;
|
||||||
|
class JsonValue;
|
||||||
|
|
||||||
class JsonContainer : public Printable
|
class JsonContainer : public Printable
|
||||||
{
|
{
|
||||||
|
friend JsonValue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JsonContainer()
|
JsonContainer()
|
||||||
: _node(0)
|
: _node(0)
|
||||||
@ -17,10 +22,32 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t size() const;
|
||||||
|
|
||||||
|
bool operator==(JsonContainer const& other) const;
|
||||||
|
|
||||||
size_t printTo(char* buffer, size_t bufferSize) const;
|
size_t printTo(char* buffer, size_t bufferSize) const;
|
||||||
virtual size_t printTo(Print& print) const;
|
virtual size_t printTo(Print& print) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
JsonNodeIterator beginChildren() const
|
||||||
|
{
|
||||||
|
return JsonNodeIterator(_node ? _node->content.asContainer.child : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNodeIterator endChildren() const
|
||||||
|
{
|
||||||
|
return JsonNodeIterator(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void insertChildAfter(JsonNode* newChild, JsonNode* insertAfterMe);
|
||||||
|
void removeChildAfter(JsonNode* child, JsonNode* previous);
|
||||||
|
JsonNode* createNode(JsonNodeType type);
|
||||||
|
|
||||||
|
bool checkNodeType(JsonNodeType expectedType);
|
||||||
|
|
||||||
|
private:
|
||||||
JsonNode* _node;
|
JsonNode* _node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,20 +11,6 @@
|
|||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
size_t JsonObject::size()
|
|
||||||
{
|
|
||||||
JsonNode* firstChild = _node->content.asContainer.child;
|
|
||||||
|
|
||||||
int size = 0;
|
|
||||||
|
|
||||||
for (JsonNode* child = firstChild; child; child = child->next)
|
|
||||||
{
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonValue JsonObject::operator[](char const* key)
|
JsonValue JsonObject::operator[](char const* key)
|
||||||
{
|
{
|
||||||
JsonNode* node = getOrCreateNodeAt(key);
|
JsonNode* node = getOrCreateNodeAt(key);
|
||||||
@ -33,61 +19,47 @@ JsonValue JsonObject::operator[](char const* key)
|
|||||||
|
|
||||||
void JsonObject::remove(char const* key)
|
void JsonObject::remove(char const* key)
|
||||||
{
|
{
|
||||||
JsonNode* firstChild = _node->content.asContainer.child;
|
|
||||||
JsonNode* lastChild = 0;
|
JsonNode* lastChild = 0;
|
||||||
|
|
||||||
for (JsonNode* child = firstChild; child; child = child->next)
|
for (JsonNodeIterator it = beginChildren(); it != endChildren(); ++it)
|
||||||
{
|
{
|
||||||
const char* childKey = child->content.asKey.key;
|
const char* childKey = it->content.asKey.key;
|
||||||
|
|
||||||
if (!strcmp(childKey, key))
|
if (!strcmp(childKey, key))
|
||||||
{
|
{
|
||||||
if (lastChild)
|
removeChildAfter(*it, lastChild);
|
||||||
lastChild->next = child->next;
|
}
|
||||||
else
|
|
||||||
_node->content.asContainer.child = child->next;
|
lastChild = *it;
|
||||||
}
|
|
||||||
lastChild = child;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JsonObject::operator==(JsonObject const& other) const
|
JsonNode* JsonObject::getOrCreateNodeAt(const char* key)
|
||||||
{
|
{
|
||||||
return _node == other._node;
|
if (!checkNodeType(JSON_OBJECT)) return 0;
|
||||||
}
|
|
||||||
|
|
||||||
JsonNode* JsonObject::getOrCreateNodeAt(char const* key)
|
|
||||||
{
|
|
||||||
if (!_node || _node->type != JSON_OBJECT) return 0;
|
|
||||||
|
|
||||||
JsonNode* firstChild = _node->content.asContainer.child;
|
|
||||||
JsonNode* lastChild = 0;
|
JsonNode* lastChild = 0;
|
||||||
|
|
||||||
for (JsonNode* child = firstChild; child; child = child->next)
|
for (JsonNodeIterator it = beginChildren(); it != endChildren(); ++it)
|
||||||
{
|
{
|
||||||
const char* childKey = child->content.asKey.key;
|
const char* childKey = it->content.asKey.key;
|
||||||
|
|
||||||
if (!strcmp(childKey, key))
|
if (!strcmp(childKey, key))
|
||||||
return child->content.asKey.value;
|
return it->content.asKey.value;
|
||||||
|
|
||||||
lastChild = child;
|
lastChild = *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonBuffer* buffer = _node->content.asContainer.buffer;
|
JsonNode* newValueNode = createNode(JSON_UNDEFINED);
|
||||||
|
|
||||||
JsonNode* newValueNode = buffer->createNode(JSON_UNDEFINED);
|
|
||||||
if (!newValueNode) return 0;
|
if (!newValueNode) return 0;
|
||||||
|
|
||||||
JsonNode* newKeyNode = buffer->createNode(JSON_KEY);
|
JsonNode* newKeyNode = createNode(JSON_KEY);
|
||||||
if (!newKeyNode) return 0;
|
if (!newKeyNode) return 0;
|
||||||
|
|
||||||
newKeyNode->content.asKey.key = key;
|
newKeyNode->content.asKey.key = key;
|
||||||
newKeyNode->content.asKey.value = newValueNode;
|
newKeyNode->content.asKey.value = newValueNode;
|
||||||
|
|
||||||
if (lastChild)
|
insertChildAfter(newKeyNode, lastChild);
|
||||||
lastChild->next = newKeyNode;
|
|
||||||
else
|
|
||||||
_node->content.asContainer.child = newKeyNode;
|
|
||||||
|
|
||||||
return newValueNode;
|
return newValueNode;
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,6 @@ struct JsonNode;
|
|||||||
|
|
||||||
class JsonObject : public JsonContainer
|
class JsonObject : public JsonContainer
|
||||||
{
|
{
|
||||||
friend JsonValue;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JsonObject()
|
JsonObject()
|
||||||
{
|
{
|
||||||
@ -19,13 +17,9 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size();
|
|
||||||
|
|
||||||
JsonValue operator[](const char* key);
|
JsonValue operator[](const char* key);
|
||||||
void remove(const char* key);
|
void remove(const char* key);
|
||||||
|
|
||||||
bool operator==(const JsonObject& other) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JsonNode* getOrCreateNodeAt(char const* key);
|
JsonNode* getOrCreateNodeAt(char const* key);
|
||||||
};
|
};
|
@ -79,6 +79,7 @@
|
|||||||
<ClInclude Include="Internals\JsonNode.h" />
|
<ClInclude Include="Internals\JsonNode.h" />
|
||||||
<ClInclude Include="Internals\JsonNodeSerializer.h" />
|
<ClInclude Include="Internals\JsonNodeSerializer.h" />
|
||||||
<ClInclude Include="JsonContainer.h" />
|
<ClInclude Include="JsonContainer.h" />
|
||||||
|
<ClInclude Include="Internals\JsonNodeIterator.h" />
|
||||||
<ClInclude Include="JsonObject.h" />
|
<ClInclude Include="JsonObject.h" />
|
||||||
<ClInclude Include="JsonValue.h" />
|
<ClInclude Include="JsonValue.h" />
|
||||||
<ClInclude Include="Arduino\Print.h" />
|
<ClInclude Include="Arduino\Print.h" />
|
||||||
|
@ -48,6 +48,9 @@
|
|||||||
<ClInclude Include="JsonContainer.h">
|
<ClInclude Include="JsonContainer.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Internals\JsonNodeIterator.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="JsonObject.cpp">
|
<ClCompile Include="JsonObject.cpp">
|
||||||
|
@ -14,6 +14,11 @@ protected:
|
|||||||
JsonObject object;
|
JsonObject object;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TEST_F(JsonObjectTests, InitialSizeIsZero)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(0, object.size());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(JsonObjectTests, Grow_WhenValuesAreAdded)
|
TEST_F(JsonObjectTests, Grow_WhenValuesAreAdded)
|
||||||
{
|
{
|
||||||
object["hello"];
|
object["hello"];
|
||||||
|
Reference in New Issue
Block a user