From 4d2d535a0377a350833deb4802cd6ee12d36c65e Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Wed, 1 Oct 2014 16:56:22 +0200 Subject: [PATCH] Pulled up code from JsonObject to JsonContainer --- srcs/Internals/JsonNodeIterator.h | 37 +++++++++++++++++++ srcs/JsonBuffer.h | 2 +- srcs/JsonContainer.cpp | 48 ++++++++++++++++++++++++- srcs/JsonContainer.h | 29 ++++++++++++++- srcs/JsonObject.cpp | 60 +++++++++---------------------- srcs/JsonObject.h | 6 ---- srcs/srcs.vcxproj | 1 + srcs/srcs.vcxproj.filters | 3 ++ tests/JsonObjectTests.cpp | 5 +++ 9 files changed, 138 insertions(+), 53 deletions(-) create mode 100644 srcs/Internals/JsonNodeIterator.h 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"];