mirror of
https://github.com/eledio-devices/thirdparty-ArduinoJson.git
synced 2025-11-01 16:14:05 +01:00
Add JsonVariant::link()
This commit is contained in:
@@ -245,3 +245,11 @@ TEST_CASE("ElementProxy cast to JsonVariant") {
|
|||||||
|
|
||||||
CHECK(doc.as<std::string>() == "[\"toto\"]");
|
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\"}]");
|
||||||
|
}
|
||||||
|
|||||||
@@ -285,3 +285,43 @@ TEST_CASE("MemberProxy cast to JsonVariant") {
|
|||||||
|
|
||||||
CHECK(doc.as<std::string>() == "{\"hello\":\"toto\"}");
|
CHECK(doc.as<std::string>() == "{\"hello\":\"toto\"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("MemberProxy::createNestedArray()") {
|
||||||
|
StaticJsonDocument<1024> doc;
|
||||||
|
JsonArray arr = doc["items"].createNestedArray();
|
||||||
|
arr.add(42);
|
||||||
|
|
||||||
|
CHECK(doc["items"][0][0] == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("MemberProxy::createNestedArray(key)") {
|
||||||
|
StaticJsonDocument<1024> doc;
|
||||||
|
JsonArray arr = doc["weather"].createNestedArray("temp");
|
||||||
|
arr.add(42);
|
||||||
|
|
||||||
|
CHECK(doc["weather"]["temp"][0] == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("MemberProxy::createNestedObject()") {
|
||||||
|
StaticJsonDocument<1024> doc;
|
||||||
|
JsonObject obj = doc["items"].createNestedObject();
|
||||||
|
obj["value"] = 42;
|
||||||
|
|
||||||
|
CHECK(doc["items"][0]["value"] == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("MemberProxy::createNestedObject(key)") {
|
||||||
|
StaticJsonDocument<1024> doc;
|
||||||
|
JsonObject obj = doc["status"].createNestedObject("weather");
|
||||||
|
obj["temp"] = 42;
|
||||||
|
|
||||||
|
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\"}}");
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ add_executable(JsonVariantTests
|
|||||||
clear.cpp
|
clear.cpp
|
||||||
compare.cpp
|
compare.cpp
|
||||||
containsKey.cpp
|
containsKey.cpp
|
||||||
copy.cpp
|
|
||||||
converters.cpp
|
converters.cpp
|
||||||
|
copy.cpp
|
||||||
createNested.cpp
|
createNested.cpp
|
||||||
is.cpp
|
is.cpp
|
||||||
isnull.cpp
|
isnull.cpp
|
||||||
|
link.cpp
|
||||||
memoryUsage.cpp
|
memoryUsage.cpp
|
||||||
misc.cpp
|
misc.cpp
|
||||||
nesting.cpp
|
nesting.cpp
|
||||||
@@ -20,6 +21,7 @@ add_executable(JsonVariantTests
|
|||||||
overflow.cpp
|
overflow.cpp
|
||||||
remove.cpp
|
remove.cpp
|
||||||
set.cpp
|
set.cpp
|
||||||
|
size.cpp
|
||||||
subscript.cpp
|
subscript.cpp
|
||||||
types.cpp
|
types.cpp
|
||||||
unbound.cpp
|
unbound.cpp
|
||||||
|
|||||||
@@ -43,4 +43,14 @@ TEST_CASE("JsonVariant::add()") {
|
|||||||
|
|
||||||
REQUIRE(var.as<std::string>() == "{\"val\":123}");
|
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);
|
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);
|
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);
|
||||||
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") {
|
TEST_CASE("Compare JsonVariant with JsonVariant") {
|
||||||
@@ -313,4 +327,19 @@ TEST_CASE("Compare JsonVariant with JsonVariant") {
|
|||||||
CHECK_FALSE(a > b);
|
CHECK_FALSE(a > b);
|
||||||
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);
|
DynamicJsonDocument doc(4096);
|
||||||
JsonVariant var = doc.to<JsonVariant>();
|
JsonVariant var = doc.to<JsonVariant>();
|
||||||
|
|
||||||
SECTION("containsKey(const char*) returns true") {
|
SECTION("containsKey(const char*)") {
|
||||||
var["hello"] = "world";
|
var["hello"] = "world";
|
||||||
|
|
||||||
REQUIRE(var.containsKey("hello") == true);
|
REQUIRE(var.containsKey("hello") == true);
|
||||||
REQUIRE(var.containsKey("world") == false);
|
REQUIRE(var.containsKey("world") == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("containsKey(std::string) returns true") {
|
SECTION("containsKey(std::string)") {
|
||||||
var["hello"] = "world";
|
var["hello"] = "world";
|
||||||
|
|
||||||
REQUIRE(var.containsKey(std::string("hello")) == true);
|
REQUIRE(var.containsKey(std::string("hello")) == true);
|
||||||
REQUIRE(var.containsKey(std::string("world")) == false);
|
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()") {
|
TEST_CASE("JsonVariantConst::containsKey()") {
|
||||||
|
|||||||
@@ -84,6 +84,16 @@ TEST_CASE("JsonVariant::set(JsonVariant)") {
|
|||||||
REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7));
|
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") {
|
SECTION("destination is unbound") {
|
||||||
JsonVariant unboundVariant;
|
JsonVariant unboundVariant;
|
||||||
|
|
||||||
|
|||||||
@@ -19,11 +19,15 @@ TEST_CASE("JsonVariant::createNestedObject()") {
|
|||||||
REQUIRE(obj.isNull() == false);
|
REQUIRE(obj.isNull() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("works on MemberProxy") {
|
SECTION("does nothing on linked array") {
|
||||||
JsonObject obj = variant["items"].createNestedObject();
|
StaticJsonDocument<128> doc2;
|
||||||
obj["value"] = 42;
|
doc2[0] = 42;
|
||||||
|
variant.link(doc2);
|
||||||
|
|
||||||
REQUIRE(variant["items"][0]["value"] == 42);
|
variant.createNestedObject();
|
||||||
|
|
||||||
|
CHECK(variant.size() == 1);
|
||||||
|
CHECK(variant[0] == 42);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,11 +42,15 @@ TEST_CASE("JsonVariant::createNestedArray()") {
|
|||||||
REQUIRE(arr.isNull() == false);
|
REQUIRE(arr.isNull() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("works on MemberProxy") {
|
SECTION("does nothing on linked array") {
|
||||||
JsonArray arr = variant["items"].createNestedArray();
|
StaticJsonDocument<128> doc2;
|
||||||
arr.add(42);
|
doc2[0] = 42;
|
||||||
|
variant.link(doc2);
|
||||||
|
|
||||||
REQUIRE(variant["items"][0][0] == 42);
|
variant.createNestedArray();
|
||||||
|
|
||||||
|
CHECK(variant.size() == 1);
|
||||||
|
CHECK(variant[0] == 42);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,11 +66,15 @@ TEST_CASE("JsonVariant::createNestedObject(key)") {
|
|||||||
REQUIRE(variant["weather"]["temp"] == 42);
|
REQUIRE(variant["weather"]["temp"] == 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("works on MemberProxy") {
|
SECTION("does nothing on linked object") {
|
||||||
JsonObject obj = variant["status"].createNestedObject("weather");
|
StaticJsonDocument<128> doc2;
|
||||||
obj["temp"] = 42;
|
doc2["hello"] = "world";
|
||||||
|
variant.link(doc2);
|
||||||
|
|
||||||
REQUIRE(variant["status"]["weather"]["temp"] == 42);
|
variant.createNestedObject("weather");
|
||||||
|
|
||||||
|
CHECK(variant.size() == 1);
|
||||||
|
CHECK(variant["hello"] == "world");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,10 +89,14 @@ TEST_CASE("JsonVariant::createNestedArray(key)") {
|
|||||||
REQUIRE(arr.isNull() == false);
|
REQUIRE(arr.isNull() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("works on MemberProxy") {
|
SECTION("does nothing on linked object") {
|
||||||
JsonArray arr = variant["weather"].createNestedArray("temp");
|
StaticJsonDocument<128> doc2;
|
||||||
arr.add(42);
|
doc2["hello"] = "world";
|
||||||
|
variant.link(doc2);
|
||||||
|
|
||||||
REQUIRE(variant["weather"]["temp"][0] == 42);
|
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);
|
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") {
|
SECTION("JsonObject") {
|
||||||
variant.to<JsonObject>();
|
variant.to<JsonObject>();
|
||||||
|
|
||||||
@@ -161,6 +179,44 @@ TEST_CASE("JsonVariant::is<T>()") {
|
|||||||
CHECK(variant.is<JsonVariant>() == true);
|
CHECK(variant.is<JsonVariant>() == true);
|
||||||
CHECK(variant.is<JsonVariantConst>() == 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>() == false);
|
||||||
|
CHECK(variant.is<bool>() == false);
|
||||||
|
CHECK(variant.is<const char *>() == false);
|
||||||
|
CHECK(variant.is<MYENUM2>() == true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("JsonVariantConst::is<T>()") {
|
TEST_CASE("JsonVariantConst::is<T>()") {
|
||||||
@@ -316,4 +372,58 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
|||||||
CHECK(cvariant.is<const char *>() == false);
|
CHECK(cvariant.is<const char *>() == false);
|
||||||
CHECK(cvariant.is<MYENUM2>() == 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>() == false);
|
||||||
|
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);
|
DynamicJsonDocument doc(4096);
|
||||||
JsonVariant variant = doc.to<JsonVariant>();
|
JsonVariant variant = doc.to<JsonVariant>();
|
||||||
|
|
||||||
SECTION("return true when Undefined") {
|
SECTION("returns true when Undefined") {
|
||||||
REQUIRE(variant.isNull() == true);
|
REQUIRE(variant.isNull() == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("return false when Integer") {
|
SECTION("returns false when Integer") {
|
||||||
variant.set(42);
|
variant.set(42);
|
||||||
|
|
||||||
REQUIRE(variant.isNull() == false);
|
REQUIRE(variant.isNull() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("return false when EmptyArray") {
|
SECTION("returns false when EmptyArray") {
|
||||||
DynamicJsonDocument doc2(4096);
|
DynamicJsonDocument doc2(4096);
|
||||||
JsonArray array = doc2.to<JsonArray>();
|
JsonArray array = doc2.to<JsonArray>();
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ TEST_CASE("JsonVariant::isNull()") {
|
|||||||
REQUIRE(variant.isNull() == false);
|
REQUIRE(variant.isNull() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("return false when EmptyObject") {
|
SECTION("returns false when EmptyObject") {
|
||||||
DynamicJsonDocument doc2(4096);
|
DynamicJsonDocument doc2(4096);
|
||||||
JsonObject obj = doc2.to<JsonObject>();
|
JsonObject obj = doc2.to<JsonObject>();
|
||||||
|
|
||||||
@@ -35,41 +35,54 @@ TEST_CASE("JsonVariant::isNull()") {
|
|||||||
REQUIRE(variant.isNull() == false);
|
REQUIRE(variant.isNull() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("return true after set(JsonArray())") {
|
SECTION("returns true after set(JsonArray())") {
|
||||||
variant.set(JsonArray());
|
variant.set(JsonArray());
|
||||||
REQUIRE(variant.isNull() == true);
|
REQUIRE(variant.isNull() == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("return true after set(JsonObject())") {
|
SECTION("returns true after set(JsonObject())") {
|
||||||
variant.set(JsonObject());
|
variant.set(JsonObject());
|
||||||
REQUIRE(variant.isNull() == true);
|
REQUIRE(variant.isNull() == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("return false after set('hello')") {
|
SECTION("returns false after set('hello')") {
|
||||||
variant.set("hello");
|
variant.set("hello");
|
||||||
REQUIRE(variant.isNull() == false);
|
REQUIRE(variant.isNull() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("return true after set((char*)0)") {
|
SECTION("returns true after set((char*)0)") {
|
||||||
variant.set(static_cast<char*>(0));
|
variant.set(static_cast<char*>(0));
|
||||||
REQUIRE(variant.isNull() == true);
|
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));
|
variant.set(static_cast<const char*>(0));
|
||||||
REQUIRE(variant.isNull() == true);
|
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)));
|
variant.set(serialized(static_cast<char*>(0)));
|
||||||
REQUIRE(variant.isNull() == true);
|
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)));
|
variant.set(serialized(static_cast<const char*>(0)));
|
||||||
REQUIRE(variant.isNull() == true);
|
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") {
|
SECTION("works with JsonVariantConst") {
|
||||||
variant.set(42);
|
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() == 6);
|
||||||
REQUIRE(var.memoryUsage() == doc.memoryUsage());
|
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>();
|
var.to<JsonArray>();
|
||||||
REQUIRE(var.nesting() == 1);
|
REQUIRE(var.nesting() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("return 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;
|
int result = variant | 42;
|
||||||
REQUIRE(result == 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}");
|
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\"}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,18 +155,21 @@ TEST_CASE("JsonVariant::set() with not enough memory") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("JsonVariant::set(DynamicJsonDocument)") {
|
TEST_CASE("Copy/link from other document") {
|
||||||
DynamicJsonDocument doc1(1024);
|
StaticJsonDocument<1024> doc1, doc2;
|
||||||
doc1["hello"] = "world";
|
JsonVariant variant = doc1.to<JsonVariant>();
|
||||||
|
|
||||||
DynamicJsonDocument doc2(1024);
|
SECTION("JsonVariant::set(JsonDocument&)") {
|
||||||
JsonVariant v = doc2.to<JsonVariant>();
|
doc2["hello"] = "world";
|
||||||
|
|
||||||
// Should copy the doc
|
variant.set(doc2);
|
||||||
v.set(doc1);
|
|
||||||
doc1.clear();
|
|
||||||
|
|
||||||
std::string json;
|
CHECK(variant.as<std::string>() == "{\"hello\":\"world\"}");
|
||||||
serializeJson(doc2, json);
|
CHECK(variant.memoryUsage() == JSON_OBJECT_SIZE(1));
|
||||||
REQUIRE(json == "{\"hello\":\"world\"}");
|
|
||||||
|
// altering the copied document should change the result
|
||||||
|
doc2["hello"] = "WORLD!";
|
||||||
|
|
||||||
|
CHECK(variant.as<std::string>() == "{\"hello\":\"world\"}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
53
extras/tests/JsonVariant/size.cpp
Normal file
53
extras/tests/JsonVariant/size.cpp
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright © 2014-2022, Benoit BLANCHON
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("JsonVariant::size()") {
|
||||||
|
DynamicJsonDocument doc(4096);
|
||||||
|
JsonVariant variant = doc.to<JsonVariant>();
|
||||||
|
|
||||||
|
SECTION("unbound reference") {
|
||||||
|
JsonVariant unbound;
|
||||||
|
|
||||||
|
CHECK(unbound.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("int") {
|
||||||
|
variant.set(42);
|
||||||
|
|
||||||
|
CHECK(variant.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("string") {
|
||||||
|
variant.set("hello");
|
||||||
|
|
||||||
|
CHECK(variant.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("object") {
|
||||||
|
variant["a"] = 1;
|
||||||
|
variant["b"] = 2;
|
||||||
|
|
||||||
|
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,6 +129,44 @@ TEST_CASE("JsonVariant::operator[]") {
|
|||||||
REQUIRE(std::string("world") == variant[vla]);
|
REQUIRE(std::string("world") == variant[vla]);
|
||||||
}
|
}
|
||||||
#endif
|
#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[]") {
|
TEST_CASE("JsonVariantConst::operator[]") {
|
||||||
@@ -201,4 +239,20 @@ TEST_CASE("JsonVariantConst::operator[]") {
|
|||||||
REQUIRE(var.is<JsonObject>() == false);
|
REQUIRE(var.is<JsonObject>() == false);
|
||||||
REQUIRE(value == 0);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ struct Converter<ArrayRef> {
|
|||||||
|
|
||||||
static bool checkJson(VariantRef src) {
|
static bool checkJson(VariantRef src) {
|
||||||
VariantData* data = getData(src);
|
VariantData* data = getData(src);
|
||||||
return data && data->isArray();
|
return data && data->isArrayStrict();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -92,6 +92,10 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
|||||||
return getOrAddUpstreamElement().template to<T>();
|
return getOrAddUpstreamElement().template to<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE void link(VariantConstRef value) const {
|
||||||
|
getOrAddUpstreamElement().link(value);
|
||||||
|
}
|
||||||
|
|
||||||
// Replaces the value
|
// Replaces the value
|
||||||
//
|
//
|
||||||
// bool set(const TValue&)
|
// bool set(const TValue&)
|
||||||
|
|||||||
@@ -117,6 +117,10 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
|||||||
getUpstreamMember().remove(key);
|
getUpstreamMember().remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE void link(VariantConstRef value) {
|
||||||
|
getOrAddUpstreamMember().link(value);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TValue>
|
template <typename TValue>
|
||||||
FORCE_INLINE typename VariantTo<TValue>::type to() {
|
FORCE_INLINE typename VariantTo<TValue>::type to() {
|
||||||
return getOrAddUpstreamMember().template to<TValue>();
|
return getOrAddUpstreamMember().template to<TValue>();
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ struct Converter<ObjectRef> {
|
|||||||
|
|
||||||
static bool checkJson(VariantRef src) {
|
static bool checkJson(VariantRef src) {
|
||||||
VariantData* data = getData(src);
|
VariantData* data = getData(src);
|
||||||
return data && data->isObject();
|
return data && data->isObjectStrict();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ enum {
|
|||||||
VALUE_IS_SIGNED_INTEGER = 0x0A,
|
VALUE_IS_SIGNED_INTEGER = 0x0A,
|
||||||
VALUE_IS_FLOAT = 0x0C,
|
VALUE_IS_FLOAT = 0x0C,
|
||||||
|
|
||||||
|
VALUE_IS_POINTER = 0x10,
|
||||||
|
|
||||||
COLLECTION_MASK = 0x60,
|
COLLECTION_MASK = 0x60,
|
||||||
VALUE_IS_OBJECT = 0x20,
|
VALUE_IS_OBJECT = 0x20,
|
||||||
VALUE_IS_ARRAY = 0x40,
|
VALUE_IS_ARRAY = 0x40,
|
||||||
@@ -49,6 +51,7 @@ union VariantContent {
|
|||||||
UInt asUnsignedInteger;
|
UInt asUnsignedInteger;
|
||||||
Integer asSignedInteger;
|
Integer asSignedInteger;
|
||||||
CollectionData asCollection;
|
CollectionData asCollection;
|
||||||
|
const class VariantData *asPointer;
|
||||||
struct {
|
struct {
|
||||||
const char *data;
|
const char *data;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ class VariantData {
|
|||||||
case VALUE_IS_BOOLEAN:
|
case VALUE_IS_BOOLEAN:
|
||||||
return visitor.visitBoolean(_content.asBoolean != 0);
|
return visitor.visitBoolean(_content.asBoolean != 0);
|
||||||
|
|
||||||
|
case VALUE_IS_POINTER:
|
||||||
|
ARDUINOJSON_ASSERT(_content.asPointer != 0);
|
||||||
|
return _content.asPointer->accept(visitor);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return visitor.visitNull();
|
return visitor.visitNull();
|
||||||
}
|
}
|
||||||
@@ -84,24 +88,35 @@ class VariantData {
|
|||||||
bool asBoolean() const;
|
bool asBoolean() const;
|
||||||
|
|
||||||
CollectionData *asArray() {
|
CollectionData *asArray() {
|
||||||
return isArray() ? &_content.asCollection : 0;
|
return isArrayStrict() ? &_content.asCollection : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CollectionData *asArray() const {
|
const CollectionData *asArray() const {
|
||||||
|
if (isPointer())
|
||||||
|
return _content.asPointer->asArray();
|
||||||
return const_cast<VariantData *>(this)->asArray();
|
return const_cast<VariantData *>(this)->asArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionData *asObject() {
|
CollectionData *asObject() {
|
||||||
return isObject() ? &_content.asCollection : 0;
|
return isObjectStrict() ? &_content.asCollection : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CollectionData *asObject() const {
|
const CollectionData *asObject() const {
|
||||||
|
if (isPointer())
|
||||||
|
return _content.asPointer->asObject();
|
||||||
return const_cast<VariantData *>(this)->asObject();
|
return const_cast<VariantData *>(this)->asObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool copyFrom(const VariantData &src, MemoryPool *pool);
|
bool copyFrom(const VariantData &src, MemoryPool *pool);
|
||||||
|
|
||||||
bool isArray() const {
|
bool isArray() const {
|
||||||
|
if (isPointer())
|
||||||
|
return _content.asPointer->isArray();
|
||||||
|
else
|
||||||
|
return isArrayStrict();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isArrayStrict() const {
|
||||||
return (_flags & VALUE_IS_ARRAY) != 0;
|
return (_flags & VALUE_IS_ARRAY) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,8 +128,14 @@ class VariantData {
|
|||||||
return (_flags & COLLECTION_MASK) != 0;
|
return (_flags & COLLECTION_MASK) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isPointer() const {
|
||||||
|
return type() == VALUE_IS_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool isInteger() const {
|
bool isInteger() const {
|
||||||
|
if (isPointer())
|
||||||
|
return _content.asPointer->isInteger<T>();
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
case VALUE_IS_UNSIGNED_INTEGER:
|
case VALUE_IS_UNSIGNED_INTEGER:
|
||||||
return canConvertNumber<T>(_content.asUnsignedInteger);
|
return canConvertNumber<T>(_content.asUnsignedInteger);
|
||||||
@@ -136,10 +157,18 @@ class VariantData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isObject() const {
|
bool isObject() const {
|
||||||
|
if (isPointer())
|
||||||
|
return _content.asPointer->isObject();
|
||||||
|
return isObjectStrict();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isObjectStrict() const {
|
||||||
return (_flags & VALUE_IS_OBJECT) != 0;
|
return (_flags & VALUE_IS_OBJECT) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNull() const {
|
bool isNull() const {
|
||||||
|
if (isPointer())
|
||||||
|
return _content.asPointer->isNull();
|
||||||
return type() == VALUE_IS_NULL;
|
return type() == VALUE_IS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,13 +177,13 @@ class VariantData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void remove(size_t index) {
|
void remove(size_t index) {
|
||||||
if (isArray())
|
if (isArrayStrict())
|
||||||
_content.asCollection.removeElement(index);
|
_content.asCollection.removeElement(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
void remove(TAdaptedString key) {
|
void remove(TAdaptedString key) {
|
||||||
if (isObject())
|
if (isObjectStrict())
|
||||||
_content.asCollection.removeMember(key);
|
_content.asCollection.removeMember(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,6 +237,12 @@ class VariantData {
|
|||||||
setType(VALUE_IS_NULL);
|
setType(VALUE_IS_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setPointer(const VariantData *p) {
|
||||||
|
ARDUINOJSON_ASSERT(p);
|
||||||
|
setType(VALUE_IS_POINTER);
|
||||||
|
_content.asPointer = p;
|
||||||
|
}
|
||||||
|
|
||||||
void setString(String s) {
|
void setString(String s) {
|
||||||
ARDUINOJSON_ASSERT(s);
|
ARDUINOJSON_ASSERT(s);
|
||||||
if (s.isLinked())
|
if (s.isLinked())
|
||||||
@@ -246,36 +281,42 @@ class VariantData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t nesting() const {
|
size_t nesting() const {
|
||||||
|
if (isPointer())
|
||||||
|
return _content.asPointer->nesting();
|
||||||
return isCollection() ? _content.asCollection.nesting() : 0;
|
return isCollection() ? _content.asCollection.nesting() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
|
if (isPointer())
|
||||||
|
return _content.asPointer->size();
|
||||||
return isCollection() ? _content.asCollection.size() : 0;
|
return isCollection() ? _content.asCollection.size() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantData *addElement(MemoryPool *pool) {
|
VariantData *addElement(MemoryPool *pool) {
|
||||||
if (isNull())
|
if (isNull())
|
||||||
toArray();
|
toArray();
|
||||||
if (!isArray())
|
if (!isArrayStrict())
|
||||||
return 0;
|
return 0;
|
||||||
return _content.asCollection.addElement(pool);
|
return _content.asCollection.addElement(pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantData *getElement(size_t index) const {
|
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) {
|
VariantData *getOrAddElement(size_t index, MemoryPool *pool) {
|
||||||
if (isNull())
|
if (isNull())
|
||||||
toArray();
|
toArray();
|
||||||
if (!isArray())
|
if (!isArrayStrict())
|
||||||
return 0;
|
return 0;
|
||||||
return _content.asCollection.getOrAddElement(index, pool);
|
return _content.asCollection.getOrAddElement(index, pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
VariantData *getMember(TAdaptedString key) const {
|
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>
|
template <typename TAdaptedString, typename TStoragePolicy>
|
||||||
@@ -283,7 +324,7 @@ class VariantData {
|
|||||||
TStoragePolicy storage_policy) {
|
TStoragePolicy storage_policy) {
|
||||||
if (isNull())
|
if (isNull())
|
||||||
toObject();
|
toObject();
|
||||||
if (!isObject())
|
if (!isObjectStrict())
|
||||||
return 0;
|
return 0;
|
||||||
return _content.asCollection.getOrAddMember(key, pool, storage_policy);
|
return _content.asCollection.getOrAddMember(key, pool, storage_policy);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ inline T VariantData::asIntegral() const {
|
|||||||
return parseNumber<T>(_content.asString.data);
|
return parseNumber<T>(_content.asString.data);
|
||||||
case VALUE_IS_FLOAT:
|
case VALUE_IS_FLOAT:
|
||||||
return convertNumber<T>(_content.asFloat);
|
return convertNumber<T>(_content.asFloat);
|
||||||
|
case VALUE_IS_POINTER:
|
||||||
|
return _content.asPointer->asIntegral<T>();
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -45,6 +47,8 @@ inline bool VariantData::asBoolean() const {
|
|||||||
return _content.asFloat != 0;
|
return _content.asFloat != 0;
|
||||||
case VALUE_IS_NULL:
|
case VALUE_IS_NULL:
|
||||||
return false;
|
return false;
|
||||||
|
case VALUE_IS_POINTER:
|
||||||
|
return _content.asPointer->asBoolean();
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -65,6 +69,8 @@ inline T VariantData::asFloat() const {
|
|||||||
return parseNumber<T>(_content.asString.data);
|
return parseNumber<T>(_content.asString.data);
|
||||||
case VALUE_IS_FLOAT:
|
case VALUE_IS_FLOAT:
|
||||||
return static_cast<T>(_content.asFloat);
|
return static_cast<T>(_content.asFloat);
|
||||||
|
case VALUE_IS_POINTER:
|
||||||
|
return _content.asPointer->asFloat<T>();
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -78,6 +84,8 @@ inline String VariantData::asString() const {
|
|||||||
case VALUE_IS_OWNED_STRING:
|
case VALUE_IS_OWNED_STRING:
|
||||||
return String(_content.asString.data, _content.asString.size,
|
return String(_content.asString.data, _content.asString.size,
|
||||||
String::Copied);
|
String::Copied);
|
||||||
|
case VALUE_IS_POINTER:
|
||||||
|
return _content.asPointer->asString();
|
||||||
default:
|
default:
|
||||||
return String();
|
return String();
|
||||||
}
|
}
|
||||||
@@ -181,4 +189,13 @@ bool CopyStringStoragePolicy::store(TAdaptedString str, MemoryPool *pool,
|
|||||||
return copy != 0;
|
return copy != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void VariantRef::link(VariantConstRef target) {
|
||||||
|
if (!_data)
|
||||||
|
return;
|
||||||
|
if (target._data)
|
||||||
|
_data->setPointer(target._data);
|
||||||
|
else
|
||||||
|
_data->setNull();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -198,6 +198,8 @@ class VariantRef : public VariantRefBase<VariantData>,
|
|||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE VariantRef getOrAddMember(const TString &) const;
|
FORCE_INLINE VariantRef getOrAddMember(const TString &) const;
|
||||||
|
|
||||||
|
void link(class VariantConstRef var);
|
||||||
|
|
||||||
FORCE_INLINE void remove(size_t index) const {
|
FORCE_INLINE void remove(size_t index) const {
|
||||||
if (_data)
|
if (_data)
|
||||||
_data->remove(index);
|
_data->remove(index);
|
||||||
|
|||||||
Reference in New Issue
Block a user