diff --git a/srcs/Internals/JsonNode.cpp b/srcs/Internals/JsonNode.cpp index 95dbfa91..8e08be31 100644 --- a/srcs/Internals/JsonNode.cpp +++ b/srcs/Internals/JsonNode.cpp @@ -3,11 +3,16 @@ #include "JsonWriter.h" #include "../JsonArray.h" #include "../JsonObject.h" +#include "../JsonBuffer.h" void JsonNode::writeTo(JsonWriter& writer) { switch (type) { + case JSON_PROXY: + content.asProxy.target->writeTo(writer); + break; + case JSON_ARRAY: writeArrayTo(writer); break; @@ -36,7 +41,11 @@ void JsonNode::writeTo(JsonWriter& writer) void JsonNode::addChild(JsonNode* childToAdd) { - if (type != JSON_ARRAY && type != JSON_OBJECT) return; + if (type == JSON_PROXY) + return content.asProxy.target->addChild(childToAdd); + + if (type != JSON_ARRAY && type != JSON_OBJECT) + return; JsonNode* lastChild = content.asContainer.child; @@ -54,6 +63,9 @@ void JsonNode::addChild(JsonNode* childToAdd) void JsonNode::removeChild(JsonNode* childToRemove) { + if (type == JSON_PROXY) + return content.asProxy.target->removeChild(childToRemove); + if (type != JSON_ARRAY && type != JSON_OBJECT) return; if (content.asContainer.child == childToRemove) @@ -121,4 +133,17 @@ void JsonNode::writeObjectTo(JsonWriter& writer) { writer.writeEmptyObject(); } +} + +void JsonNode::setAsProxyOfSelf() +{ + JsonBuffer* buffer = content.asContainer.buffer; + if (!buffer) return; + + JsonNode* newNode = buffer->createNode(); + if (!newNode) return; + + *newNode = *this; + + setAsProxyOf(newNode); } \ No newline at end of file diff --git a/srcs/Internals/JsonNode.h b/srcs/Internals/JsonNode.h index bccfad63..0751851e 100644 --- a/srcs/Internals/JsonNode.h +++ b/srcs/Internals/JsonNode.h @@ -18,6 +18,7 @@ class JsonNode JSON_BOOLEAN, JSON_STRING, JSON_LONG, + JSON_PROXY, JSON_DOUBLE_0_DECIMALS, JSON_DOUBLE_1_DECIMAL, JSON_DOUBLE_2_DECIMALS, @@ -126,11 +127,13 @@ public: JsonBuffer* getContainerBuffer() { + if (type == JSON_PROXY) return content.asProxy.target->getContainerBuffer(); return type == JSON_ARRAY || type == JSON_OBJECT ? content.asContainer.buffer : 0; } JsonNode* getContainerChild() { + if (type == JSON_PROXY) return content.asProxy.target->getContainerChild(); return type == JSON_ARRAY || type == JSON_OBJECT ? content.asContainer.child : 0; } @@ -148,6 +151,23 @@ public: void removeChild(JsonNode* childToRemove); + void duplicate(JsonNode* other) + { + if (!other) + { + type = JSON_UNDEFINED; + } + else if (other->type == JSON_ARRAY || other->type==JSON_OBJECT) + { + other->setAsProxyOfSelf(); + setAsProxyOf(other->content.asProxy.target); + } + else + { + *this = *other; + } + } + private: JsonNode* next; JsonNodeContent content; @@ -155,4 +175,12 @@ private: inline void writeArrayTo(JsonWriter&);// TODO: <- move in JsonNodeSerializer inline void writeObjectTo(JsonWriter&);// TODO: <- move in JsonNodeSerializer + + void setAsProxyOfSelf(); + + void setAsProxyOf(JsonNode* target) + { + type = JSON_PROXY; + content.asProxy.target = target; + } }; \ No newline at end of file diff --git a/srcs/Internals/JsonNodeWrapper.h b/srcs/Internals/JsonNodeWrapper.h new file mode 100644 index 00000000..522e0735 --- /dev/null +++ b/srcs/Internals/JsonNodeWrapper.h @@ -0,0 +1,37 @@ +#pragma once + +#include "JsonNode.h" +class JsonValue; + +class JsonNodeWrapper +{ + friend JsonValue; + +public: + JsonNodeWrapper() + : _node(0) + { + } + + explicit JsonNodeWrapper(JsonNode* node) + : _node(node) + { + } + +protected: + + void duplicate(const JsonNodeWrapper& other) + { + if (!_node) + { + _node = other._node; + } + else + { + _node->duplicate(other._node); + } + } + + JsonNode* _node; +}; + diff --git a/srcs/JsonArray.cpp b/srcs/JsonArray.cpp index 4ddf1d51..57a94f14 100644 --- a/srcs/JsonArray.cpp +++ b/srcs/JsonArray.cpp @@ -50,6 +50,7 @@ void JsonArray::add(long value) addChild(node); } +// TODO: we should have the same issue as in JsonValue void JsonArray::add(JsonContainer nestedContainer) { JsonNode* node = createNode(); diff --git a/srcs/JsonBuffer.h b/srcs/JsonBuffer.h index e4b3c416..5b378225 100644 --- a/srcs/JsonBuffer.h +++ b/srcs/JsonBuffer.h @@ -6,6 +6,7 @@ class JsonBuffer { friend class JsonContainer; + friend class JsonNode; public: virtual ~JsonBuffer() {}; diff --git a/srcs/JsonContainer.h b/srcs/JsonContainer.h index ce5da173..028be531 100644 --- a/srcs/JsonContainer.h +++ b/srcs/JsonContainer.h @@ -4,24 +4,23 @@ #include "Internals/JsonNodeIterator.h" #include "Internals/JsonNode.h" #include "Internals/IndentedPrint.h" - +#include "Internals/JsonNodeWrapper.h" class JsonArray; class JsonObject; class JsonValue; -class JsonContainer : public Printable +class JsonContainer : public Printable, public JsonNodeWrapper { - friend JsonValue; + // friend JsonValue; friend JsonArray; public: - JsonContainer() - : _node(0) - { - } - JsonContainer(JsonNode* node) - : _node(node) + + JsonContainer() {} + + explicit JsonContainer(JsonNode* node) + : JsonNodeWrapper(node) { } @@ -54,7 +53,5 @@ protected: void addChild(JsonNode*); void removeChild(JsonNode*); JsonNode* createNode(); - - JsonNode* _node; }; diff --git a/srcs/JsonValue.cpp b/srcs/JsonValue.cpp index fd784b96..61093fac 100644 --- a/srcs/JsonValue.cpp +++ b/srcs/JsonValue.cpp @@ -28,32 +28,6 @@ void JsonValue::operator=(int value) _node->setAsLong(value); } -// TODO: it's a duplicate -void JsonValue::operator=(const JsonContainer& object) -{ - if (!_node) - { - _node = object._node; - } - else - { - *_node = *object._node; - } -} - -// TODO: it's a duplicate -void JsonValue::operator=(JsonValue const& value) -{ - if (!_node) - { - _node = value._node; - } - else - { - *_node = *value._node; - } -} - JsonValue::operator bool() const { return _node ? _node->getAsBoolean() : false; diff --git a/srcs/JsonValue.h b/srcs/JsonValue.h index 9a98be6f..9ad98acd 100644 --- a/srcs/JsonValue.h +++ b/srcs/JsonValue.h @@ -1,21 +1,19 @@ #pragma once +#include "Internals/JsonNodeWrapper.h" + class JsonArray; class JsonContainer; class JsonObject; -class JsonNode; -class JsonValue +class JsonValue : public JsonNodeWrapper { public: - - explicit JsonValue() - : _node(0) - { - } + + JsonValue() {} explicit JsonValue(JsonNode* node) - : _node(node) + : JsonNodeWrapper(node) { } @@ -23,9 +21,9 @@ public: void operator=(const char*); void operator=(double x) { set(x, 2); } void operator=(int); - void operator=(const JsonContainer&); - void operator=(const JsonValue&); - + void operator=(const JsonValue& value) { duplicate(value); } + void operator=(const JsonNodeWrapper& object) { duplicate(object); } + operator bool() const; operator const char*() const; operator double() const; @@ -35,7 +33,4 @@ public: operator JsonObject() const; void set(double value, int decimals); - -private: - JsonNode* _node; }; \ No newline at end of file diff --git a/srcs/srcs.vcxproj b/srcs/srcs.vcxproj index 44dc01ff..2b1866cb 100644 --- a/srcs/srcs.vcxproj +++ b/srcs/srcs.vcxproj @@ -83,6 +83,7 @@ + diff --git a/srcs/srcs.vcxproj.filters b/srcs/srcs.vcxproj.filters index f0fff5aa..fe5a5d1f 100644 --- a/srcs/srcs.vcxproj.filters +++ b/srcs/srcs.vcxproj.filters @@ -63,6 +63,9 @@ Header Files + + Header Files + diff --git a/tests/JsonObject_Serialization_Tests.cpp b/tests/JsonObject_Serialization_Tests.cpp index d0804514..fa900cd2 100644 --- a/tests/JsonObject_Serialization_Tests.cpp +++ b/tests/JsonObject_Serialization_Tests.cpp @@ -123,21 +123,35 @@ TEST_F(JsonObject_Serialization_Tests, OneFalse) object["key"] = false; outputMustBe("{\"key\":false}"); } -/* -TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedArray) + +TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedArrayViaProxy) { - auto nestedArray = JsonArray<1>(); + auto nestedArray = json.createArray(); object["key"] = nestedArray; outputMustBe("{\"key\":[]}"); } -*/ -TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedObject) -{ - auto nestedObject = json.createObject(); - object["key"] = nestedObject; +TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedObjectViaProxy) +{ + auto nestedArray = json.createObject(); + + object["key"] = nestedArray; outputMustBe("{\"key\":{}}"); +} + +TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedObject) +{ + object.createNestedObject("key"); + + outputMustBe("{\"key\":{}}"); +} + +TEST_F(JsonObject_Serialization_Tests, OneEmptyNestedArray) +{ + object.createNestedArray("key"); + + outputMustBe("{\"key\":[]}"); } \ No newline at end of file diff --git a/tests/JsonValueTests.cpp b/tests/JsonValueTests.cpp index baa4ab14..c9a3a98f 100644 --- a/tests/JsonValueTests.cpp +++ b/tests/JsonValueTests.cpp @@ -101,12 +101,10 @@ TEST_F(JsonValueTests, ObjectsAreCopiedByReference) JsonObject object = json.createObject(); jsonValue1 = object; - jsonValue2 = jsonValue1; object["hello"] = "world"; - jsonValue1 = 0; - EXPECT_EQ(1, ((JsonObject) jsonValue2).size()); + EXPECT_EQ(1, ((JsonObject) jsonValue1).size()); } TEST_F(JsonValueTests, ArraysAreCopiedByReference) @@ -114,10 +112,8 @@ TEST_F(JsonValueTests, ArraysAreCopiedByReference) JsonArray array = json.createArray(); jsonValue1 = array; - jsonValue2 = jsonValue1; - jsonValue1 = 0; array.add("world"); - EXPECT_EQ(1, ((JsonObject) jsonValue2).size()); + EXPECT_EQ(1, ((JsonObject) jsonValue1).size()); } \ No newline at end of file