diff --git a/CHANGELOG.md b/CHANGELOG.md index 8341c236..18bfa5a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ArduinoJson: change log HEAD ---- -* Add `JsonVariant::link()` (issue #1343) +* Add `JsonVariant::shallowCopy()` (issue #1343) * Fix `9.22337e+18 is outside the range of representable values of type 'long'` * Fix comparison operators for `JsonArray`, `JsonArrayConst`, `JsonObject`, and `JsonObjectConst` * Remove undocumented `accept()` functions diff --git a/extras/tests/Cpp11/nullptr.cpp b/extras/tests/Cpp11/nullptr.cpp index ae0eb634..813b9cc2 100644 --- a/extras/tests/Cpp11/nullptr.cpp +++ b/extras/tests/Cpp11/nullptr.cpp @@ -43,13 +43,5 @@ TEST_CASE("nullptr") { variant.clear(); REQUIRE(variant.is() == true); - - StaticJsonDocument<128> doc2; - doc2["hello"] = "world"; - variant.link(doc2); - REQUIRE(variant.is() == false); - - doc2.clear(); - REQUIRE(variant.is() == true); } } diff --git a/extras/tests/JsonDocument/ElementProxy.cpp b/extras/tests/JsonDocument/ElementProxy.cpp index e54560c1..3596dadc 100644 --- a/extras/tests/JsonDocument/ElementProxy.cpp +++ b/extras/tests/JsonDocument/ElementProxy.cpp @@ -246,10 +246,10 @@ TEST_CASE("ElementProxy cast to JsonVariant") { CHECK(doc.as() == "[\"toto\"]"); } -TEST_CASE("ElementProxy::link()") { +TEST_CASE("ElementProxy::shallowCopy()") { StaticJsonDocument<1024> doc1, doc2; - doc1[0].link(doc2); doc2["hello"] = "world"; + doc1[0].shallowCopy(doc2); CHECK(doc1.as() == "[{\"hello\":\"world\"}]"); } diff --git a/extras/tests/JsonDocument/MemberProxy.cpp b/extras/tests/JsonDocument/MemberProxy.cpp index a4de1257..b9e2b749 100644 --- a/extras/tests/JsonDocument/MemberProxy.cpp +++ b/extras/tests/JsonDocument/MemberProxy.cpp @@ -318,10 +318,10 @@ TEST_CASE("MemberProxy::createNestedObject(key)") { CHECK(doc["status"]["weather"]["temp"] == 42); } -TEST_CASE("MemberProxy::link()") { +TEST_CASE("MemberProxy::shallowCopy()") { StaticJsonDocument<1024> doc1, doc2; - doc1["obj"].link(doc2); doc2["hello"] = "world"; + doc1["obj"].shallowCopy(doc2); CHECK(doc1.as() == "{\"obj\":{\"hello\":\"world\"}}"); } diff --git a/extras/tests/JsonDocument/size.cpp b/extras/tests/JsonDocument/size.cpp index 683cc733..4fbb6e23 100644 --- a/extras/tests/JsonDocument/size.cpp +++ b/extras/tests/JsonDocument/size.cpp @@ -25,21 +25,4 @@ TEST_CASE("JsonDocument::size()") { REQUIRE(doc.size() == 2); } - - SECTION("linked array") { - StaticJsonDocument<128> doc2; - doc2.add(1); - doc2.add(2); - doc.as().link(doc2); - - REQUIRE(doc.size() == 2); - } - - SECTION("linked object") { - StaticJsonDocument<128> doc2; - doc2["hello"] = "world"; - doc.as().link(doc2); - - REQUIRE(doc.size() == 1); - } } diff --git a/extras/tests/JsonVariant/CMakeLists.txt b/extras/tests/JsonVariant/CMakeLists.txt index 35cf3818..1a0d14a9 100644 --- a/extras/tests/JsonVariant/CMakeLists.txt +++ b/extras/tests/JsonVariant/CMakeLists.txt @@ -13,7 +13,6 @@ add_executable(JsonVariantTests createNested.cpp is.cpp isnull.cpp - link.cpp memoryUsage.cpp misc.cpp nesting.cpp @@ -21,6 +20,7 @@ add_executable(JsonVariantTests overflow.cpp remove.cpp set.cpp + shallowCopy.cpp size.cpp subscript.cpp types.cpp diff --git a/extras/tests/JsonVariant/add.cpp b/extras/tests/JsonVariant/add.cpp index fec99c5a..526e914d 100644 --- a/extras/tests/JsonVariant/add.cpp +++ b/extras/tests/JsonVariant/add.cpp @@ -43,14 +43,4 @@ TEST_CASE("JsonVariant::add()") { REQUIRE(var.as() == "{\"val\":123}"); } - - SECTION("add to linked array") { - StaticJsonDocument<1024> doc2; - doc2.add(42); - var.link(doc2); - - var.add(666); // no-op - - CHECK(var.as() == "[42]"); - } } diff --git a/extras/tests/JsonVariant/as.cpp b/extras/tests/JsonVariant/as.cpp index 43c30185..c9956778 100644 --- a/extras/tests/JsonVariant/as.cpp +++ b/extras/tests/JsonVariant/as.cpp @@ -267,97 +267,4 @@ TEST_CASE("JsonVariant::as()") { REQUIRE(variant.as() == ONE); } - - SECTION("linked object") { - StaticJsonDocument<128> doc2; - doc2["hello"] = "world"; - variant.link(doc2); - - SECTION("as()") { - CHECK(variant.as() == "{\"hello\":\"world\"}"); - } - - SECTION("as()") { - JsonArray a = variant.as(); - CHECK(a.isNull() == true); - } - - SECTION("as()") { - JsonObject o = variant.as(); - CHECK(o.isNull() == true); - } - - SECTION("as()") { - JsonObjectConst o = variant.as(); - CHECK(o.isNull() == false); - CHECK(o.size() == 1); - CHECK(o["hello"] == "world"); - } - } - - SECTION("linked array") { - StaticJsonDocument<128> doc2; - doc2.add("hello"); - doc2.add("world"); - variant.link(doc2); - - SECTION("as()") { - CHECK(variant.as() == "[\"hello\",\"world\"]"); - } - - SECTION("as()") { - JsonArray a = variant.as(); - CHECK(a.isNull() == true); - } - - SECTION("as()") { - JsonArrayConst a = variant.as(); - CHECK(a.isNull() == false); - CHECK(a.size() == 2); - CHECK(a[0] == "hello"); - CHECK(a[1] == "world"); - } - - SECTION("as()") { - JsonObject o = variant.as(); - CHECK(o.isNull() == true); - } - } - - SECTION("linked int") { - StaticJsonDocument<128> doc2; - doc2.set(42); - variant.link(doc2); - - CHECK(variant.as() == 42); - CHECK(variant.as() == 42.0); - } - - SECTION("linked double") { - StaticJsonDocument<128> doc2; - doc2.set(42.0); - variant.link(doc2); - - CHECK(variant.as() == 42); - CHECK(variant.as() == 42.0); - } - - SECTION("linked string") { - StaticJsonDocument<128> doc2; - doc2.set("hello"); - variant.link(doc2); - - CHECK(variant.as() == "hello"); - } - - SECTION("linked bool") { - StaticJsonDocument<128> doc2; - variant.link(doc2); - - doc2.set(true); - CHECK(variant.as() == true); - - doc2.set(false); - CHECK(variant.as() == false); - } } diff --git a/extras/tests/JsonVariant/clear.cpp b/extras/tests/JsonVariant/clear.cpp index 173a7dea..2b40e324 100644 --- a/extras/tests/JsonVariant/clear.cpp +++ b/extras/tests/JsonVariant/clear.cpp @@ -23,15 +23,4 @@ TEST_CASE("JsonVariant::clear()") { REQUIRE(var.isNull() == true); } - - SECTION("doesn't alter linked object") { - StaticJsonDocument<128> doc2; - doc2["hello"] = "world"; - var.link(doc2); - - var.clear(); - - CHECK(var.isNull() == true); - CHECK(doc2.as() == "{\"hello\":\"world\"}"); - } } diff --git a/extras/tests/JsonVariant/compare.cpp b/extras/tests/JsonVariant/compare.cpp index c6211a55..63adbc26 100644 --- a/extras/tests/JsonVariant/compare.cpp +++ b/extras/tests/JsonVariant/compare.cpp @@ -34,20 +34,6 @@ TEST_CASE("Compare JsonVariant with value") { CHECK_FALSE(a < b); CHECK_FALSE(a > b); } - - SECTION("linked 42 vs 42") { - StaticJsonDocument<128> doc2; - doc2.set(42); - a.link(doc2); - int b = 42; - - CHECK(a == b); - CHECK(a <= b); - CHECK(a >= b); - CHECK_FALSE(a != b); - CHECK_FALSE(a < b); - CHECK_FALSE(a > b); - } } TEST_CASE("Compare JsonVariant with JsonVariant") { @@ -327,19 +313,4 @@ TEST_CASE("Compare JsonVariant with JsonVariant") { CHECK_FALSE(a > b); CHECK_FALSE(a >= b); } - - SECTION("linked 42 vs link 42") { - StaticJsonDocument<128> doc2, doc3; - doc2.set(42); - doc3.set(42); - a.link(doc2); - b.link(doc3); - - CHECK(a == b); - CHECK(a <= b); - CHECK(a >= b); - CHECK_FALSE(a != b); - CHECK_FALSE(a < b); - CHECK_FALSE(a > b); - } } diff --git a/extras/tests/JsonVariant/containsKey.cpp b/extras/tests/JsonVariant/containsKey.cpp index 739e33ec..fca684ee 100644 --- a/extras/tests/JsonVariant/containsKey.cpp +++ b/extras/tests/JsonVariant/containsKey.cpp @@ -25,15 +25,6 @@ TEST_CASE("JsonVariant::containsKey()") { REQUIRE(var.containsKey(std::string("hello")) == true); REQUIRE(var.containsKey(std::string("world")) == false); } - - SECTION("linked object") { - StaticJsonDocument<128> doc2; - doc2["hello"] = "world"; - var.link(doc2); - - CHECK(var.containsKey("hello") == true); - CHECK(var.containsKey("world") == false); - } } TEST_CASE("JsonVariantConst::containsKey()") { diff --git a/extras/tests/JsonVariant/copy.cpp b/extras/tests/JsonVariant/copy.cpp index b8f96297..7784f0ca 100644 --- a/extras/tests/JsonVariant/copy.cpp +++ b/extras/tests/JsonVariant/copy.cpp @@ -84,16 +84,6 @@ TEST_CASE("JsonVariant::set(JsonVariant)") { REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7)); } - SECTION("stores linked object by pointer") { - StaticJsonDocument<128> doc3; - doc3["hello"] = "world"; - var1.link(doc3); - var2.set(var1); - - REQUIRE(doc1.memoryUsage() == 0); - REQUIRE(doc2.memoryUsage() == 0); - } - SECTION("destination is unbound") { JsonVariant unboundVariant; diff --git a/extras/tests/JsonVariant/createNested.cpp b/extras/tests/JsonVariant/createNested.cpp index 0636762e..efd75015 100644 --- a/extras/tests/JsonVariant/createNested.cpp +++ b/extras/tests/JsonVariant/createNested.cpp @@ -18,17 +18,6 @@ TEST_CASE("JsonVariant::createNestedObject()") { REQUIRE(variant[0]["value"] == 42); REQUIRE(obj.isNull() == false); } - - SECTION("does nothing on linked array") { - StaticJsonDocument<128> doc2; - doc2[0] = 42; - variant.link(doc2); - - variant.createNestedObject(); - - CHECK(variant.size() == 1); - CHECK(variant[0] == 42); - } } TEST_CASE("JsonVariant::createNestedArray()") { @@ -41,17 +30,6 @@ TEST_CASE("JsonVariant::createNestedArray()") { REQUIRE(variant.is() == true); REQUIRE(arr.isNull() == false); } - - SECTION("does nothing on linked array") { - StaticJsonDocument<128> doc2; - doc2[0] = 42; - variant.link(doc2); - - variant.createNestedArray(); - - CHECK(variant.size() == 1); - CHECK(variant[0] == 42); - } } TEST_CASE("JsonVariant::createNestedObject(key)") { @@ -65,17 +43,6 @@ TEST_CASE("JsonVariant::createNestedObject(key)") { REQUIRE(variant.is() == true); REQUIRE(variant["weather"]["temp"] == 42); } - - SECTION("does nothing on linked object") { - StaticJsonDocument<128> doc2; - doc2["hello"] = "world"; - variant.link(doc2); - - variant.createNestedObject("weather"); - - CHECK(variant.size() == 1); - CHECK(variant["hello"] == "world"); - } } TEST_CASE("JsonVariant::createNestedArray(key)") { @@ -88,15 +55,4 @@ TEST_CASE("JsonVariant::createNestedArray(key)") { REQUIRE(variant.is() == true); REQUIRE(arr.isNull() == false); } - - SECTION("does nothing on linked object") { - StaticJsonDocument<128> doc2; - doc2["hello"] = "world"; - variant.link(doc2); - - variant.createNestedArray("items"); - - CHECK(variant.size() == 1); - CHECK(variant["hello"] == "world"); - } } diff --git a/extras/tests/JsonVariant/is.cpp b/extras/tests/JsonVariant/is.cpp index 0cc63e3d..6d04f0af 100644 --- a/extras/tests/JsonVariant/is.cpp +++ b/extras/tests/JsonVariant/is.cpp @@ -144,24 +144,6 @@ TEST_CASE("JsonVariant::is()") { CHECK(variant.is() == false); } - SECTION("linked array") { - StaticJsonDocument<1024> doc2; - doc2[0] = "world"; - variant.link(doc2); - - CHECK(variant.is() == false); - CHECK(variant.is() == true); - CHECK(variant.is() == true); - CHECK(variant.is() == true); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - } - SECTION("JsonObject") { variant.to(); @@ -179,44 +161,6 @@ TEST_CASE("JsonVariant::is()") { CHECK(variant.is() == true); CHECK(variant.is() == true); } - - SECTION("linked object") { - StaticJsonDocument<1024> doc2; - doc2["hello"] = "world"; - variant.link(doc2); - - CHECK(variant.is() == false); - CHECK(variant.is() == true); - CHECK(variant.is() == true); - CHECK(variant.is() == true); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - CHECK(variant.is() == true); - CHECK(variant.is() == true); - } - - SECTION("linked int") { - StaticJsonDocument<1024> doc2; - doc2.set(42); - variant.link(doc2); - - CHECK(variant.is() == false); - CHECK(variant.is() == true); - CHECK(variant.is() == false); - CHECK(variant.is() == true); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - CHECK(variant.is() == true); - CHECK(variant.is() == true); - CHECK(variant.is() == false); - CHECK(variant.is() == false); - CHECK(variant.is() == true); - } } TEST_CASE("JsonVariantConst::is()") { @@ -372,58 +316,4 @@ TEST_CASE("JsonVariantConst::is()") { CHECK(cvariant.is() == false); CHECK(cvariant.is() == false); } - - SECTION("linked array") { - StaticJsonDocument<1024> doc2; - doc2[0] = "world"; - variant.link(doc2); - - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - } - - SECTION("linked object") { - StaticJsonDocument<1024> doc2; - doc2["hello"] = "world"; - variant.link(doc2); - - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - } - - SECTION("linked int") { - StaticJsonDocument<1024> doc2; - doc2.set(42); - variant.link(doc2); - - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == true); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == false); - CHECK(cvariant.is() == true); - } } diff --git a/extras/tests/JsonVariant/isnull.cpp b/extras/tests/JsonVariant/isnull.cpp index ec5e0a34..1ec6f353 100644 --- a/extras/tests/JsonVariant/isnull.cpp +++ b/extras/tests/JsonVariant/isnull.cpp @@ -70,16 +70,16 @@ TEST_CASE("JsonVariant::isNull()") { REQUIRE(variant.isNull() == true); } - SECTION("returns true for a linked null") { + SECTION("returns true for a shallow null copy") { StaticJsonDocument<128> doc2; - variant.link(doc2); + variant.shallowCopy(doc2); CHECK(variant.isNull() == true); } - SECTION("returns false for a linked array") { + SECTION("returns false for a shallow array copy") { StaticJsonDocument<128> doc2; doc2[0] = 42; - variant.link(doc2); + variant.shallowCopy(doc2); CHECK(variant.isNull() == false); } diff --git a/extras/tests/JsonVariant/memoryUsage.cpp b/extras/tests/JsonVariant/memoryUsage.cpp index 5c18b906..59587dbb 100644 --- a/extras/tests/JsonVariant/memoryUsage.cpp +++ b/extras/tests/JsonVariant/memoryUsage.cpp @@ -38,12 +38,4 @@ TEST_CASE("JsonVariant::memoryUsage()") { REQUIRE(var.memoryUsage() == 6); REQUIRE(var.memoryUsage() == doc.memoryUsage()); } - - SECTION("ignore size of linked document") { - StaticJsonDocument<128> doc2; - doc2["hello"] = "world"; - var.link(doc2); - CHECK(var.memoryUsage() == 0); - CHECK(var.memoryUsage() == doc.memoryUsage()); - } } diff --git a/extras/tests/JsonVariant/nesting.cpp b/extras/tests/JsonVariant/nesting.cpp index e7602e51..3e936fbe 100644 --- a/extras/tests/JsonVariant/nesting.cpp +++ b/extras/tests/JsonVariant/nesting.cpp @@ -28,12 +28,4 @@ TEST_CASE("JsonVariant::nesting()") { var.to(); REQUIRE(var.nesting() == 1); } - - SECTION("returns depth of linked array") { - StaticJsonDocument<128> doc2; - doc2[0][0] = 42; - var.link(doc2); - - CHECK(var.nesting() == 2); - } } diff --git a/extras/tests/JsonVariant/or.cpp b/extras/tests/JsonVariant/or.cpp index 41bd2f79..7d1c190b 100644 --- a/extras/tests/JsonVariant/or.cpp +++ b/extras/tests/JsonVariant/or.cpp @@ -156,12 +156,4 @@ TEST_CASE("JsonVariant::operator|()") { int result = variant | 42; REQUIRE(result == 42); } - - SECTION("linked int | int") { - StaticJsonDocument<128> doc2; - doc2.set(42); - variant.link(doc2); - int result = variant | 666; - CHECK(result == 42); - } } diff --git a/extras/tests/JsonVariant/remove.cpp b/extras/tests/JsonVariant/remove.cpp index adaa0761..c744e19b 100644 --- a/extras/tests/JsonVariant/remove.cpp +++ b/extras/tests/JsonVariant/remove.cpp @@ -39,24 +39,4 @@ TEST_CASE("JsonVariant::remove()") { REQUIRE(var.as() == "{\"a\":1}"); } - - SECTION("linked array") { - StaticJsonDocument<128> doc2; - doc2[0] = 42; - var.link(doc2); - - var.remove(0); - - CHECK(var.as() == "[42]"); - } - - SECTION("linked object") { - StaticJsonDocument<128> doc2; - doc2["hello"] = "world"; - var.link(doc2); - - var.remove("hello"); - - CHECK(var.as() == "{\"hello\":\"world\"}"); - } } diff --git a/extras/tests/JsonVariant/link.cpp b/extras/tests/JsonVariant/shallowCopy.cpp similarity index 69% rename from extras/tests/JsonVariant/link.cpp rename to extras/tests/JsonVariant/shallowCopy.cpp index 28ef2ecd..c7c334b7 100644 --- a/extras/tests/JsonVariant/link.cpp +++ b/extras/tests/JsonVariant/shallowCopy.cpp @@ -5,17 +5,16 @@ #include #include -TEST_CASE("JsonVariant::link()") { +TEST_CASE("JsonVariant::shallowCopy()") { StaticJsonDocument<1024> doc1, doc2; JsonVariant variant = doc1.to(); - SECTION("JsonVariant::link(JsonDocument&)") { + SECTION("JsonVariant::shallowCopy(JsonDocument&)") { doc2["hello"] = "world"; - variant.link(doc2); + variant.shallowCopy(doc2); CHECK(variant.as() == "{\"hello\":\"world\"}"); - CHECK(variant.memoryUsage() == 0); // altering the linked document should change the result doc2["hello"] = "WORLD!"; @@ -23,13 +22,12 @@ TEST_CASE("JsonVariant::link()") { CHECK(variant.as() == "{\"hello\":\"WORLD!\"}"); } - SECTION("JsonVariant::link(MemberProxy)") { + SECTION("JsonVariant::shallowCopy(MemberProxy)") { doc2["obj"]["hello"] = "world"; - variant.link(doc2["obj"]); + variant.shallowCopy(doc2["obj"]); CHECK(variant.as() == "{\"hello\":\"world\"}"); - CHECK(variant.memoryUsage() == 0); // altering the linked document should change the result doc2["obj"]["hello"] = "WORLD!"; @@ -37,13 +35,12 @@ TEST_CASE("JsonVariant::link()") { CHECK(variant.as() == "{\"hello\":\"WORLD!\"}"); } - SECTION("JsonVariant::link(ElementProxy)") { + SECTION("JsonVariant::shallowCopy(ElementProxy)") { doc2[0]["hello"] = "world"; - variant.link(doc2[0]); + variant.shallowCopy(doc2[0]); CHECK(variant.as() == "{\"hello\":\"world\"}"); - CHECK(variant.memoryUsage() == 0); // altering the linked document should change the result doc2[0]["hello"] = "WORLD!"; @@ -55,7 +52,7 @@ TEST_CASE("JsonVariant::link()") { JsonVariant unbound; variant["hello"] = "world"; - variant.link(unbound); + variant.shallowCopy(unbound); CHECK(variant.isUnbound() == false); CHECK(variant.isNull() == true); @@ -67,11 +64,24 @@ TEST_CASE("JsonVariant::link()") { JsonVariant unbound; doc2["hello"] = "world"; - unbound.link(doc2); + unbound.shallowCopy(doc2); CHECK(unbound.isUnbound() == true); CHECK(unbound.isNull() == true); CHECK(unbound.memoryUsage() == 0); CHECK(unbound.size() == 0); } + + SECTION("preserves owned key bit") { + doc2.set(42); + + doc1["a"].shallowCopy(doc2); + doc1[std::string("b")].shallowCopy(doc2); + + JsonObject::iterator it = doc1.as().begin(); + + CHECK(it->key().isLinked() == true); + ++it; + CHECK(it->key().isLinked() == false); + } } diff --git a/extras/tests/JsonVariant/size.cpp b/extras/tests/JsonVariant/size.cpp index 9db3c538..73d9ced8 100644 --- a/extras/tests/JsonVariant/size.cpp +++ b/extras/tests/JsonVariant/size.cpp @@ -33,21 +33,4 @@ TEST_CASE("JsonVariant::size()") { CHECK(variant.size() == 2); } - - SECTION("linked object") { - StaticJsonDocument<1024> doc2; - doc2["hello"] = "world"; - variant.link(doc2); - - CHECK(variant.size() == 1); - } - - SECTION("linked array") { - StaticJsonDocument<1024> doc2; - doc2.add(1); - doc2.add(2); - variant.link(doc2); - - CHECK(variant.size() == 2); - } } diff --git a/extras/tests/JsonVariant/subscript.cpp b/extras/tests/JsonVariant/subscript.cpp index a1bba08c..f466cd27 100644 --- a/extras/tests/JsonVariant/subscript.cpp +++ b/extras/tests/JsonVariant/subscript.cpp @@ -129,44 +129,6 @@ TEST_CASE("JsonVariant::operator[]") { REQUIRE(std::string("world") == variant[vla]); } #endif - - SECTION("get value from linked object") { - StaticJsonDocument<1024> doc2; - doc2["hello"] = "world"; - var.link(doc2); - - CHECK(var["hello"].as() == "world"); - } - - SECTION("set value to linked object") { - StaticJsonDocument<1024> doc2; - doc2["hello"] = "world"; - var.link(doc2); - - var["tutu"] = "toto"; // no-op - - CHECK(doc.as() == "{\"hello\":\"world\"}"); - CHECK(doc2.as() == "{\"hello\":\"world\"}"); - } - - SECTION("get value from linked array") { - StaticJsonDocument<1024> doc2; - doc2.add(42); - var.link(doc2); - - CHECK(var[0].as() == 42); - } - - SECTION("set value to linked array") { - StaticJsonDocument<1024> doc2; - doc2.add(42); - var.link(doc2); - - var[0] = 666; // no-op - - CHECK(doc.as() == "[42]"); - CHECK(doc2.as() == "[42]"); - } } TEST_CASE("JsonVariantConst::operator[]") { @@ -239,20 +201,4 @@ TEST_CASE("JsonVariantConst::operator[]") { REQUIRE(var.is() == false); REQUIRE(value == 0); } - - SECTION("get value from linked object") { - StaticJsonDocument<1024> doc2; - doc2["hello"] = "world"; - var.link(doc2); - - CHECK(cvar["hello"].as() == "world"); - } - - SECTION("get value from linked array") { - StaticJsonDocument<1024> doc2; - doc2.add(42); - var.link(doc2); - - CHECK(cvar[0].as() == 42); - } } diff --git a/src/ArduinoJson/Array/ArrayRef.hpp b/src/ArduinoJson/Array/ArrayRef.hpp index fb396987..2a897406 100644 --- a/src/ArduinoJson/Array/ArrayRef.hpp +++ b/src/ArduinoJson/Array/ArrayRef.hpp @@ -202,12 +202,12 @@ struct Converter { static ArrayConstRef fromJson(VariantConstRef src) { const VariantData* data = getData(src); - return data ? data->resolve()->asArray() : 0; + return data ? data->asArray() : 0; } static bool checkJson(VariantConstRef src) { const VariantData* data = getData(src); - return data && data->resolve()->isArray(); + return data && data->isArray(); } }; diff --git a/src/ArduinoJson/Array/ElementProxy.hpp b/src/ArduinoJson/Array/ElementProxy.hpp index 588f3331..4f3cbd0b 100644 --- a/src/ArduinoJson/Array/ElementProxy.hpp +++ b/src/ArduinoJson/Array/ElementProxy.hpp @@ -106,8 +106,8 @@ class ElementProxy : public VariantOperators >, return getOrAddUpstreamElement().template to(); } - FORCE_INLINE void link(VariantConstRef value) const { - getOrAddUpstreamElement().link(value); + FORCE_INLINE void shallowCopy(VariantConstRef value) const { + getOrAddUpstreamElement().shallowCopy(value); } // Replaces the value diff --git a/src/ArduinoJson/Collection/CollectionImpl.hpp b/src/ArduinoJson/Collection/CollectionImpl.hpp index 8f963baa..da9835e3 100644 --- a/src/ArduinoJson/Collection/CollectionImpl.hpp +++ b/src/ArduinoJson/Collection/CollectionImpl.hpp @@ -17,6 +17,7 @@ inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) { return 0; if (_tail) { + ARDUINOJSON_ASSERT(pool->owns(_tail)); // Can't alter a linked array/object _tail->setNextNotNull(slot); _tail = slot; } else { diff --git a/src/ArduinoJson/Document/JsonDocument.hpp b/src/ArduinoJson/Document/JsonDocument.hpp index 17f06e30..bcd14716 100644 --- a/src/ArduinoJson/Document/JsonDocument.hpp +++ b/src/ArduinoJson/Document/JsonDocument.hpp @@ -62,7 +62,7 @@ class JsonDocument : public VariantOperators { } size_t size() const { - return _data.resolve()->size(); + return _data.size(); } bool set(const JsonDocument& src) { diff --git a/src/ArduinoJson/Json/JsonSerializer.hpp b/src/ArduinoJson/Json/JsonSerializer.hpp index 31bd529e..3b016a63 100644 --- a/src/ArduinoJson/Json/JsonSerializer.hpp +++ b/src/ArduinoJson/Json/JsonSerializer.hpp @@ -24,7 +24,7 @@ class JsonSerializer : public Visitor { const VariantSlot *slot = array.head(); while (slot != 0) { - slot->data()->resolve()->accept(*this); + slot->data()->accept(*this); slot = slot->next(); if (slot == 0) @@ -45,7 +45,7 @@ class JsonSerializer : public Visitor { while (slot != 0) { _formatter.writeString(slot->key()); write(':'); - slot->data()->resolve()->accept(*this); + slot->data()->accept(*this); slot = slot->next(); if (slot == 0) diff --git a/src/ArduinoJson/Json/PrettyJsonSerializer.hpp b/src/ArduinoJson/Json/PrettyJsonSerializer.hpp index 3f63b2c5..c80ad940 100644 --- a/src/ArduinoJson/Json/PrettyJsonSerializer.hpp +++ b/src/ArduinoJson/Json/PrettyJsonSerializer.hpp @@ -25,7 +25,7 @@ class PrettyJsonSerializer : public JsonSerializer { _nesting++; while (slot != 0) { indent(); - slot->data()->resolve()->accept(*this); + slot->data()->accept(*this); slot = slot->next(); base::write(slot ? ",\r\n" : "\r\n"); @@ -48,7 +48,7 @@ class PrettyJsonSerializer : public JsonSerializer { indent(); base::visitString(slot->key()); base::write(": "); - slot->data()->resolve()->accept(*this); + slot->data()->accept(*this); slot = slot->next(); base::write(slot ? ",\r\n" : "\r\n"); diff --git a/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp b/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp index 1abc7cc7..6217d8bb 100644 --- a/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp +++ b/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp @@ -56,7 +56,7 @@ class MsgPackSerializer : public Visitor { writeInteger(uint32_t(n)); } for (const VariantSlot* slot = array.head(); slot; slot = slot->next()) { - slot->data()->resolve()->accept(*this); + slot->data()->accept(*this); } return bytesWritten(); } @@ -74,7 +74,7 @@ class MsgPackSerializer : public Visitor { } for (const VariantSlot* slot = object.head(); slot; slot = slot->next()) { visitString(slot->key()); - slot->data()->resolve()->accept(*this); + slot->data()->accept(*this); } return bytesWritten(); } diff --git a/src/ArduinoJson/Object/MemberProxy.hpp b/src/ArduinoJson/Object/MemberProxy.hpp index 67f49d78..2b246231 100644 --- a/src/ArduinoJson/Object/MemberProxy.hpp +++ b/src/ArduinoJson/Object/MemberProxy.hpp @@ -132,8 +132,8 @@ class MemberProxy : public VariantOperators >, getUpstreamMember().remove(key); } - FORCE_INLINE void link(VariantConstRef value) { - getOrAddUpstreamMember().link(value); + FORCE_INLINE void shallowCopy(VariantConstRef value) { + getOrAddUpstreamMember().shallowCopy(value); } template diff --git a/src/ArduinoJson/Object/ObjectRef.hpp b/src/ArduinoJson/Object/ObjectRef.hpp index ba862abe..7f383093 100644 --- a/src/ArduinoJson/Object/ObjectRef.hpp +++ b/src/ArduinoJson/Object/ObjectRef.hpp @@ -269,12 +269,12 @@ struct Converter { static ObjectConstRef fromJson(VariantConstRef src) { const VariantData* data = getData(src); - return data != 0 ? data->resolve()->asObject() : 0; + return data != 0 ? data->asObject() : 0; } static bool checkJson(VariantConstRef src) { const VariantData* data = getData(src); - return data && data->resolve()->isObject(); + return data && data->isObject(); } }; diff --git a/src/ArduinoJson/Variant/ConverterImpl.hpp b/src/ArduinoJson/Variant/ConverterImpl.hpp index a510aa23..9a207fa2 100644 --- a/src/ArduinoJson/Variant/ConverterImpl.hpp +++ b/src/ArduinoJson/Variant/ConverterImpl.hpp @@ -48,12 +48,12 @@ struct Converter< static T fromJson(VariantConstRef src) { ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T); const VariantData* data = getData(src); - return data ? data->resolve()->asIntegral() : T(); + return data ? data->asIntegral() : T(); } static bool checkJson(VariantConstRef src) { const VariantData* data = getData(src); - return data && data->resolve()->isInteger(); + return data && data->isInteger(); } }; @@ -65,12 +65,12 @@ struct Converter::value>::type> { static T fromJson(VariantConstRef src) { const VariantData* data = getData(src); - return data ? static_cast(data->resolve()->asIntegral()) : T(); + return data ? static_cast(data->asIntegral()) : T(); } static bool checkJson(VariantConstRef src) { const VariantData* data = getData(src); - return data && data->resolve()->isInteger(); + return data && data->isInteger(); } }; @@ -84,12 +84,12 @@ struct Converter { static bool fromJson(VariantConstRef src) { const VariantData* data = getData(src); - return data ? data->resolve()->asBoolean() : false; + return data ? data->asBoolean() : false; } static bool checkJson(VariantConstRef src) { const VariantData* data = getData(src); - return data && data->resolve()->isBoolean(); + return data && data->isBoolean(); } }; @@ -103,12 +103,12 @@ struct Converter::value>::type> { static T fromJson(VariantConstRef src) { const VariantData* data = getData(src); - return data ? data->resolve()->asFloat() : 0; + return data ? data->asFloat() : 0; } static bool checkJson(VariantConstRef src) { const VariantData* data = getData(src); - return data && data->resolve()->isFloat(); + return data && data->isFloat(); } }; @@ -121,12 +121,12 @@ struct Converter { static const char* fromJson(VariantConstRef src) { const VariantData* data = getData(src); - return data ? data->resolve()->asString().c_str() : 0; + return data ? data->asString().c_str() : 0; } static bool checkJson(VariantConstRef src) { const VariantData* data = getData(src); - return data && data->resolve()->isString(); + return data && data->isString(); } }; @@ -139,12 +139,12 @@ struct Converter { static String fromJson(VariantConstRef src) { const VariantData* data = getData(src); - return data ? data->resolve()->asString() : 0; + return data ? data->asString() : 0; } static bool checkJson(VariantConstRef src) { const VariantData* data = getData(src); - return data && data->resolve()->isString(); + return data && data->isString(); } }; @@ -192,7 +192,7 @@ struct Converter { } static bool checkJson(VariantConstRef src) { const VariantData* data = getData(src); - return data == 0 || data->resolve()->isNull(); + return data == 0 || data->isNull(); } }; diff --git a/src/ArduinoJson/Variant/VariantContent.hpp b/src/ArduinoJson/Variant/VariantContent.hpp index 3ede76ef..dbe833e5 100644 --- a/src/ArduinoJson/Variant/VariantContent.hpp +++ b/src/ArduinoJson/Variant/VariantContent.hpp @@ -31,8 +31,6 @@ enum { VALUE_IS_SIGNED_INTEGER = 0x0A, VALUE_IS_FLOAT = 0x0C, - VALUE_IS_POINTER = 0x10, - COLLECTION_MASK = 0x60, VALUE_IS_OBJECT = 0x20, VALUE_IS_ARRAY = 0x40, @@ -51,7 +49,6 @@ union VariantContent { UInt asUnsignedInteger; Integer asSignedInteger; CollectionData asCollection; - const class VariantData *asPointer; struct { const char *data; size_t size; diff --git a/src/ArduinoJson/Variant/VariantData.hpp b/src/ArduinoJson/Variant/VariantData.hpp index e99400fd..a2e5d33c 100644 --- a/src/ArduinoJson/Variant/VariantData.hpp +++ b/src/ArduinoJson/Variant/VariantData.hpp @@ -37,6 +37,11 @@ class VariantData { _flags = VALUE_IS_NULL; } + void operator=(const VariantData &src) { + _content = src._content; + _flags = uint8_t((_flags & OWNED_KEY_BIT) | (src._flags & ~OWNED_KEY_BIT)); + } + template typename TVisitor::result_type accept(TVisitor &visitor) const { switch (type()) { @@ -83,12 +88,6 @@ class VariantData { bool asBoolean() const; - const VariantData *resolve() const { - if (isPointer()) - return _content.asPointer->resolve(); - return this; - } - CollectionData *asArray() { return isArray() ? &_content.asCollection : 0; } @@ -123,10 +122,6 @@ class VariantData { return (_flags & COLLECTION_MASK) != 0; } - bool isPointer() const { - return type() == VALUE_IS_POINTER; - } - template bool isInteger() const { switch (type()) { @@ -222,12 +217,6 @@ class VariantData { setType(VALUE_IS_NULL); } - void setPointer(const VariantData *p) { - ARDUINOJSON_ASSERT(p); - setType(VALUE_IS_POINTER); - _content.asPointer = p; - } - void setString(String s) { ARDUINOJSON_ASSERT(s); if (s.isLinked()) diff --git a/src/ArduinoJson/Variant/VariantFunctions.hpp b/src/ArduinoJson/Variant/VariantFunctions.hpp index 5962fd87..16e9b403 100644 --- a/src/ArduinoJson/Variant/VariantFunctions.hpp +++ b/src/ArduinoJson/Variant/VariantFunctions.hpp @@ -15,7 +15,7 @@ template inline typename TVisitor::result_type variantAccept(const VariantData *var, TVisitor &visitor) { if (var != 0) - return var->resolve()->accept(visitor); + return var->accept(visitor); else return visitor.visitNull(); } @@ -44,7 +44,7 @@ inline bool variantSetString(VariantData *var, TAdaptedString value, } inline size_t variantSize(const VariantData *var) { - return var != 0 ? var->resolve()->size() : 0; + return var != 0 ? var->size() : 0; } inline CollectionData *variantToArray(VariantData *var) { @@ -90,14 +90,14 @@ NO_INLINE VariantData *variantGetOrAddMember(VariantData *var, } inline bool variantIsNull(const VariantData *var) { - return var == 0 || var->resolve()->isNull(); + return var == 0 || var->isNull(); } inline size_t variantNesting(const VariantData *var) { if (!var) return 0; - const CollectionData *collection = var->resolve()->asCollection(); + const CollectionData *collection = var->asCollection(); if (!collection) return 0; diff --git a/src/ArduinoJson/Variant/VariantRef.hpp b/src/ArduinoJson/Variant/VariantRef.hpp index 10863400..47684e39 100644 --- a/src/ArduinoJson/Variant/VariantRef.hpp +++ b/src/ArduinoJson/Variant/VariantRef.hpp @@ -117,8 +117,7 @@ class VariantConstRef : public VariantRefBase, } FORCE_INLINE VariantConstRef getElementConst(size_t index) const { - return VariantConstRef(_data != 0 ? _data->resolve()->getElement(index) - : 0); + return VariantConstRef(_data != 0 ? _data->getElement(index) : 0); } FORCE_INLINE VariantConstRef operator[](size_t index) const { @@ -129,8 +128,7 @@ class VariantConstRef : public VariantRefBase, // getMemberConst(const String&) const template FORCE_INLINE VariantConstRef getMemberConst(const TString &key) const { - return VariantConstRef(_data ? _data->resolve()->getMember(adaptString(key)) - : 0); + return VariantConstRef(_data ? _data->getMember(adaptString(key)) : 0); } // getMemberConst(char*) const @@ -138,8 +136,7 @@ class VariantConstRef : public VariantRefBase, // getMemberConst(const __FlashStringHelper*) const template FORCE_INLINE VariantConstRef getMemberConst(TChar *key) const { - return VariantConstRef(_data ? _data->resolve()->getMember(adaptString(key)) - : 0); + return VariantConstRef(_data ? _data->getMember(adaptString(key)) : 0); } // operator[](const std::string&) const @@ -281,8 +278,7 @@ class VariantRef : public VariantRefBase, } FORCE_INLINE VariantConstRef getElementConst(size_t index) const { - return VariantConstRef(_data != 0 ? _data->resolve()->getElement(index) - : 0); + return VariantConstRef(_data != 0 ? _data->getElement(index) : 0); } FORCE_INLINE VariantRef getOrAddElement(size_t index) const { @@ -310,8 +306,7 @@ class VariantRef : public VariantRefBase, // getMemberConst(const __FlashStringHelper*) const template FORCE_INLINE VariantConstRef getMemberConst(TChar *key) const { - return VariantConstRef(_data ? _data->resolve()->getMember(adaptString(key)) - : 0); + return VariantConstRef(_data ? _data->getMember(adaptString(key)) : 0); } // getMemberConst(const std::string&) const @@ -320,8 +315,7 @@ class VariantRef : public VariantRefBase, FORCE_INLINE typename enable_if::value, VariantConstRef>::type getMemberConst(const TString &key) const { - return VariantConstRef(_data ? _data->resolve()->getMember(adaptString(key)) - : 0); + return VariantConstRef(_data ? _data->getMember(adaptString(key)) : 0); } // getOrAddMember(char*) const @@ -361,12 +355,12 @@ class VariantRef : public VariantRefBase, _data->remove(adaptString(key)); } - inline void link(VariantConstRef target) { + inline void shallowCopy(VariantConstRef target) { if (!_data) return; const VariantData *targetData = getData(target); if (targetData) - _data->setPointer(targetData); + *_data = *targetData; else _data->setNull(); }