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

This commit is contained in:
Benoit Blanchon
2014-09-27 14:43:19 +02:00
parent 166bdd6919
commit a2fc188526
10 changed files with 146 additions and 32 deletions

View File

@ -1,15 +1,21 @@
#include "JsonBuffer.h" #include "JsonBuffer.h"
//#include "JsonNode.h" #include "JsonNode.h"
#include "JsonObject.h" #include "JsonObject.h"
#include <string.h> // for memset
JsonObject JsonBuffer::createObject() JsonObject JsonBuffer::createObject()
{ {
allocateNode(); JsonNode* node = createNode(JSON_OBJECT);
return JsonObject(this); 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;
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <stddef.h> #include <stddef.h>
#include "JsonNode.h"
class JsonObject; class JsonObject;
struct JsonNode; struct JsonNode;
@ -13,10 +14,10 @@ public:
// virtual ~JsonBuffer() = 0; // virtual ~JsonBuffer() = 0;
JsonObject createObject(); JsonObject createObject();
protected: protected:
virtual /*JsonNode&*/void allocateNode() = 0; virtual JsonNode* allocateNode() = 0;
/*JsonNode&*/void createNode(); private:
JsonNode* createNode(JsonNodeType type);
}; };

41
srcs/JsonNode.h Normal file
View File

@ -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;
};

View File

@ -1,8 +1,8 @@
#include "JsonBuffer.h" #include "JsonBuffer.h"
#include "JsonObject.h" #include "JsonObject.h"
#include "JsonValue.h" #include "JsonValue.h"
//#include "JsonNode.h" #include "JsonNode.h"
#include <string.h>
//JsonValue& JsonObject::operator[](char const* key) //JsonValue& JsonObject::operator[](char const* key)
//{ //{
@ -31,10 +31,53 @@
// _node.asObjectNode.child = &newChild; // _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) JsonValue JsonObject::operator[](char const* key)
{ {
_buffer->createNode(); JsonNode* node = getOrCreateNodeAt(key);
_buffer->createNode(); return JsonValue(/*node*/);
_size++; }
return JsonValue();
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;
} }

View File

@ -24,27 +24,20 @@ class JsonObject
public: public:
JsonObject(JsonBuffer* buffer) JsonObject(JsonBuffer* buffer, JsonNode* node)
: _size(0), _buffer(buffer) : _buffer(buffer), _node(node)
{ {
} }
int size() size_t size();
{
return _size;
}
JsonValue operator[](const char* key); JsonValue operator[](const char* key);
private: private:
int _size;
JsonBuffer* _buffer; JsonBuffer* _buffer;
//JsonNode* _node; JsonNode* _node;
// JsonNode* getOrCreateNodeAt(char const* key);
// void addNodeAt(char const* key, JsonNode& node);
// JsonNode& getNodeAt(const char* key);
// //
// // TODO: pull up // // TODO: pull up
// void appendChild(JsonNode& newChild); // void appendChild(JsonNode& newChild);

View File

@ -28,13 +28,14 @@ public:
} }
protected: protected:
virtual /*JsonNode&*/void allocateNode() virtual JsonNode* allocateNode()
{ {
if (_size < CAPACITY) if (_size >= CAPACITY) return 0;
_size++;
return &_buffer[_size++];
} }
private: private:
//JsonNode _buffer[CAPACITY]; JsonNode _buffer[CAPACITY];
int _size; int _size;
}; };

View File

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

View File

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

View File

@ -13,4 +13,17 @@ TEST(JsonObjectTests, WhenValueIsAdded_ThenSizeIsIncreasedByOne)
object["world"]; object["world"];
EXPECT_EQ(2, object.size()); 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());
} }

View File

@ -54,4 +54,16 @@ TEST(StaticJsonBuffer, GivenAJsonObject_WhenValuesAreAdded_ThenSizeIsIncreasedBy
obj["world"]; obj["world"];
EXPECT_EQ(5, json.size()); 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());
} }