mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-21 22:42:25 +02:00
Add JsonVariant::link()
(resolves #1343)
This commit is contained in:
@ -4,6 +4,7 @@ ArduinoJson: change log
|
||||
HEAD
|
||||
----
|
||||
|
||||
* Add `JsonVariant::link()` (issue #1343)
|
||||
* Fix `9.22337e+18 is outside the range of representable values of type 'long'`
|
||||
|
||||
v6.19.4 (2022-04-05)
|
||||
|
@ -43,5 +43,13 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -245,3 +245,11 @@ TEST_CASE("ElementProxy cast to JsonVariant") {
|
||||
|
||||
CHECK(doc.as<std::string>() == "[\"toto\"]");
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::link()") {
|
||||
StaticJsonDocument<1024> doc1, doc2;
|
||||
doc1[0].link(doc2);
|
||||
doc2["hello"] = "world";
|
||||
|
||||
CHECK(doc1.as<std::string>() == "[{\"hello\":\"world\"}]");
|
||||
}
|
||||
|
@ -318,3 +318,10 @@ TEST_CASE("MemberProxy::createNestedObject(key)") {
|
||||
CHECK(doc["status"]["weather"]["temp"] == 42);
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::link()") {
|
||||
StaticJsonDocument<1024> doc1, doc2;
|
||||
doc1["obj"].link(doc2);
|
||||
doc2["hello"] = "world";
|
||||
|
||||
CHECK(doc1.as<std::string>() == "{\"obj\":{\"hello\":\"world\"}}");
|
||||
}
|
||||
|
@ -25,4 +25,21 @@ 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,6 +13,7 @@ add_executable(JsonVariantTests
|
||||
createNested.cpp
|
||||
is.cpp
|
||||
isnull.cpp
|
||||
link.cpp
|
||||
memoryUsage.cpp
|
||||
misc.cpp
|
||||
nesting.cpp
|
||||
|
@ -43,4 +43,14 @@ 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,4 +267,97 @@ 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,4 +23,15 @@ 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,6 +34,20 @@ 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") {
|
||||
@ -313,4 +327,19 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -12,19 +12,28 @@ TEST_CASE("JsonVariant::containsKey()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
JsonVariant var = doc.to<JsonVariant>();
|
||||
|
||||
SECTION("containsKey(const char*) returns true") {
|
||||
SECTION("containsKey(const char*)") {
|
||||
var["hello"] = "world";
|
||||
|
||||
REQUIRE(var.containsKey("hello") == true);
|
||||
REQUIRE(var.containsKey("world") == false);
|
||||
}
|
||||
|
||||
SECTION("containsKey(std::string) returns true") {
|
||||
SECTION("containsKey(std::string)") {
|
||||
var["hello"] = "world";
|
||||
|
||||
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,6 +84,16 @@ 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,6 +18,17 @@ 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()") {
|
||||
@ -30,6 +41,17 @@ 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)") {
|
||||
@ -43,6 +65,17 @@ 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)") {
|
||||
@ -55,4 +88,15 @@ 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,6 +144,24 @@ 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>();
|
||||
|
||||
@ -161,6 +179,44 @@ 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>()") {
|
||||
@ -316,4 +372,58 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -9,17 +9,17 @@ TEST_CASE("JsonVariant::isNull()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
JsonVariant variant = doc.to<JsonVariant>();
|
||||
|
||||
SECTION("return true when Undefined") {
|
||||
SECTION("returns true when Undefined") {
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("return false when Integer") {
|
||||
SECTION("returns false when Integer") {
|
||||
variant.set(42);
|
||||
|
||||
REQUIRE(variant.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("return false when EmptyArray") {
|
||||
SECTION("returns false when EmptyArray") {
|
||||
DynamicJsonDocument doc2(4096);
|
||||
JsonArray array = doc2.to<JsonArray>();
|
||||
|
||||
@ -27,7 +27,7 @@ TEST_CASE("JsonVariant::isNull()") {
|
||||
REQUIRE(variant.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("return false when EmptyObject") {
|
||||
SECTION("returns false when EmptyObject") {
|
||||
DynamicJsonDocument doc2(4096);
|
||||
JsonObject obj = doc2.to<JsonObject>();
|
||||
|
||||
@ -35,41 +35,54 @@ TEST_CASE("JsonVariant::isNull()") {
|
||||
REQUIRE(variant.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("return true after set(JsonArray())") {
|
||||
SECTION("returns true after set(JsonArray())") {
|
||||
variant.set(JsonArray());
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("return true after set(JsonObject())") {
|
||||
SECTION("returns true after set(JsonObject())") {
|
||||
variant.set(JsonObject());
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("return false after set('hello')") {
|
||||
SECTION("returns false after set('hello')") {
|
||||
variant.set("hello");
|
||||
REQUIRE(variant.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("return true after set((char*)0)") {
|
||||
SECTION("returns true after set((char*)0)") {
|
||||
variant.set(static_cast<char*>(0));
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("return true after set((const char*)0)") {
|
||||
SECTION("returns true after set((const char*)0)") {
|
||||
variant.set(static_cast<const char*>(0));
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("return true after set(serialized((char*)0))") {
|
||||
SECTION("returns true after set(serialized((char*)0))") {
|
||||
variant.set(serialized(static_cast<char*>(0)));
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("return true after set(serialized((const char*)0))") {
|
||||
SECTION("returns true after set(serialized((const char*)0))") {
|
||||
variant.set(serialized(static_cast<const char*>(0)));
|
||||
REQUIRE(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("returns true for a linked null") {
|
||||
StaticJsonDocument<128> doc2;
|
||||
variant.link(doc2);
|
||||
CHECK(variant.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("returns false for a linked array") {
|
||||
StaticJsonDocument<128> doc2;
|
||||
doc2[0] = 42;
|
||||
variant.link(doc2);
|
||||
CHECK(variant.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("works with JsonVariantConst") {
|
||||
variant.set(42);
|
||||
|
||||
|
77
extras/tests/JsonVariant/link.cpp
Normal file
77
extras/tests/JsonVariant/link.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonVariant::link()") {
|
||||
StaticJsonDocument<1024> doc1, doc2;
|
||||
JsonVariant variant = doc1.to<JsonVariant>();
|
||||
|
||||
SECTION("JsonVariant::link(JsonDocument&)") {
|
||||
doc2["hello"] = "world";
|
||||
|
||||
variant.link(doc2);
|
||||
|
||||
CHECK(variant.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
CHECK(variant.memoryUsage() == 0);
|
||||
|
||||
// altering the linked document should change the result
|
||||
doc2["hello"] = "WORLD!";
|
||||
|
||||
CHECK(variant.as<std::string>() == "{\"hello\":\"WORLD!\"}");
|
||||
}
|
||||
|
||||
SECTION("JsonVariant::link(MemberProxy)") {
|
||||
doc2["obj"]["hello"] = "world";
|
||||
|
||||
variant.link(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!";
|
||||
|
||||
CHECK(variant.as<std::string>() == "{\"hello\":\"WORLD!\"}");
|
||||
}
|
||||
|
||||
SECTION("JsonVariant::link(ElementProxy)") {
|
||||
doc2[0]["hello"] = "world";
|
||||
|
||||
variant.link(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!";
|
||||
|
||||
CHECK(variant.as<std::string>() == "{\"hello\":\"WORLD!\"}");
|
||||
}
|
||||
|
||||
SECTION("target is unbound") {
|
||||
JsonVariant unbound;
|
||||
variant["hello"] = "world";
|
||||
|
||||
variant.link(unbound);
|
||||
|
||||
CHECK(variant.isUnbound() == false);
|
||||
CHECK(variant.isNull() == true);
|
||||
CHECK(variant.memoryUsage() == 0);
|
||||
CHECK(variant.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("variant is unbound") {
|
||||
JsonVariant unbound;
|
||||
doc2["hello"] = "world";
|
||||
|
||||
unbound.link(doc2);
|
||||
|
||||
CHECK(unbound.isUnbound() == true);
|
||||
CHECK(unbound.isNull() == true);
|
||||
CHECK(unbound.memoryUsage() == 0);
|
||||
CHECK(unbound.size() == 0);
|
||||
}
|
||||
}
|
@ -38,4 +38,12 @@ 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,4 +28,12 @@ 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,4 +156,12 @@ 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,4 +39,24 @@ 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\"}");
|
||||
}
|
||||
}
|
||||
|
@ -41,4 +41,13 @@ TEST_CASE("JsonVariant::size()") {
|
||||
|
||||
CHECK(variant.size() == 1);
|
||||
}
|
||||
|
||||
SECTION("linked array") {
|
||||
StaticJsonDocument<1024> doc2;
|
||||
doc2.add(1);
|
||||
doc2.add(2);
|
||||
variant.link(doc2);
|
||||
|
||||
CHECK(variant.size() == 2);
|
||||
}
|
||||
}
|
||||
|
@ -129,6 +129,44 @@ 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[]") {
|
||||
@ -201,4 +239,20 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ struct Converter<ArrayConstRef> {
|
||||
|
||||
static bool checkJson(VariantConstRef src) {
|
||||
const VariantData* data = getData(src);
|
||||
return data && data->isArray();
|
||||
return data && data->resolve()->isArray();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -109,6 +109,10 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
return getOrAddUpstreamElement().template to<T>();
|
||||
}
|
||||
|
||||
FORCE_INLINE void link(VariantConstRef value) const {
|
||||
getOrAddUpstreamElement().link(value);
|
||||
}
|
||||
|
||||
// Replaces the value
|
||||
//
|
||||
// bool set(const TValue&)
|
||||
|
@ -68,7 +68,7 @@ class JsonDocument : public Visitable,
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return _data.size();
|
||||
return _data.resolve()->size();
|
||||
}
|
||||
|
||||
bool set(const JsonDocument& src) {
|
||||
|
@ -25,7 +25,7 @@ class JsonSerializer : public Visitor<size_t> {
|
||||
VariantSlot *slot = array.head();
|
||||
|
||||
while (slot != 0) {
|
||||
slot->data()->accept(*this);
|
||||
slot->data()->resolve()->accept(*this);
|
||||
|
||||
slot = slot->next();
|
||||
if (slot == 0)
|
||||
@ -46,7 +46,7 @@ class JsonSerializer : public Visitor<size_t> {
|
||||
while (slot != 0) {
|
||||
_formatter.writeString(slot->key());
|
||||
write(':');
|
||||
slot->data()->accept(*this);
|
||||
slot->data()->resolve()->accept(*this);
|
||||
|
||||
slot = slot->next();
|
||||
if (slot == 0)
|
||||
|
@ -25,7 +25,7 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
||||
_nesting++;
|
||||
while (slot != 0) {
|
||||
indent();
|
||||
slot->data()->accept(*this);
|
||||
slot->data()->resolve()->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()->accept(*this);
|
||||
slot->data()->resolve()->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 (VariantSlot* slot = array.head(); slot; slot = slot->next()) {
|
||||
slot->data()->accept(*this);
|
||||
slot->data()->resolve()->accept(*this);
|
||||
}
|
||||
return bytesWritten();
|
||||
}
|
||||
@ -74,7 +74,7 @@ class MsgPackSerializer : public Visitor<size_t> {
|
||||
}
|
||||
for (VariantSlot* slot = object.head(); slot; slot = slot->next()) {
|
||||
visitString(slot->key());
|
||||
slot->data()->accept(*this);
|
||||
slot->data()->resolve()->accept(*this);
|
||||
}
|
||||
return bytesWritten();
|
||||
}
|
||||
|
@ -135,6 +135,10 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
||||
getUpstreamMember().remove(key);
|
||||
}
|
||||
|
||||
FORCE_INLINE void link(VariantConstRef value) {
|
||||
getOrAddUpstreamMember().link(value);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename VariantTo<TValue>::type to() {
|
||||
return getOrAddUpstreamMember().template to<TValue>();
|
||||
|
@ -278,7 +278,7 @@ struct Converter<ObjectConstRef> {
|
||||
|
||||
static bool checkJson(VariantConstRef src) {
|
||||
const VariantData* data = getData(src);
|
||||
return data && data->isObject();
|
||||
return data && data->resolve()->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->asIntegral<T>() : T();
|
||||
return data ? data->resolve()->asIntegral<T>() : T();
|
||||
}
|
||||
|
||||
static bool checkJson(VariantConstRef src) {
|
||||
const VariantData* data = getData(src);
|
||||
return data && data->isInteger<T>();
|
||||
return data && data->resolve()->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->asIntegral<int>()) : T();
|
||||
return data ? static_cast<T>(data->resolve()->asIntegral<int>()) : T();
|
||||
}
|
||||
|
||||
static bool checkJson(VariantConstRef src) {
|
||||
const VariantData* data = getData(src);
|
||||
return data && data->isInteger<int>();
|
||||
return data && data->resolve()->isInteger<int>();
|
||||
}
|
||||
};
|
||||
|
||||
@ -84,12 +84,12 @@ struct Converter<bool> {
|
||||
|
||||
static bool fromJson(VariantConstRef src) {
|
||||
const VariantData* data = getData(src);
|
||||
return data ? data->asBoolean() : false;
|
||||
return data ? data->resolve()->asBoolean() : false;
|
||||
}
|
||||
|
||||
static bool checkJson(VariantConstRef src) {
|
||||
const VariantData* data = getData(src);
|
||||
return data && data->isBoolean();
|
||||
return data && data->resolve()->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->asFloat<T>() : false;
|
||||
return data ? data->resolve()->asFloat<T>() : 0;
|
||||
}
|
||||
|
||||
static bool checkJson(VariantConstRef src) {
|
||||
const VariantData* data = getData(src);
|
||||
return data && data->isFloat();
|
||||
return data && data->resolve()->isFloat();
|
||||
}
|
||||
};
|
||||
|
||||
@ -121,12 +121,12 @@ struct Converter<const char*> {
|
||||
|
||||
static const char* fromJson(VariantConstRef src) {
|
||||
const VariantData* data = getData(src);
|
||||
return data ? data->asString().c_str() : 0;
|
||||
return data ? data->resolve()->asString().c_str() : 0;
|
||||
}
|
||||
|
||||
static bool checkJson(VariantConstRef src) {
|
||||
const VariantData* data = getData(src);
|
||||
return data && data->isString();
|
||||
return data && data->resolve()->isString();
|
||||
}
|
||||
};
|
||||
|
||||
@ -139,12 +139,12 @@ struct Converter<String> {
|
||||
|
||||
static String fromJson(VariantConstRef src) {
|
||||
const VariantData* data = getData(src);
|
||||
return data ? data->asString() : 0;
|
||||
return data ? data->resolve()->asString() : 0;
|
||||
}
|
||||
|
||||
static bool checkJson(VariantConstRef src) {
|
||||
const VariantData* data = getData(src);
|
||||
return data && data->isString();
|
||||
return data && data->resolve()->isString();
|
||||
}
|
||||
};
|
||||
|
||||
@ -192,7 +192,7 @@ struct Converter<decltype(nullptr)> {
|
||||
}
|
||||
static bool checkJson(VariantConstRef src) {
|
||||
const VariantData* data = getData(src);
|
||||
return data == 0 || data->isNull();
|
||||
return data == 0 || data->resolve()->isNull();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,8 @@ 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,
|
||||
@ -49,6 +51,7 @@ union VariantContent {
|
||||
UInt asUnsignedInteger;
|
||||
Integer asSignedInteger;
|
||||
CollectionData asCollection;
|
||||
const class VariantData *asPointer;
|
||||
struct {
|
||||
const char *data;
|
||||
size_t size;
|
||||
|
@ -83,6 +83,12 @@ class VariantData {
|
||||
|
||||
bool asBoolean() const;
|
||||
|
||||
const VariantData *resolve() const {
|
||||
if (isPointer())
|
||||
return _content.asPointer->resolve();
|
||||
return this;
|
||||
}
|
||||
|
||||
CollectionData *asArray() {
|
||||
return isArray() ? &_content.asCollection : 0;
|
||||
}
|
||||
@ -117,6 +123,10 @@ class VariantData {
|
||||
return (_flags & COLLECTION_MASK) != 0;
|
||||
}
|
||||
|
||||
bool isPointer() const {
|
||||
return type() == VALUE_IS_POINTER;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool isInteger() const {
|
||||
switch (type()) {
|
||||
@ -212,6 +222,12 @@ 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())
|
||||
@ -262,7 +278,8 @@ class VariantData {
|
||||
}
|
||||
|
||||
VariantData *getElement(size_t index) const {
|
||||
return isArray() ? _content.asCollection.getElement(index) : 0;
|
||||
const CollectionData *col = asArray();
|
||||
return col ? col->getElement(index) : 0;
|
||||
}
|
||||
|
||||
VariantData *getOrAddElement(size_t index, MemoryPool *pool) {
|
||||
@ -275,7 +292,8 @@ class VariantData {
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData *getMember(TAdaptedString key) const {
|
||||
return isObject() ? _content.asCollection.getMember(key) : 0;
|
||||
const CollectionData *col = asObject();
|
||||
return col ? col->getMember(key) : 0;
|
||||
}
|
||||
|
||||
template <typename TAdaptedString, typename TStoragePolicy>
|
||||
|
@ -15,17 +15,17 @@ template <typename TVisitor>
|
||||
inline typename TVisitor::result_type variantAccept(const VariantData *var,
|
||||
TVisitor &visitor) {
|
||||
if (var != 0)
|
||||
return var->accept(visitor);
|
||||
return var->resolve()->accept(visitor);
|
||||
else
|
||||
return visitor.visitNull();
|
||||
}
|
||||
|
||||
inline const CollectionData *variantAsArray(const VariantData *var) {
|
||||
return var != 0 ? var->asArray() : 0;
|
||||
return var != 0 ? var->resolve()->asArray() : 0;
|
||||
}
|
||||
|
||||
inline const CollectionData *variantAsObject(const VariantData *var) {
|
||||
return var != 0 ? var->asObject() : 0;
|
||||
return var != 0 ? var->resolve()->asObject() : 0;
|
||||
}
|
||||
|
||||
inline CollectionData *variantAsObject(VariantData *var) {
|
||||
@ -56,7 +56,7 @@ inline bool variantSetString(VariantData *var, TAdaptedString value,
|
||||
}
|
||||
|
||||
inline size_t variantSize(const VariantData *var) {
|
||||
return var != 0 ? var->size() : 0;
|
||||
return var != 0 ? var->resolve()->size() : 0;
|
||||
}
|
||||
|
||||
inline CollectionData *variantToArray(VariantData *var) {
|
||||
@ -102,14 +102,14 @@ NO_INLINE VariantData *variantGetOrAddMember(VariantData *var,
|
||||
}
|
||||
|
||||
inline bool variantIsNull(const VariantData *var) {
|
||||
return var == 0 || var->isNull();
|
||||
return var == 0 || var->resolve()->isNull();
|
||||
}
|
||||
|
||||
inline size_t variantNesting(const VariantData *var) {
|
||||
if (!var)
|
||||
return 0;
|
||||
|
||||
const CollectionData *collection = var->asCollection();
|
||||
const CollectionData *collection = var->resolve()->asCollection();
|
||||
if (!collection)
|
||||
return 0;
|
||||
|
||||
|
@ -124,7 +124,8 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef getElementConst(size_t index) const {
|
||||
return VariantConstRef(_data != 0 ? _data->getElement(index) : 0);
|
||||
return VariantConstRef(_data != 0 ? _data->resolve()->getElement(index)
|
||||
: 0);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef operator[](size_t index) const {
|
||||
@ -135,8 +136,8 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
|
||||
// getMemberConst(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantConstRef getMemberConst(const TString &key) const {
|
||||
return VariantConstRef(
|
||||
objectGetMember(variantAsObject(_data), adaptString(key)));
|
||||
return VariantConstRef(_data ? _data->resolve()->getMember(adaptString(key))
|
||||
: 0);
|
||||
}
|
||||
|
||||
// getMemberConst(char*) const
|
||||
@ -144,8 +145,8 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
|
||||
// getMemberConst(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantConstRef getMemberConst(TChar *key) const {
|
||||
const CollectionData *obj = variantAsObject(_data);
|
||||
return VariantConstRef(obj ? obj->getMember(adaptString(key)) : 0);
|
||||
return VariantConstRef(_data ? _data->resolve()->getMember(adaptString(key))
|
||||
: 0);
|
||||
}
|
||||
|
||||
// operator[](const std::string&) const
|
||||
@ -293,7 +294,8 @@ class VariantRef : public VariantRefBase<VariantData>,
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef getElementConst(size_t index) const {
|
||||
return VariantConstRef(_data != 0 ? _data->getElement(index) : 0);
|
||||
return VariantConstRef(_data != 0 ? _data->resolve()->getElement(index)
|
||||
: 0);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
|
||||
@ -321,7 +323,8 @@ class VariantRef : public VariantRefBase<VariantData>,
|
||||
// getMemberConst(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantConstRef getMemberConst(TChar *key) const {
|
||||
return VariantConstRef(_data ? _data->getMember(adaptString(key)) : 0);
|
||||
return VariantConstRef(_data ? _data->resolve()->getMember(adaptString(key))
|
||||
: 0);
|
||||
}
|
||||
|
||||
// getMemberConst(const std::string&) const
|
||||
@ -330,7 +333,8 @@ class VariantRef : public VariantRefBase<VariantData>,
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
||||
getMemberConst(const TString &key) const {
|
||||
return VariantConstRef(_data ? _data->getMember(adaptString(key)) : 0);
|
||||
return VariantConstRef(_data ? _data->resolve()->getMember(adaptString(key))
|
||||
: 0);
|
||||
}
|
||||
|
||||
// getOrAddMember(char*) const
|
||||
@ -370,6 +374,16 @@ class VariantRef : public VariantRefBase<VariantData>,
|
||||
_data->remove(adaptString(key));
|
||||
}
|
||||
|
||||
inline void link(VariantConstRef target) {
|
||||
if (!_data)
|
||||
return;
|
||||
const VariantData *targetData = getData(target);
|
||||
if (targetData)
|
||||
_data->setPointer(targetData);
|
||||
else
|
||||
_data->setNull();
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool *_pool;
|
||||
|
||||
|
Reference in New Issue
Block a user