From a2fc188526dccecfd950d5bf060a5277b1a0ec4a Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Sat, 27 Sep 2014 14:43:19 +0200 Subject: [PATCH] Test that adding the same value twice doesn't increase the size of the object --- srcs/JsonBuffer.cpp | 16 +++++++--- srcs/JsonBuffer.h | 9 +++--- srcs/JsonNode.h | 41 ++++++++++++++++++++++++ srcs/JsonObject.cpp | 55 +++++++++++++++++++++++++++++---- srcs/JsonObject.h | 19 ++++-------- srcs/StaticJsonBuffer.h | 9 +++--- srcs/srcs.vcxproj | 1 + srcs/srcs.vcxproj.filters | 3 ++ tests/JsonObjectTests.cpp | 13 ++++++++ tests/StaticJsonBufferTests.cpp | 12 +++++++ 10 files changed, 146 insertions(+), 32 deletions(-) create mode 100644 srcs/JsonNode.h diff --git a/srcs/JsonBuffer.cpp b/srcs/JsonBuffer.cpp index 54e4eb55..406f6db7 100644 --- a/srcs/JsonBuffer.cpp +++ b/srcs/JsonBuffer.cpp @@ -1,15 +1,21 @@ #include "JsonBuffer.h" -//#include "JsonNode.h" +#include "JsonNode.h" #include "JsonObject.h" +#include // for memset JsonObject JsonBuffer::createObject() { - allocateNode(); - return JsonObject(this); + JsonNode* node = createNode(JSON_OBJECT); + return JsonObject(this, node); } -void JsonBuffer::createNode() +JsonNode* JsonBuffer::createNode(JsonNodeType type) { - allocateNode(); + JsonNode* node = allocateNode(); + if (!node) return 0; + + memset(node, 0, sizeof(JsonNode)); + node->type = type; + return node; } \ No newline at end of file diff --git a/srcs/JsonBuffer.h b/srcs/JsonBuffer.h index f57b31fe..0d8d1009 100644 --- a/srcs/JsonBuffer.h +++ b/srcs/JsonBuffer.h @@ -1,6 +1,7 @@ #pragma once #include +#include "JsonNode.h" class JsonObject; struct JsonNode; @@ -13,10 +14,10 @@ public: // virtual ~JsonBuffer() = 0; JsonObject createObject(); - protected: - virtual /*JsonNode&*/void allocateNode() = 0; - - /*JsonNode&*/void createNode(); + virtual JsonNode* allocateNode() = 0; + +private: + JsonNode* createNode(JsonNodeType type); }; diff --git a/srcs/JsonNode.h b/srcs/JsonNode.h new file mode 100644 index 00000000..f8d585f9 --- /dev/null +++ b/srcs/JsonNode.h @@ -0,0 +1,41 @@ +#pragma once + +enum JsonNodeType +{ + JSON_UNDEFINED, + JSON_NULL, + JSON_ARRAY, + JSON_OBJECT, + JSON_KEY, + JSON_TRUE, + JSON_FALSE, + JSON_STRING, + JSON_INTEGER, + JSON_DOUBLE_0_DECIMALS, + JSON_DOUBLE_1_DECIMAL, + JSON_DOUBLE_2_DECIMALS, + // etc. +}; + +struct JsonNode +{ + JsonNode* next; + JsonNodeType type; + + union + { + // int asInteger; + + struct + { + const char* key; + JsonNode* value; + } asKey; + + struct + { + JsonNode* child; + } asObjectNode; + + } content; +}; \ No newline at end of file diff --git a/srcs/JsonObject.cpp b/srcs/JsonObject.cpp index 60279576..974adf21 100644 --- a/srcs/JsonObject.cpp +++ b/srcs/JsonObject.cpp @@ -1,8 +1,8 @@ #include "JsonBuffer.h" #include "JsonObject.h" #include "JsonValue.h" -//#include "JsonNode.h" - +#include "JsonNode.h" +#include //JsonValue& JsonObject::operator[](char const* key) //{ @@ -31,10 +31,53 @@ // _node.asObjectNode.child = &newChild; //} +size_t JsonObject::size() +{ + JsonNode* firstChild = _node->content.asObjectNode.child; + + int size = 0; + + for (JsonNode* child = firstChild; child; child = child->next) + { + size++; + } + + return size; +} + JsonValue JsonObject::operator[](char const* key) { - _buffer->createNode(); - _buffer->createNode(); - _size++; - return JsonValue(); + JsonNode* node = getOrCreateNodeAt(key); + return JsonValue(/*node*/); +} + +JsonNode* JsonObject::getOrCreateNodeAt(char const* key) +{ + if (!_node || _node->type != JSON_OBJECT) return 0; + + JsonNode* firstChild = _node->content.asObjectNode.child; + JsonNode* lastChild = 0; + + for (JsonNode* child = firstChild; child; child = child->next) + { + const char* childKey = child->content.asKey.key; + + if (!strcmp(childKey, key)) + return child->content.asKey.value; + + lastChild = child; + } + + JsonNode* newValueNode = _buffer->createNode(JSON_UNDEFINED); + + JsonNode* newKeyNode = _buffer->createNode(JSON_KEY); + newKeyNode->content.asKey.key = key; + newKeyNode->content.asKey.value = newValueNode; + + if (lastChild) + lastChild->next = newKeyNode; + else + _node->content.asObjectNode.child = newKeyNode; + + return newValueNode; } \ No newline at end of file diff --git a/srcs/JsonObject.h b/srcs/JsonObject.h index 02047ebd..e2c4b7d8 100644 --- a/srcs/JsonObject.h +++ b/srcs/JsonObject.h @@ -24,27 +24,20 @@ class JsonObject public: - JsonObject(JsonBuffer* buffer) - : _size(0), _buffer(buffer) + JsonObject(JsonBuffer* buffer, JsonNode* node) + : _buffer(buffer), _node(node) { } - int size() - { - return _size; - } + size_t size(); JsonValue operator[](const char* key); - private: - int _size; - JsonBuffer* _buffer; - //JsonNode* _node; - // - // void addNodeAt(char const* key, JsonNode& node); - // JsonNode& getNodeAt(const char* key); + JsonNode* _node; + JsonNode* getOrCreateNodeAt(char const* key); + // // // TODO: pull up // void appendChild(JsonNode& newChild); diff --git a/srcs/StaticJsonBuffer.h b/srcs/StaticJsonBuffer.h index acfaa98f..3769b211 100644 --- a/srcs/StaticJsonBuffer.h +++ b/srcs/StaticJsonBuffer.h @@ -28,13 +28,14 @@ public: } protected: - virtual /*JsonNode&*/void allocateNode() + virtual JsonNode* allocateNode() { - if (_size < CAPACITY) - _size++; + if (_size >= CAPACITY) return 0; + + return &_buffer[_size++]; } private: - //JsonNode _buffer[CAPACITY]; + JsonNode _buffer[CAPACITY]; int _size; }; \ No newline at end of file diff --git a/srcs/srcs.vcxproj b/srcs/srcs.vcxproj index 8994ad7b..b679eaad 100644 --- a/srcs/srcs.vcxproj +++ b/srcs/srcs.vcxproj @@ -66,6 +66,7 @@ + diff --git a/srcs/srcs.vcxproj.filters b/srcs/srcs.vcxproj.filters index ecf23303..b13d846d 100644 --- a/srcs/srcs.vcxproj.filters +++ b/srcs/srcs.vcxproj.filters @@ -27,6 +27,9 @@ Header Files + + Header Files + diff --git a/tests/JsonObjectTests.cpp b/tests/JsonObjectTests.cpp index d0c2c84f..45175fdf 100644 --- a/tests/JsonObjectTests.cpp +++ b/tests/JsonObjectTests.cpp @@ -13,4 +13,17 @@ TEST(JsonObjectTests, WhenValueIsAdded_ThenSizeIsIncreasedByOne) object["world"]; EXPECT_EQ(2, object.size()); +} + +TEST(JsonObjectTests, WhenTheSameValueIsAddedTwice_ThenSizeIsOnlyIncreasedByOne) +{ + StaticJsonBuffer<42> json; + + JsonObject object = json.createObject(); + + object["hello"]; + EXPECT_EQ(1, object.size()); + + object["hello"]; + EXPECT_EQ(1, object.size()); } \ No newline at end of file diff --git a/tests/StaticJsonBufferTests.cpp b/tests/StaticJsonBufferTests.cpp index 157e8c87..55081099 100644 --- a/tests/StaticJsonBufferTests.cpp +++ b/tests/StaticJsonBufferTests.cpp @@ -54,4 +54,16 @@ TEST(StaticJsonBuffer, GivenAJsonObject_WhenValuesAreAdded_ThenSizeIsIncreasedBy obj["world"]; EXPECT_EQ(5, json.size()); +} + +TEST(StaticJsonBuffer, GivenAJsonObject_WhenSameValuesAreAddedTwice_ThenSizeIsOnlyIncreasedByTwo) +{ + StaticJsonBuffer<42> json; + JsonObject obj = json.createObject(); + + obj["hello"]; + EXPECT_EQ(3, json.size()); + + obj["hello"]; + EXPECT_EQ(3, json.size()); } \ No newline at end of file