diff --git a/srcs/Internals/JsonNodeIterator.h b/srcs/Internals/JsonNodeIterator.h
new file mode 100644
index 00000000..c9f6774a
--- /dev/null
+++ b/srcs/Internals/JsonNodeIterator.h
@@ -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;
+};
+
diff --git a/srcs/JsonBuffer.h b/srcs/JsonBuffer.h
index 893ed739..afe0735d 100644
--- a/srcs/JsonBuffer.h
+++ b/srcs/JsonBuffer.h
@@ -9,7 +9,7 @@ struct JsonNode;
class JsonBuffer
{
- friend class JsonObject;
+ friend class JsonContainer;
public:
// virtual ~JsonBuffer() = 0;
diff --git a/srcs/JsonContainer.cpp b/srcs/JsonContainer.cpp
index cb0f6a55..44c4e694 100644
--- a/srcs/JsonContainer.cpp
+++ b/srcs/JsonContainer.cpp
@@ -1,5 +1,6 @@
#include "JsonContainer.h"
+#include "JsonBuffer.h"
#include "Internals/JsonNodeSerializer.h"
#include "Internals/StringBuilder.h"
@@ -13,4 +14,49 @@ size_t JsonContainer::printTo(Print& p) const
{
JsonNodeSerializer serializer(p);
return serializer.serialize(_node);
-}
\ No newline at end of file
+}
+
+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;
+}
+
diff --git a/srcs/JsonContainer.h b/srcs/JsonContainer.h
index a31fc639..d6715d82 100644
--- a/srcs/JsonContainer.h
+++ b/srcs/JsonContainer.h
@@ -1,11 +1,16 @@
#pragma once
-#include "Arduino\Printable.h"
+#include "Arduino/Printable.h"
+#include "Internals/JsonNodeIterator.h"
+#include "Internals/JsonNode.h"
struct JsonNode;
+class JsonValue;
class JsonContainer : public Printable
{
+ friend JsonValue;
+
public:
JsonContainer()
: _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;
virtual size_t printTo(Print& print) const;
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;
};
diff --git a/srcs/JsonObject.cpp b/srcs/JsonObject.cpp
index 9d0ccb80..3a1ef1ed 100644
--- a/srcs/JsonObject.cpp
+++ b/srcs/JsonObject.cpp
@@ -11,20 +11,6 @@
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)
{
JsonNode* node = getOrCreateNodeAt(key);
@@ -33,61 +19,47 @@ JsonValue JsonObject::operator[](char const* key)
void JsonObject::remove(char const* key)
{
- JsonNode* firstChild = _node->content.asContainer.child;
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 (lastChild)
- lastChild->next = child->next;
- else
- _node->content.asContainer.child = child->next;
- }
- lastChild = child;
+ removeChildAfter(*it, lastChild);
+ }
+
+ lastChild = *it;
}
}
-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;
- 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))
- return child->content.asKey.value;
+ return it->content.asKey.value;
- lastChild = child;
+ lastChild = *it;
}
-
- JsonBuffer* buffer = _node->content.asContainer.buffer;
-
- JsonNode* newValueNode = buffer->createNode(JSON_UNDEFINED);
+
+ JsonNode* newValueNode = createNode(JSON_UNDEFINED);
if (!newValueNode) return 0;
- JsonNode* newKeyNode = buffer->createNode(JSON_KEY);
+ JsonNode* newKeyNode = createNode(JSON_KEY);
if (!newKeyNode) return 0;
newKeyNode->content.asKey.key = key;
newKeyNode->content.asKey.value = newValueNode;
- if (lastChild)
- lastChild->next = newKeyNode;
- else
- _node->content.asContainer.child = newKeyNode;
+ insertChildAfter(newKeyNode, lastChild);
return newValueNode;
}
diff --git a/srcs/JsonObject.h b/srcs/JsonObject.h
index db10aa75..73cb0551 100644
--- a/srcs/JsonObject.h
+++ b/srcs/JsonObject.h
@@ -7,8 +7,6 @@ struct JsonNode;
class JsonObject : public JsonContainer
{
- friend JsonValue;
-
public:
JsonObject()
{
@@ -19,13 +17,9 @@ public:
{
}
- size_t size();
-
JsonValue operator[](const char* key);
void remove(const char* key);
- bool operator==(const JsonObject& other) const;
-
private:
JsonNode* getOrCreateNodeAt(char const* key);
};
\ No newline at end of file
diff --git a/srcs/srcs.vcxproj b/srcs/srcs.vcxproj
index 7542e775..743911ec 100644
--- a/srcs/srcs.vcxproj
+++ b/srcs/srcs.vcxproj
@@ -79,6 +79,7 @@
+
diff --git a/srcs/srcs.vcxproj.filters b/srcs/srcs.vcxproj.filters
index a37c1acf..eaeed88a 100644
--- a/srcs/srcs.vcxproj.filters
+++ b/srcs/srcs.vcxproj.filters
@@ -48,6 +48,9 @@
Header Files
+
+ Header Files
+
diff --git a/tests/JsonObjectTests.cpp b/tests/JsonObjectTests.cpp
index cf7cbf6c..6338c035 100644
--- a/tests/JsonObjectTests.cpp
+++ b/tests/JsonObjectTests.cpp
@@ -14,6 +14,11 @@ protected:
JsonObject object;
};
+TEST_F(JsonObjectTests, InitialSizeIsZero)
+{
+ EXPECT_EQ(0, object.size());
+}
+
TEST_F(JsonObjectTests, Grow_WhenValuesAreAdded)
{
object["hello"];