mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Change link() to shallowCopy() (issue #1343)
				
					
				
			Instead of storing a pointer, the function copies the `VariantData`. Benefits: * smaller code * no impact on programs that don't use this feature Drawbacks: * changes to the original variant are not always reflected on the copy * modifying the original from the shallow copy leads to UB
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
| @@ -43,13 +43,5 @@ TEST_CASE("nullptr") { | ||||
|  | ||||
|     variant.clear(); | ||||
|     REQUIRE(variant.is<std::nullptr_t>() == true); | ||||
|  | ||||
|     StaticJsonDocument<128> doc2; | ||||
|     doc2["hello"] = "world"; | ||||
|     variant.link(doc2); | ||||
|     REQUIRE(variant.is<std::nullptr_t>() == false); | ||||
|  | ||||
|     doc2.clear(); | ||||
|     REQUIRE(variant.is<std::nullptr_t>() == true); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -246,10 +246,10 @@ TEST_CASE("ElementProxy cast to JsonVariant") { | ||||
|   CHECK(doc.as<std::string>() == "[\"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<std::string>() == "[{\"hello\":\"world\"}]"); | ||||
| } | ||||
|   | ||||
| @@ -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<std::string>() == "{\"obj\":{\"hello\":\"world\"}}"); | ||||
| } | ||||
|   | ||||
| @@ -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<JsonVariant>().link(doc2); | ||||
|  | ||||
|     REQUIRE(doc.size() == 2); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked object") { | ||||
|     StaticJsonDocument<128> doc2; | ||||
|     doc2["hello"] = "world"; | ||||
|     doc.as<JsonVariant>().link(doc2); | ||||
|  | ||||
|     REQUIRE(doc.size() == 1); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -43,14 +43,4 @@ TEST_CASE("JsonVariant::add()") { | ||||
|  | ||||
|     REQUIRE(var.as<std::string>() == "{\"val\":123}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("add to linked array") { | ||||
|     StaticJsonDocument<1024> doc2; | ||||
|     doc2.add(42); | ||||
|     var.link(doc2); | ||||
|  | ||||
|     var.add(666);  // no-op | ||||
|  | ||||
|     CHECK(var.as<std::string>() == "[42]"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -267,97 +267,4 @@ TEST_CASE("JsonVariant::as()") { | ||||
|  | ||||
|     REQUIRE(variant.as<MY_ENUM>() == ONE); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked object") { | ||||
|     StaticJsonDocument<128> doc2; | ||||
|     doc2["hello"] = "world"; | ||||
|     variant.link(doc2); | ||||
|  | ||||
|     SECTION("as<std::string>()") { | ||||
|       CHECK(variant.as<std::string>() == "{\"hello\":\"world\"}"); | ||||
|     } | ||||
|  | ||||
|     SECTION("as<JsonArray>()") { | ||||
|       JsonArray a = variant.as<JsonArray>(); | ||||
|       CHECK(a.isNull() == true); | ||||
|     } | ||||
|  | ||||
|     SECTION("as<JsonObject>()") { | ||||
|       JsonObject o = variant.as<JsonObject>(); | ||||
|       CHECK(o.isNull() == true); | ||||
|     } | ||||
|  | ||||
|     SECTION("as<JsonObjectConst>()") { | ||||
|       JsonObjectConst o = variant.as<JsonObjectConst>(); | ||||
|       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<std::string>()") { | ||||
|       CHECK(variant.as<std::string>() == "[\"hello\",\"world\"]"); | ||||
|     } | ||||
|  | ||||
|     SECTION("as<JsonArray>()") { | ||||
|       JsonArray a = variant.as<JsonArray>(); | ||||
|       CHECK(a.isNull() == true); | ||||
|     } | ||||
|  | ||||
|     SECTION("as<JsonArrayConst>()") { | ||||
|       JsonArrayConst a = variant.as<JsonArrayConst>(); | ||||
|       CHECK(a.isNull() == false); | ||||
|       CHECK(a.size() == 2); | ||||
|       CHECK(a[0] == "hello"); | ||||
|       CHECK(a[1] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("as<JsonObject>()") { | ||||
|       JsonObject o = variant.as<JsonObject>(); | ||||
|       CHECK(o.isNull() == true); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("linked int") { | ||||
|     StaticJsonDocument<128> doc2; | ||||
|     doc2.set(42); | ||||
|     variant.link(doc2); | ||||
|  | ||||
|     CHECK(variant.as<int>() == 42); | ||||
|     CHECK(variant.as<double>() == 42.0); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked double") { | ||||
|     StaticJsonDocument<128> doc2; | ||||
|     doc2.set(42.0); | ||||
|     variant.link(doc2); | ||||
|  | ||||
|     CHECK(variant.as<int>() == 42); | ||||
|     CHECK(variant.as<double>() == 42.0); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked string") { | ||||
|     StaticJsonDocument<128> doc2; | ||||
|     doc2.set("hello"); | ||||
|     variant.link(doc2); | ||||
|  | ||||
|     CHECK(variant.as<std::string>() == "hello"); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked bool") { | ||||
|     StaticJsonDocument<128> doc2; | ||||
|     variant.link(doc2); | ||||
|  | ||||
|     doc2.set(true); | ||||
|     CHECK(variant.as<bool>() == true); | ||||
|  | ||||
|     doc2.set(false); | ||||
|     CHECK(variant.as<bool>() == false); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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<std::string>() == "{\"hello\":\"world\"}"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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()") { | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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<JsonArray>() == 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<JsonObject>() == 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<JsonObject>() == 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"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -144,24 +144,6 @@ TEST_CASE("JsonVariant::is<T>()") { | ||||
|     CHECK(variant.is<MYENUM2>() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked array") { | ||||
|     StaticJsonDocument<1024> doc2; | ||||
|     doc2[0] = "world"; | ||||
|     variant.link(doc2); | ||||
|  | ||||
|     CHECK(variant.is<JsonArray>() == false); | ||||
|     CHECK(variant.is<JsonArrayConst>() == true); | ||||
|     CHECK(variant.is<JsonVariant>() == true); | ||||
|     CHECK(variant.is<JsonVariantConst>() == true); | ||||
|     CHECK(variant.is<JsonObject>() == false); | ||||
|     CHECK(variant.is<JsonObjectConst>() == false); | ||||
|     CHECK(variant.is<int>() == false); | ||||
|     CHECK(variant.is<float>() == false); | ||||
|     CHECK(variant.is<bool>() == false); | ||||
|     CHECK(variant.is<const char *>() == false); | ||||
|     CHECK(variant.is<MYENUM2>() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonObject") { | ||||
|     variant.to<JsonObject>(); | ||||
|  | ||||
| @@ -179,44 +161,6 @@ TEST_CASE("JsonVariant::is<T>()") { | ||||
|     CHECK(variant.is<JsonVariant>() == true); | ||||
|     CHECK(variant.is<JsonVariantConst>() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked object") { | ||||
|     StaticJsonDocument<1024> doc2; | ||||
|     doc2["hello"] = "world"; | ||||
|     variant.link(doc2); | ||||
|  | ||||
|     CHECK(variant.is<JsonObject>() == false); | ||||
|     CHECK(variant.is<JsonObjectConst>() == true); | ||||
|     CHECK(variant.is<JsonVariant>() == true); | ||||
|     CHECK(variant.is<JsonVariantConst>() == true); | ||||
|     CHECK(variant.is<JsonArray>() == false); | ||||
|     CHECK(variant.is<JsonArrayConst>() == false); | ||||
|     CHECK(variant.is<int>() == false); | ||||
|     CHECK(variant.is<float>() == false); | ||||
|     CHECK(variant.is<bool>() == false); | ||||
|     CHECK(variant.is<const char *>() == false); | ||||
|     CHECK(variant.is<MYENUM2>() == false); | ||||
|     CHECK(variant.is<JsonVariant>() == true); | ||||
|     CHECK(variant.is<JsonVariantConst>() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked int") { | ||||
|     StaticJsonDocument<1024> doc2; | ||||
|     doc2.set(42); | ||||
|     variant.link(doc2); | ||||
|  | ||||
|     CHECK(variant.is<JsonObjectConst>() == false); | ||||
|     CHECK(variant.is<JsonVariantConst>() == true); | ||||
|     CHECK(variant.is<JsonObject>() == false); | ||||
|     CHECK(variant.is<JsonVariant>() == true); | ||||
|     CHECK(variant.is<JsonArray>() == false); | ||||
|     CHECK(variant.is<JsonArrayConst>() == false); | ||||
|     CHECK(variant.is<int>() == true); | ||||
|     CHECK(variant.is<float>() == true); | ||||
|     CHECK(variant.is<bool>() == false); | ||||
|     CHECK(variant.is<const char *>() == false); | ||||
|     CHECK(variant.is<MYENUM2>() == true); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariantConst::is<T>()") { | ||||
| @@ -372,58 +316,4 @@ TEST_CASE("JsonVariantConst::is<T>()") { | ||||
|     CHECK(cvariant.is<const char *>() == false); | ||||
|     CHECK(cvariant.is<MYENUM2>() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked array") { | ||||
|     StaticJsonDocument<1024> doc2; | ||||
|     doc2[0] = "world"; | ||||
|     variant.link(doc2); | ||||
|  | ||||
|     CHECK(cvariant.is<JsonArrayConst>() == true); | ||||
|     CHECK(cvariant.is<JsonVariantConst>() == true); | ||||
|     CHECK(cvariant.is<JsonArray>() == false); | ||||
|     CHECK(cvariant.is<JsonVariant>() == false); | ||||
|     CHECK(cvariant.is<JsonObject>() == false); | ||||
|     CHECK(cvariant.is<JsonObjectConst>() == false); | ||||
|     CHECK(cvariant.is<int>() == false); | ||||
|     CHECK(cvariant.is<float>() == false); | ||||
|     CHECK(cvariant.is<bool>() == false); | ||||
|     CHECK(cvariant.is<const char *>() == false); | ||||
|     CHECK(cvariant.is<MYENUM2>() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked object") { | ||||
|     StaticJsonDocument<1024> doc2; | ||||
|     doc2["hello"] = "world"; | ||||
|     variant.link(doc2); | ||||
|  | ||||
|     CHECK(cvariant.is<JsonObjectConst>() == true); | ||||
|     CHECK(cvariant.is<JsonVariantConst>() == true); | ||||
|     CHECK(cvariant.is<JsonObject>() == false); | ||||
|     CHECK(cvariant.is<JsonVariant>() == false); | ||||
|     CHECK(cvariant.is<JsonArray>() == false); | ||||
|     CHECK(cvariant.is<JsonArrayConst>() == false); | ||||
|     CHECK(cvariant.is<int>() == false); | ||||
|     CHECK(cvariant.is<float>() == false); | ||||
|     CHECK(cvariant.is<bool>() == false); | ||||
|     CHECK(cvariant.is<const char *>() == false); | ||||
|     CHECK(cvariant.is<MYENUM2>() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked int") { | ||||
|     StaticJsonDocument<1024> doc2; | ||||
|     doc2.set(42); | ||||
|     variant.link(doc2); | ||||
|  | ||||
|     CHECK(cvariant.is<JsonObjectConst>() == false); | ||||
|     CHECK(cvariant.is<JsonVariantConst>() == true); | ||||
|     CHECK(cvariant.is<JsonObject>() == false); | ||||
|     CHECK(cvariant.is<JsonVariant>() == false); | ||||
|     CHECK(cvariant.is<JsonArray>() == false); | ||||
|     CHECK(cvariant.is<JsonArrayConst>() == false); | ||||
|     CHECK(cvariant.is<int>() == true); | ||||
|     CHECK(cvariant.is<float>() == true); | ||||
|     CHECK(cvariant.is<bool>() == false); | ||||
|     CHECK(cvariant.is<const char *>() == false); | ||||
|     CHECK(cvariant.is<MYENUM2>() == true); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -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()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -28,12 +28,4 @@ TEST_CASE("JsonVariant::nesting()") { | ||||
|     var.to<JsonArray>(); | ||||
|     REQUIRE(var.nesting() == 1); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns depth of linked array") { | ||||
|     StaticJsonDocument<128> doc2; | ||||
|     doc2[0][0] = 42; | ||||
|     var.link(doc2); | ||||
|  | ||||
|     CHECK(var.nesting() == 2); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -39,24 +39,4 @@ TEST_CASE("JsonVariant::remove()") { | ||||
|  | ||||
|     REQUIRE(var.as<std::string>() == "{\"a\":1}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked array") { | ||||
|     StaticJsonDocument<128> doc2; | ||||
|     doc2[0] = 42; | ||||
|     var.link(doc2); | ||||
|  | ||||
|     var.remove(0); | ||||
|  | ||||
|     CHECK(var.as<std::string>() == "[42]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked object") { | ||||
|     StaticJsonDocument<128> doc2; | ||||
|     doc2["hello"] = "world"; | ||||
|     var.link(doc2); | ||||
|  | ||||
|     var.remove("hello"); | ||||
|  | ||||
|     CHECK(var.as<std::string>() == "{\"hello\":\"world\"}"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -5,17 +5,16 @@ | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| 
 | ||||
| TEST_CASE("JsonVariant::link()") { | ||||
| TEST_CASE("JsonVariant::shallowCopy()") { | ||||
|   StaticJsonDocument<1024> doc1, doc2; | ||||
|   JsonVariant variant = doc1.to<JsonVariant>(); | ||||
| 
 | ||||
|   SECTION("JsonVariant::link(JsonDocument&)") { | ||||
|   SECTION("JsonVariant::shallowCopy(JsonDocument&)") { | ||||
|     doc2["hello"] = "world"; | ||||
| 
 | ||||
|     variant.link(doc2); | ||||
|     variant.shallowCopy(doc2); | ||||
| 
 | ||||
|     CHECK(variant.as<std::string>() == "{\"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<std::string>() == "{\"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<std::string>() == "{\"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<std::string>() == "{\"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<std::string>() == "{\"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<JsonObject>().begin(); | ||||
| 
 | ||||
|     CHECK(it->key().isLinked() == true); | ||||
|     ++it; | ||||
|     CHECK(it->key().isLinked() == false); | ||||
|   } | ||||
| } | ||||
| @@ -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); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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<std::string>() == "world"); | ||||
|   } | ||||
|  | ||||
|   SECTION("set value to linked object") { | ||||
|     StaticJsonDocument<1024> doc2; | ||||
|     doc2["hello"] = "world"; | ||||
|     var.link(doc2); | ||||
|  | ||||
|     var["tutu"] = "toto";  // no-op | ||||
|  | ||||
|     CHECK(doc.as<std::string>() == "{\"hello\":\"world\"}"); | ||||
|     CHECK(doc2.as<std::string>() == "{\"hello\":\"world\"}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("get value from linked array") { | ||||
|     StaticJsonDocument<1024> doc2; | ||||
|     doc2.add(42); | ||||
|     var.link(doc2); | ||||
|  | ||||
|     CHECK(var[0].as<int>() == 42); | ||||
|   } | ||||
|  | ||||
|   SECTION("set value to linked array") { | ||||
|     StaticJsonDocument<1024> doc2; | ||||
|     doc2.add(42); | ||||
|     var.link(doc2); | ||||
|  | ||||
|     var[0] = 666;  // no-op | ||||
|  | ||||
|     CHECK(doc.as<std::string>() == "[42]"); | ||||
|     CHECK(doc2.as<std::string>() == "[42]"); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariantConst::operator[]") { | ||||
| @@ -239,20 +201,4 @@ TEST_CASE("JsonVariantConst::operator[]") { | ||||
|     REQUIRE(var.is<JsonObject>() == false); | ||||
|     REQUIRE(value == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("get value from linked object") { | ||||
|     StaticJsonDocument<1024> doc2; | ||||
|     doc2["hello"] = "world"; | ||||
|     var.link(doc2); | ||||
|  | ||||
|     CHECK(cvar["hello"].as<std::string>() == "world"); | ||||
|   } | ||||
|  | ||||
|   SECTION("get value from linked array") { | ||||
|     StaticJsonDocument<1024> doc2; | ||||
|     doc2.add(42); | ||||
|     var.link(doc2); | ||||
|  | ||||
|     CHECK(cvar[0].as<int>() == 42); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -202,12 +202,12 @@ struct Converter<ArrayConstRef> { | ||||
|  | ||||
|   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(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -106,8 +106,8 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >, | ||||
|     return getOrAddUpstreamElement().template to<T>(); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE void link(VariantConstRef value) const { | ||||
|     getOrAddUpstreamElement().link(value); | ||||
|   FORCE_INLINE void shallowCopy(VariantConstRef value) const { | ||||
|     getOrAddUpstreamElement().shallowCopy(value); | ||||
|   } | ||||
|  | ||||
|   // Replaces the value | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -62,7 +62,7 @@ class JsonDocument : public VariantOperators<const JsonDocument&> { | ||||
|   } | ||||
|  | ||||
|   size_t size() const { | ||||
|     return _data.resolve()->size(); | ||||
|     return _data.size(); | ||||
|   } | ||||
|  | ||||
|   bool set(const JsonDocument& src) { | ||||
|   | ||||
| @@ -24,7 +24,7 @@ class JsonSerializer : public Visitor<size_t> { | ||||
|     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<size_t> { | ||||
|     while (slot != 0) { | ||||
|       _formatter.writeString(slot->key()); | ||||
|       write(':'); | ||||
|       slot->data()->resolve()->accept(*this); | ||||
|       slot->data()->accept(*this); | ||||
|  | ||||
|       slot = slot->next(); | ||||
|       if (slot == 0) | ||||
|   | ||||
| @@ -25,7 +25,7 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> { | ||||
|       _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<TWriter> { | ||||
|         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"); | ||||
|   | ||||
| @@ -56,7 +56,7 @@ class MsgPackSerializer : public Visitor<size_t> { | ||||
|       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<size_t> { | ||||
|     } | ||||
|     for (const VariantSlot* slot = object.head(); slot; slot = slot->next()) { | ||||
|       visitString(slot->key()); | ||||
|       slot->data()->resolve()->accept(*this); | ||||
|       slot->data()->accept(*this); | ||||
|     } | ||||
|     return bytesWritten(); | ||||
|   } | ||||
|   | ||||
| @@ -132,8 +132,8 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >, | ||||
|     getUpstreamMember().remove(key); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE void link(VariantConstRef value) { | ||||
|     getOrAddUpstreamMember().link(value); | ||||
|   FORCE_INLINE void shallowCopy(VariantConstRef value) { | ||||
|     getOrAddUpstreamMember().shallowCopy(value); | ||||
|   } | ||||
|  | ||||
|   template <typename TValue> | ||||
|   | ||||
| @@ -269,12 +269,12 @@ struct Converter<ObjectConstRef> { | ||||
|  | ||||
|   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(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -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>() : T(); | ||||
|     return data ? data->asIntegral<T>() : T(); | ||||
|   } | ||||
|  | ||||
|   static bool checkJson(VariantConstRef src) { | ||||
|     const VariantData* data = getData(src); | ||||
|     return data && data->resolve()->isInteger<T>(); | ||||
|     return data && data->isInteger<T>(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| @@ -65,12 +65,12 @@ struct Converter<T, typename enable_if<is_enum<T>::value>::type> { | ||||
|  | ||||
|   static T fromJson(VariantConstRef src) { | ||||
|     const VariantData* data = getData(src); | ||||
|     return data ? static_cast<T>(data->resolve()->asIntegral<int>()) : T(); | ||||
|     return data ? static_cast<T>(data->asIntegral<int>()) : T(); | ||||
|   } | ||||
|  | ||||
|   static bool checkJson(VariantConstRef src) { | ||||
|     const VariantData* data = getData(src); | ||||
|     return data && data->resolve()->isInteger<int>(); | ||||
|     return data && data->isInteger<int>(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| @@ -84,12 +84,12 @@ struct Converter<bool> { | ||||
|  | ||||
|   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<T, typename enable_if<is_floating_point<T>::value>::type> { | ||||
|  | ||||
|   static T fromJson(VariantConstRef src) { | ||||
|     const VariantData* data = getData(src); | ||||
|     return data ? data->resolve()->asFloat<T>() : 0; | ||||
|     return data ? data->asFloat<T>() : 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<const char*> { | ||||
|  | ||||
|   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<String> { | ||||
|  | ||||
|   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<decltype(nullptr)> { | ||||
|   } | ||||
|   static bool checkJson(VariantConstRef src) { | ||||
|     const VariantData* data = getData(src); | ||||
|     return data == 0 || data->resolve()->isNull(); | ||||
|     return data == 0 || data->isNull(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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> | ||||
|   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 <typename T> | ||||
|   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()) | ||||
|   | ||||
| @@ -15,7 +15,7 @@ template <typename TVisitor> | ||||
| 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; | ||||
|  | ||||
|   | ||||
| @@ -117,8 +117,7 @@ class VariantConstRef : public VariantRefBase<const VariantData>, | ||||
|   } | ||||
|  | ||||
|   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<const VariantData>, | ||||
|   // getMemberConst(const String&) const | ||||
|   template <typename TString> | ||||
|   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<const VariantData>, | ||||
|   // getMemberConst(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   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<VariantData>, | ||||
|   } | ||||
|  | ||||
|   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<VariantData>, | ||||
|   // getMemberConst(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   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<VariantData>, | ||||
|   FORCE_INLINE | ||||
|       typename enable_if<IsString<TString>::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<VariantData>, | ||||
|       _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(); | ||||
|   } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user