Просмотр исходного кода

Test that adding the same value twice doesn't increase the size of the object

Benoit Blanchon 11 лет назад
Родитель
Сommit
a2fc188526

+ 11 - 5
srcs/JsonBuffer.cpp

@@ -1,15 +1,21 @@
 #include "JsonBuffer.h"
-//#include "JsonNode.h"
+#include "JsonNode.h"
 #include "JsonObject.h"
+#include <string.h> // 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;
 }

+ 5 - 4
srcs/JsonBuffer.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include <stddef.h>
+#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);
 };
 

+ 41 - 0
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;
+};

+ 49 - 6
srcs/JsonObject.cpp

@@ -1,8 +1,8 @@
 #include "JsonBuffer.h"
 #include "JsonObject.h"
 #include "JsonValue.h"
-//#include "JsonNode.h"
-
+#include "JsonNode.h"
+#include <string.h>
 
 //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;
 }

+ 6 - 13
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);

+ 5 - 4
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;
 };

+ 1 - 0
srcs/srcs.vcxproj

@@ -66,6 +66,7 @@
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClInclude Include="JsonBuffer.h" />
+    <ClInclude Include="JsonNode.h" />
     <ClInclude Include="JsonObject.h" />
     <ClInclude Include="JsonValue.h" />
     <ClInclude Include="StaticJsonBuffer.h" />

+ 3 - 0
srcs/srcs.vcxproj.filters

@@ -27,6 +27,9 @@
     <ClInclude Include="JsonBuffer.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="JsonNode.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="JsonObject.cpp">

+ 13 - 0
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());
 }

+ 12 - 0
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());
 }