mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-18 13:02:25 +02:00
Added support for custom converters (closes #687)
This commit is contained in:
@ -4,6 +4,7 @@ ArduinoJson: change log
|
|||||||
HEAD
|
HEAD
|
||||||
----
|
----
|
||||||
|
|
||||||
|
* Added support for custom converters (issue #687)
|
||||||
* Removed support for `char` values, see below (issue #1498)
|
* Removed support for `char` values, see below (issue #1498)
|
||||||
* `deserializeJson()` leaves `\uXXXX` unchanged instead of returning `NotSupported`
|
* `deserializeJson()` leaves `\uXXXX` unchanged instead of returning `NotSupported`
|
||||||
* `deserializeMsgPack()` inserts `null` instead of returning `NotSupported`
|
* `deserializeMsgPack()` inserts `null` instead of returning `NotSupported`
|
||||||
|
@ -38,6 +38,7 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
|
|||||||
* Supports Arduino's `Stream` and [STL's `std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/?utm_source=github&utm_medium=readme)
|
* Supports Arduino's `Stream` and [STL's `std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/?utm_source=github&utm_medium=readme)
|
||||||
* [Supports Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/?utm_source=github&utm_medium=readme)
|
* [Supports Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/?utm_source=github&utm_medium=readme)
|
||||||
* Supports [custom readers](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme#custom-reader) and [custom writers](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme#custom-writer)
|
* Supports [custom readers](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme#custom-reader) and [custom writers](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme#custom-writer)
|
||||||
|
* Supports custom converters
|
||||||
* Portable
|
* Portable
|
||||||
* Usable on any C++ project (not limited to Arduino)
|
* Usable on any C++ project (not limited to Arduino)
|
||||||
* Compatible with C++98
|
* Compatible with C++98
|
||||||
|
@ -9,6 +9,7 @@ add_executable(JsonVariantTests
|
|||||||
compare.cpp
|
compare.cpp
|
||||||
containsKey.cpp
|
containsKey.cpp
|
||||||
copy.cpp
|
copy.cpp
|
||||||
|
converters.cpp
|
||||||
createNested.cpp
|
createNested.cpp
|
||||||
is.cpp
|
is.cpp
|
||||||
isnull.cpp
|
isnull.cpp
|
||||||
|
144
extras/tests/JsonVariant/converters.cpp
Normal file
144
extras/tests/JsonVariant/converters.cpp
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2021
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct Date {
|
||||||
|
int day;
|
||||||
|
int month;
|
||||||
|
int year;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool convertToJson(JsonVariant variant, const Date& date) {
|
||||||
|
variant["day"] = date.day;
|
||||||
|
variant["month"] = date.month;
|
||||||
|
variant["year"] = date.year;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void convertFromJson(Date& date, JsonVariantConst variant) {
|
||||||
|
date.day = variant["day"];
|
||||||
|
date.month = variant["month"];
|
||||||
|
date.year = variant["year"];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool canConvertFromJson(Date&, JsonVariantConst variant) {
|
||||||
|
return variant["day"].is<int>() && variant["month"].is<int>() &&
|
||||||
|
variant["year"].is<int>();
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST_CASE("Custom converter with overloading") {
|
||||||
|
DynamicJsonDocument doc(4096);
|
||||||
|
|
||||||
|
SECTION("convert JSON to Date") {
|
||||||
|
doc["date"]["day"] = 2;
|
||||||
|
doc["date"]["month"] = 3;
|
||||||
|
doc["date"]["year"] = 2021;
|
||||||
|
|
||||||
|
Date date = doc["date"];
|
||||||
|
|
||||||
|
REQUIRE(date.day == 2);
|
||||||
|
REQUIRE(date.month == 3);
|
||||||
|
REQUIRE(date.year == 2021);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("is<Date>() returns true") {
|
||||||
|
doc["date"]["day"] = 2;
|
||||||
|
doc["date"]["month"] = 3;
|
||||||
|
doc["date"]["year"] = 2021;
|
||||||
|
|
||||||
|
REQUIRE(doc["date"].is<Date>());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("is<Date>() returns false") {
|
||||||
|
doc["date"]["day"] = 2;
|
||||||
|
doc["date"]["month"] = 3;
|
||||||
|
doc["date"]["year"] = "2021";
|
||||||
|
|
||||||
|
REQUIRE(doc["date"].is<Date>() == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("convert Date to JSON") {
|
||||||
|
Date date = {19, 3, 2021};
|
||||||
|
doc["date"] = date;
|
||||||
|
|
||||||
|
REQUIRE(doc["date"]["day"] == 19);
|
||||||
|
REQUIRE(doc["date"]["month"] == 3);
|
||||||
|
REQUIRE(doc["date"]["year"] == 2021);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Complex {
|
||||||
|
public:
|
||||||
|
explicit Complex(double r, double i) : _real(r), _imag(i) {}
|
||||||
|
|
||||||
|
double real() const {
|
||||||
|
return _real;
|
||||||
|
}
|
||||||
|
|
||||||
|
double imag() const {
|
||||||
|
return _imag;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
double _real, _imag;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
template <>
|
||||||
|
struct Converter<Complex> {
|
||||||
|
static bool toJson(VariantRef variant, const Complex& value) {
|
||||||
|
variant["real"] = value.real();
|
||||||
|
variant["imag"] = value.imag();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Complex fromJson(VariantConstRef variant) {
|
||||||
|
return Complex(variant["real"], variant["imag"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantConstRef variant) {
|
||||||
|
return variant["real"].is<double>() && variant["imag"].is<double>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|
||||||
|
TEST_CASE("Custom converter with specialization") {
|
||||||
|
DynamicJsonDocument doc(4096);
|
||||||
|
|
||||||
|
SECTION("convert JSON to Complex") {
|
||||||
|
doc["value"]["real"] = 2;
|
||||||
|
doc["value"]["imag"] = 3;
|
||||||
|
|
||||||
|
Complex value = doc["value"];
|
||||||
|
|
||||||
|
REQUIRE(value.real() == 2);
|
||||||
|
REQUIRE(value.imag() == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("is<Complex>() returns true") {
|
||||||
|
doc["value"]["real"] = 2;
|
||||||
|
doc["value"]["imag"] = 3;
|
||||||
|
|
||||||
|
REQUIRE(doc["value"].is<Complex>());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("is<Complex>() returns false") {
|
||||||
|
doc["value"]["real"] = 2;
|
||||||
|
doc["value"]["imag"] = "3";
|
||||||
|
|
||||||
|
REQUIRE(doc["value"].is<Complex>() == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("convert value to JSON") {
|
||||||
|
doc["value"] = Complex(19, 3);
|
||||||
|
|
||||||
|
REQUIRE(doc["value"]["real"] == 19);
|
||||||
|
REQUIRE(doc["value"]["imag"] == 3);
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
|||||||
CHECK(variant.is<JsonVariant>() == false);
|
CHECK(variant.is<JsonVariant>() == false);
|
||||||
CHECK(variant.is<JsonVariantConst>() == false);
|
CHECK(variant.is<JsonVariantConst>() == false);
|
||||||
CHECK(variant.is<bool>() == false);
|
CHECK(variant.is<bool>() == false);
|
||||||
CHECK(variant.is<char *>() == false);
|
CHECK(variant.is<const char *>() == false);
|
||||||
CHECK(variant.is<int>() == false);
|
CHECK(variant.is<int>() == false);
|
||||||
CHECK(variant.is<std::string>() == false);
|
CHECK(variant.is<std::string>() == false);
|
||||||
CHECK(variant.is<float>() == false);
|
CHECK(variant.is<float>() == false);
|
||||||
@ -32,7 +32,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
|||||||
CHECK(variant.is<JsonObject>() == false);
|
CHECK(variant.is<JsonObject>() == false);
|
||||||
CHECK(variant.is<JsonArray>() == false);
|
CHECK(variant.is<JsonArray>() == false);
|
||||||
CHECK(variant.is<bool>() == false);
|
CHECK(variant.is<bool>() == false);
|
||||||
CHECK(variant.is<char *>() == false);
|
CHECK(variant.is<const char *>() == false);
|
||||||
CHECK(variant.is<int>() == false);
|
CHECK(variant.is<int>() == false);
|
||||||
CHECK(variant.is<std::string>() == false);
|
CHECK(variant.is<std::string>() == false);
|
||||||
CHECK(variant.is<float>() == false);
|
CHECK(variant.is<float>() == false);
|
||||||
@ -47,7 +47,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
|||||||
CHECK(variant.is<JsonVariantConst>() == true);
|
CHECK(variant.is<JsonVariantConst>() == true);
|
||||||
CHECK(variant.is<JsonObject>() == false);
|
CHECK(variant.is<JsonObject>() == false);
|
||||||
CHECK(variant.is<JsonArray>() == false);
|
CHECK(variant.is<JsonArray>() == false);
|
||||||
CHECK(variant.is<char *>() == false);
|
CHECK(variant.is<const char *>() == false);
|
||||||
CHECK(variant.is<int>() == false);
|
CHECK(variant.is<int>() == false);
|
||||||
CHECK(variant.is<std::string>() == false);
|
CHECK(variant.is<std::string>() == false);
|
||||||
CHECK(variant.is<float>() == false);
|
CHECK(variant.is<float>() == false);
|
||||||
@ -62,7 +62,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
|||||||
CHECK(variant.is<JsonVariantConst>() == true);
|
CHECK(variant.is<JsonVariantConst>() == true);
|
||||||
CHECK(variant.is<JsonObject>() == false);
|
CHECK(variant.is<JsonObject>() == false);
|
||||||
CHECK(variant.is<JsonArray>() == false);
|
CHECK(variant.is<JsonArray>() == false);
|
||||||
CHECK(variant.is<char *>() == false);
|
CHECK(variant.is<const char *>() == false);
|
||||||
CHECK(variant.is<int>() == false);
|
CHECK(variant.is<int>() == false);
|
||||||
CHECK(variant.is<std::string>() == false);
|
CHECK(variant.is<std::string>() == false);
|
||||||
CHECK(variant.is<float>() == false);
|
CHECK(variant.is<float>() == false);
|
||||||
@ -83,7 +83,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
|||||||
CHECK(variant.is<bool>() == false);
|
CHECK(variant.is<bool>() == false);
|
||||||
CHECK(variant.is<JsonObject>() == false);
|
CHECK(variant.is<JsonObject>() == false);
|
||||||
CHECK(variant.is<JsonArray>() == false);
|
CHECK(variant.is<JsonArray>() == false);
|
||||||
CHECK(variant.is<char *>() == false);
|
CHECK(variant.is<const char *>() == false);
|
||||||
CHECK(variant.is<std::string>() == false);
|
CHECK(variant.is<std::string>() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
|||||||
CHECK(variant.is<bool>() == false);
|
CHECK(variant.is<bool>() == false);
|
||||||
CHECK(variant.is<JsonObject>() == false);
|
CHECK(variant.is<JsonObject>() == false);
|
||||||
CHECK(variant.is<JsonArray>() == false);
|
CHECK(variant.is<JsonArray>() == false);
|
||||||
CHECK(variant.is<char *>() == false);
|
CHECK(variant.is<const char *>() == false);
|
||||||
CHECK(variant.is<int>() == false);
|
CHECK(variant.is<int>() == false);
|
||||||
CHECK(variant.is<std::string>() == false);
|
CHECK(variant.is<std::string>() == false);
|
||||||
CHECK(variant.is<MYENUM2>() == false);
|
CHECK(variant.is<MYENUM2>() == false);
|
||||||
@ -106,7 +106,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
|||||||
SECTION("const char*") {
|
SECTION("const char*") {
|
||||||
variant.set("4.2");
|
variant.set("4.2");
|
||||||
|
|
||||||
CHECK(variant.is<char *>() == true);
|
CHECK(variant.is<const char *>() == true);
|
||||||
CHECK(variant.is<const char *>() == true);
|
CHECK(variant.is<const char *>() == true);
|
||||||
CHECK(variant.is<std::string>() == true);
|
CHECK(variant.is<std::string>() == true);
|
||||||
CHECK(variant.is<JsonVariant>() == true);
|
CHECK(variant.is<JsonVariant>() == true);
|
||||||
@ -132,7 +132,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
|||||||
CHECK(variant.is<int>() == false);
|
CHECK(variant.is<int>() == false);
|
||||||
CHECK(variant.is<float>() == false);
|
CHECK(variant.is<float>() == false);
|
||||||
CHECK(variant.is<bool>() == false);
|
CHECK(variant.is<bool>() == false);
|
||||||
CHECK(variant.is<char *>() == false);
|
CHECK(variant.is<const char *>() == false);
|
||||||
CHECK(variant.is<MYENUM2>() == false);
|
CHECK(variant.is<MYENUM2>() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ TEST_CASE("JsonVariant::is<T>()") {
|
|||||||
CHECK(variant.is<int>() == false);
|
CHECK(variant.is<int>() == false);
|
||||||
CHECK(variant.is<float>() == false);
|
CHECK(variant.is<float>() == false);
|
||||||
CHECK(variant.is<bool>() == false);
|
CHECK(variant.is<bool>() == false);
|
||||||
CHECK(variant.is<char *>() == false);
|
CHECK(variant.is<const char *>() == false);
|
||||||
CHECK(variant.is<MYENUM2>() == false);
|
CHECK(variant.is<MYENUM2>() == false);
|
||||||
CHECK(variant.is<JsonVariant>() == true);
|
CHECK(variant.is<JsonVariant>() == true);
|
||||||
CHECK(variant.is<JsonVariantConst>() == true);
|
CHECK(variant.is<JsonVariantConst>() == true);
|
||||||
@ -170,7 +170,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
|||||||
CHECK(cvariant.is<JsonVariant>() == false);
|
CHECK(cvariant.is<JsonVariant>() == false);
|
||||||
CHECK(cvariant.is<JsonVariantConst>() == false);
|
CHECK(cvariant.is<JsonVariantConst>() == false);
|
||||||
CHECK(cvariant.is<bool>() == false);
|
CHECK(cvariant.is<bool>() == false);
|
||||||
CHECK(cvariant.is<char *>() == false);
|
CHECK(cvariant.is<const char *>() == false);
|
||||||
CHECK(cvariant.is<int>() == false);
|
CHECK(cvariant.is<int>() == false);
|
||||||
CHECK(cvariant.is<std::string>() == false);
|
CHECK(cvariant.is<std::string>() == false);
|
||||||
CHECK(cvariant.is<float>() == false);
|
CHECK(cvariant.is<float>() == false);
|
||||||
@ -183,7 +183,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
|||||||
CHECK(cvariant.is<JsonArray>() == false);
|
CHECK(cvariant.is<JsonArray>() == false);
|
||||||
CHECK(cvariant.is<JsonVariant>() == false);
|
CHECK(cvariant.is<JsonVariant>() == false);
|
||||||
CHECK(cvariant.is<bool>() == false);
|
CHECK(cvariant.is<bool>() == false);
|
||||||
CHECK(cvariant.is<char *>() == false);
|
CHECK(cvariant.is<const char *>() == false);
|
||||||
CHECK(cvariant.is<int>() == false);
|
CHECK(cvariant.is<int>() == false);
|
||||||
CHECK(cvariant.is<std::string>() == false);
|
CHECK(cvariant.is<std::string>() == false);
|
||||||
CHECK(cvariant.is<float>() == false);
|
CHECK(cvariant.is<float>() == false);
|
||||||
@ -198,7 +198,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
|||||||
CHECK(cvariant.is<JsonVariant>() == false);
|
CHECK(cvariant.is<JsonVariant>() == false);
|
||||||
CHECK(cvariant.is<JsonObject>() == false);
|
CHECK(cvariant.is<JsonObject>() == false);
|
||||||
CHECK(cvariant.is<JsonArray>() == false);
|
CHECK(cvariant.is<JsonArray>() == false);
|
||||||
CHECK(cvariant.is<char *>() == false);
|
CHECK(cvariant.is<const char *>() == false);
|
||||||
CHECK(cvariant.is<int>() == false);
|
CHECK(cvariant.is<int>() == false);
|
||||||
CHECK(cvariant.is<std::string>() == false);
|
CHECK(cvariant.is<std::string>() == false);
|
||||||
CHECK(cvariant.is<float>() == false);
|
CHECK(cvariant.is<float>() == false);
|
||||||
@ -213,7 +213,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
|||||||
CHECK(cvariant.is<JsonVariant>() == false);
|
CHECK(cvariant.is<JsonVariant>() == false);
|
||||||
CHECK(cvariant.is<JsonObject>() == false);
|
CHECK(cvariant.is<JsonObject>() == false);
|
||||||
CHECK(cvariant.is<JsonArray>() == false);
|
CHECK(cvariant.is<JsonArray>() == false);
|
||||||
CHECK(cvariant.is<char *>() == false);
|
CHECK(cvariant.is<const char *>() == false);
|
||||||
CHECK(cvariant.is<int>() == false);
|
CHECK(cvariant.is<int>() == false);
|
||||||
CHECK(cvariant.is<std::string>() == false);
|
CHECK(cvariant.is<std::string>() == false);
|
||||||
CHECK(cvariant.is<float>() == false);
|
CHECK(cvariant.is<float>() == false);
|
||||||
@ -234,7 +234,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
|||||||
CHECK(cvariant.is<JsonObject>() == false);
|
CHECK(cvariant.is<JsonObject>() == false);
|
||||||
CHECK(cvariant.is<JsonArray>() == false);
|
CHECK(cvariant.is<JsonArray>() == false);
|
||||||
CHECK(cvariant.is<JsonVariant>() == false);
|
CHECK(cvariant.is<JsonVariant>() == false);
|
||||||
CHECK(cvariant.is<char *>() == false);
|
CHECK(cvariant.is<const char *>() == false);
|
||||||
CHECK(cvariant.is<std::string>() == false);
|
CHECK(cvariant.is<std::string>() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +248,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
|||||||
CHECK(cvariant.is<JsonObject>() == false);
|
CHECK(cvariant.is<JsonObject>() == false);
|
||||||
CHECK(cvariant.is<JsonArray>() == false);
|
CHECK(cvariant.is<JsonArray>() == false);
|
||||||
CHECK(cvariant.is<JsonVariant>() == false);
|
CHECK(cvariant.is<JsonVariant>() == false);
|
||||||
CHECK(cvariant.is<char *>() == false);
|
CHECK(cvariant.is<const char *>() == false);
|
||||||
CHECK(cvariant.is<int>() == false);
|
CHECK(cvariant.is<int>() == false);
|
||||||
CHECK(cvariant.is<std::string>() == false);
|
CHECK(cvariant.is<std::string>() == false);
|
||||||
CHECK(cvariant.is<MYENUM2>() == false);
|
CHECK(cvariant.is<MYENUM2>() == false);
|
||||||
@ -257,7 +257,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
|||||||
SECTION("const char*") {
|
SECTION("const char*") {
|
||||||
variant.set("4.2");
|
variant.set("4.2");
|
||||||
|
|
||||||
CHECK(cvariant.is<char *>() == true);
|
CHECK(cvariant.is<const char *>() == true);
|
||||||
CHECK(cvariant.is<const char *>() == true);
|
CHECK(cvariant.is<const char *>() == true);
|
||||||
CHECK(cvariant.is<std::string>() == true);
|
CHECK(cvariant.is<std::string>() == true);
|
||||||
CHECK(cvariant.is<double>() == false);
|
CHECK(cvariant.is<double>() == false);
|
||||||
@ -282,7 +282,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
|||||||
CHECK(cvariant.is<int>() == false);
|
CHECK(cvariant.is<int>() == false);
|
||||||
CHECK(cvariant.is<float>() == false);
|
CHECK(cvariant.is<float>() == false);
|
||||||
CHECK(cvariant.is<bool>() == false);
|
CHECK(cvariant.is<bool>() == false);
|
||||||
CHECK(cvariant.is<char *>() == false);
|
CHECK(cvariant.is<const char *>() == false);
|
||||||
CHECK(cvariant.is<MYENUM2>() == false);
|
CHECK(cvariant.is<MYENUM2>() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +298,7 @@ TEST_CASE("JsonVariantConst::is<T>()") {
|
|||||||
CHECK(cvariant.is<int>() == false);
|
CHECK(cvariant.is<int>() == false);
|
||||||
CHECK(cvariant.is<float>() == false);
|
CHECK(cvariant.is<float>() == false);
|
||||||
CHECK(cvariant.is<bool>() == false);
|
CHECK(cvariant.is<bool>() == false);
|
||||||
CHECK(cvariant.is<char *>() == false);
|
CHECK(cvariant.is<const char *>() == false);
|
||||||
CHECK(cvariant.is<MYENUM2>() == false);
|
CHECK(cvariant.is<MYENUM2>() == false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@ TEST_CASE("JsonVariant undefined") {
|
|||||||
REQUIRE(variant.is<unsigned>() == false);
|
REQUIRE(variant.is<unsigned>() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("char*") {
|
SECTION("const char*") {
|
||||||
REQUIRE(variant.is<char*>() == false);
|
REQUIRE(variant.is<const char*>() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("double") {
|
SECTION("double") {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
|
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
|
||||||
#include <ArduinoJson/Deserialization/Reader.hpp>
|
#include <ArduinoJson.hpp>
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ARDUINOJSON_NAMESPACE;
|
using namespace ARDUINOJSON_NAMESPACE;
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
#define ARDUINOJSON_ENABLE_NAN 1
|
#define ARDUINOJSON_ENABLE_NAN 1
|
||||||
#define ARDUINOJSON_ENABLE_INFINITY 1
|
#define ARDUINOJSON_ENABLE_INFINITY 1
|
||||||
|
|
||||||
#include <ArduinoJson/Numbers/parseNumber.hpp>
|
#include <ArduinoJson.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantImpl.hpp>
|
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ARDUINOJSON_NAMESPACE;
|
using namespace ARDUINOJSON_NAMESPACE;
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
#define ARDUINOJSON_ENABLE_NAN 1
|
#define ARDUINOJSON_ENABLE_NAN 1
|
||||||
#define ARDUINOJSON_ENABLE_INFINITY 1
|
#define ARDUINOJSON_ENABLE_INFINITY 1
|
||||||
|
|
||||||
#include <ArduinoJson/Numbers/parseNumber.hpp>
|
#include <ArduinoJson.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantImpl.hpp>
|
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ARDUINOJSON_NAMESPACE;
|
using namespace ARDUINOJSON_NAMESPACE;
|
||||||
|
@ -3,8 +3,7 @@
|
|||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <ArduinoJson/Numbers/parseNumber.hpp>
|
#include <ArduinoJson.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantImpl.hpp>
|
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ARDUINOJSON_NAMESPACE;
|
using namespace ARDUINOJSON_NAMESPACE;
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
// Copyright Benoit Blanchon 2014-2021
|
// Copyright Benoit Blanchon 2014-2021
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#include <ArduinoJson/Numbers/Integer.hpp>
|
#include <ArduinoJson.hpp>
|
||||||
#include <ArduinoJson/Numbers/parseNumber.hpp>
|
|
||||||
#include <ArduinoJson/Variant/VariantImpl.hpp>
|
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ARDUINOJSON_NAMESPACE;
|
using namespace ARDUINOJSON_NAMESPACE;
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "ArduinoJson/Collection/CollectionImpl.hpp"
|
#include "ArduinoJson/Collection/CollectionImpl.hpp"
|
||||||
#include "ArduinoJson/Object/MemberProxy.hpp"
|
#include "ArduinoJson/Object/MemberProxy.hpp"
|
||||||
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
||||||
#include "ArduinoJson/Variant/VariantAsImpl.hpp"
|
#include "ArduinoJson/Variant/ConverterImpl.hpp"
|
||||||
#include "ArduinoJson/Variant/VariantCompare.hpp"
|
#include "ArduinoJson/Variant/VariantCompare.hpp"
|
||||||
#include "ArduinoJson/Variant/VariantImpl.hpp"
|
#include "ArduinoJson/Variant/VariantImpl.hpp"
|
||||||
|
|
||||||
|
@ -164,4 +164,42 @@ class ArrayRef : public ArrayRefBase<CollectionData>,
|
|||||||
private:
|
private:
|
||||||
MemoryPool* _pool;
|
MemoryPool* _pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<ArrayConstRef> {
|
||||||
|
static bool toJson(VariantRef variant, VariantConstRef value) {
|
||||||
|
return variantCopyFrom(getData(variant), getData(value), getPool(variant));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ArrayConstRef fromJson(VariantConstRef variant) {
|
||||||
|
return ArrayConstRef(variantAsArray(getData(variant)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data && data->isArray();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<ArrayRef> {
|
||||||
|
static bool toJson(VariantRef variant, VariantConstRef value) {
|
||||||
|
return variantCopyFrom(getData(variant), getData(value), getPool(variant));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ArrayRef fromJson(VariantRef variant) {
|
||||||
|
VariantData* data = getData(variant);
|
||||||
|
MemoryPool* pool = getPool(variant);
|
||||||
|
return ArrayRef(pool, data != 0 ? data->asArray() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantConstRef) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantRef variant) {
|
||||||
|
VariantData* data = getData(variant);
|
||||||
|
return data && data->isArray();
|
||||||
|
}
|
||||||
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
// Forward declarations.
|
// Forward declarations.
|
||||||
|
class ArrayRef;
|
||||||
|
class ObjectRef;
|
||||||
template <typename>
|
template <typename>
|
||||||
class ElementProxy;
|
class ElementProxy;
|
||||||
|
|
||||||
|
@ -170,6 +170,10 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
|||||||
return _array.getOrAddElement(_index);
|
return _array.getOrAddElement(_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend bool convertToJson(VariantRef variant, const this_type& value) {
|
||||||
|
return variant.set(value.getUpstreamElement());
|
||||||
|
}
|
||||||
|
|
||||||
TArray _array;
|
TArray _array;
|
||||||
const size_t _index;
|
const size_t _index;
|
||||||
};
|
};
|
||||||
|
@ -76,7 +76,8 @@ class ArrayCopier1D : public Visitor<size_t> {
|
|||||||
VariantSlot* slot = array.head();
|
VariantSlot* slot = array.head();
|
||||||
|
|
||||||
while (slot != 0 && size < _capacity) {
|
while (slot != 0 && size < _capacity) {
|
||||||
_destination[size++] = variantAs<T>(slot->data());
|
_destination[size++] =
|
||||||
|
Converter<T>::fromJson(VariantConstRef(slot->data()));
|
||||||
slot = slot->next();
|
slot = slot->next();
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
|
@ -337,4 +337,8 @@ class JsonDocument : public Visitable {
|
|||||||
JsonDocument& operator=(const JsonDocument&);
|
JsonDocument& operator=(const JsonDocument&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool convertToJson(VariantRef variant, const JsonDocument& doc) {
|
||||||
|
return variant.set(doc.as<VariantConstRef>());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include <ArduinoJson/Polyfills/ctype.hpp>
|
#include <ArduinoJson/Polyfills/ctype.hpp>
|
||||||
#include <ArduinoJson/Polyfills/math.hpp>
|
#include <ArduinoJson/Polyfills/math.hpp>
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantAs.hpp>
|
#include <ArduinoJson/Variant/Converter.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
@ -142,6 +142,6 @@ inline T parseNumber(const char* s) {
|
|||||||
VariantData value;
|
VariantData value;
|
||||||
value.init(); // VariantData is a POD, so it has no constructor
|
value.init(); // VariantData is a POD, so it has no constructor
|
||||||
parseNumber(s, value);
|
parseNumber(s, value);
|
||||||
return variantAs<T>(&value);
|
return Converter<T>::fromJson(VariantConstRef(&value));
|
||||||
}
|
}
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
@ -193,6 +193,10 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
|||||||
return _object.getOrAddMember(_key);
|
return _object.getOrAddMember(_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend bool convertToJson(VariantRef variant, const this_type &value) {
|
||||||
|
return variant.set(value.getUpstreamMember());
|
||||||
|
}
|
||||||
|
|
||||||
TObject _object;
|
TObject _object;
|
||||||
TStringRef _key;
|
TStringRef _key;
|
||||||
};
|
};
|
||||||
|
@ -236,4 +236,42 @@ class ObjectRef : public ObjectRefBase<CollectionData>,
|
|||||||
private:
|
private:
|
||||||
MemoryPool* _pool;
|
MemoryPool* _pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<ObjectConstRef> {
|
||||||
|
static bool toJson(VariantRef variant, VariantConstRef value) {
|
||||||
|
return variantCopyFrom(getData(variant), getData(value), getPool(variant));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ObjectConstRef fromJson(VariantConstRef variant) {
|
||||||
|
return ObjectConstRef(variantAsObject(getData(variant)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data && data->isObject();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<ObjectRef> {
|
||||||
|
static bool toJson(VariantRef variant, VariantConstRef value) {
|
||||||
|
return variantCopyFrom(getData(variant), getData(value), getPool(variant));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ObjectRef fromJson(VariantRef variant) {
|
||||||
|
VariantData* data = getData(variant);
|
||||||
|
MemoryPool* pool = getPool(variant);
|
||||||
|
return ObjectRef(pool, data != 0 ? data->asObject() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantConstRef) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantRef variant) {
|
||||||
|
VariantData* data = getData(variant);
|
||||||
|
return data && data->isObject();
|
||||||
|
}
|
||||||
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
12
src/ArduinoJson/Variant/Converter.hpp
Normal file
12
src/ArduinoJson/Variant/Converter.hpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2021
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <typename T, typename Enable = void>
|
||||||
|
struct Converter;
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
209
src/ArduinoJson/Variant/ConverterImpl.hpp
Normal file
209
src/ArduinoJson/Variant/ConverterImpl.hpp
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2021
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Strings/IsWriteableString.hpp>
|
||||||
|
#include <ArduinoJson/Variant/VariantFunctions.hpp>
|
||||||
|
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <typename T, typename Enable>
|
||||||
|
struct Converter {
|
||||||
|
static bool toJson(VariantRef variant, const T& value) {
|
||||||
|
// clang-format off
|
||||||
|
return convertToJson(variant, value); // Error here? See https://arduinojson.org/v6/unsupported-set/
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
|
static T fromJson(VariantConstRef variant) {
|
||||||
|
// clang-format off
|
||||||
|
T value; // Error here? See https://arduinojson.org/v6/non-default-constructible/
|
||||||
|
convertFromJson(value, variant); // Error here? See https://arduinojson.org/v6/unsupported-as/
|
||||||
|
// clang-format on
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantConstRef variant) {
|
||||||
|
T dummy;
|
||||||
|
// clang-format off
|
||||||
|
return canConvertFromJson(dummy, variant); // Error here? See https://arduinojson.org/v6/unsupported-is/
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Converter<
|
||||||
|
T, typename enable_if<is_integral<T>::value && !is_same<bool, T>::value &&
|
||||||
|
!is_same<char, T>::value>::type> {
|
||||||
|
static bool toJson(VariantRef variant, T value) {
|
||||||
|
VariantData* data = getData(variant);
|
||||||
|
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
|
||||||
|
if (!data)
|
||||||
|
return false;
|
||||||
|
data->setInteger(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static T fromJson(VariantConstRef variant) {
|
||||||
|
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data ? data->asIntegral<T>() : T();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data && data->isInteger<T>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Converter<T, typename enable_if<is_enum<T>::value>::type> {
|
||||||
|
static bool toJson(VariantRef variant, T value) {
|
||||||
|
return variant.set(static_cast<Integer>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
static T fromJson(VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data ? static_cast<T>(data->asIntegral<int>()) : T();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data && data->isInteger<int>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<bool> {
|
||||||
|
static bool toJson(VariantRef variant, bool value) {
|
||||||
|
VariantData* data = getData(variant);
|
||||||
|
if (!data)
|
||||||
|
return false;
|
||||||
|
data->setBoolean(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool fromJson(VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data ? data->asBoolean() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data && data->isBoolean();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Converter<T, typename enable_if<is_floating_point<T>::value>::type> {
|
||||||
|
static bool toJson(VariantRef variant, T value) {
|
||||||
|
VariantData* data = getData(variant);
|
||||||
|
if (!data)
|
||||||
|
return false;
|
||||||
|
data->setFloat(static_cast<Float>(value));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static T fromJson(VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data ? data->asFloat<T>() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data && data->isFloat();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<const char*> {
|
||||||
|
static bool toJson(VariantRef variant, const char* value) {
|
||||||
|
// TODO: don't pass pool
|
||||||
|
return variantSetString(getData(variant), adaptString(value),
|
||||||
|
getPool(variant));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* fromJson(VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data ? data->asString() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data && data->isString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline typename enable_if<IsString<T>::value, bool>::type convertToJson(
|
||||||
|
VariantRef variant, const T& value) {
|
||||||
|
VariantData* data = getData(variant);
|
||||||
|
MemoryPool* pool = getPool(variant);
|
||||||
|
return variantSetString(data, adaptString(value), pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline typename enable_if<IsWriteableString<T>::value>::type convertFromJson(
|
||||||
|
T& value, VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
const char* cstr = data != 0 ? data->asString() : 0;
|
||||||
|
if (cstr)
|
||||||
|
value = cstr;
|
||||||
|
else
|
||||||
|
serializeJson(variant, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline typename enable_if<IsWriteableString<T>::value, bool>::type
|
||||||
|
canConvertFromJson(T&, VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data && data->isString();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<SerializedValue<const char*> > {
|
||||||
|
static bool toJson(VariantRef variant, SerializedValue<const char*> value) {
|
||||||
|
VariantData* data = getData(variant);
|
||||||
|
if (!data)
|
||||||
|
return false;
|
||||||
|
data->setLinkedRaw(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// SerializedValue<std::string>
|
||||||
|
// SerializedValue<String>
|
||||||
|
// SerializedValue<const __FlashStringHelper*>
|
||||||
|
template <typename T>
|
||||||
|
struct Converter<SerializedValue<T>,
|
||||||
|
typename enable_if<!is_same<const char*, T>::value>::type> {
|
||||||
|
static bool toJson(VariantRef variant, SerializedValue<T> value) {
|
||||||
|
VariantData* data = getData(variant);
|
||||||
|
MemoryPool* pool = getPool(variant);
|
||||||
|
return data != 0 && data->setOwnedRaw(value, pool);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ARDUINOJSON_HAS_NULLPTR
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<decltype(nullptr)> {
|
||||||
|
static bool toJson(VariantRef variant, decltype(nullptr)) {
|
||||||
|
variantSetNull(getData(variant));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
static decltype(nullptr) fromJson(VariantConstRef) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
static bool checkJson(VariantConstRef variant) {
|
||||||
|
const VariantData* data = getData(variant);
|
||||||
|
return data == 0 || data->isNull();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
@ -1,76 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2021
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ArduinoJson/Strings/IsWriteableString.hpp>
|
|
||||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
|
|
||||||
class ArrayRef;
|
|
||||||
class ArrayConstRef;
|
|
||||||
class ObjectRef;
|
|
||||||
class ObjectConstRef;
|
|
||||||
class VariantRef;
|
|
||||||
class VariantConstRef;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename enable_if<is_integral<T>::value && !is_same<bool, T>::value &&
|
|
||||||
!is_same<char, T>::value,
|
|
||||||
T>::type
|
|
||||||
variantAs(const VariantData* data) {
|
|
||||||
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
|
|
||||||
return data != 0 ? data->asIntegral<T>() : T(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename enable_if<is_enum<T>::value, T>::type variantAs(
|
|
||||||
const VariantData* data) {
|
|
||||||
return data != 0 ? static_cast<T>(data->asIntegral<int>()) : T();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename enable_if<is_same<T, bool>::value, T>::type variantAs(
|
|
||||||
const VariantData* data) {
|
|
||||||
return data != 0 ? data->asBoolean() : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename enable_if<is_floating_point<T>::value, T>::type variantAs(
|
|
||||||
const VariantData* data) {
|
|
||||||
return data != 0 ? data->asFloat<T>() : T(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename enable_if<is_same<T, const char*>::value, T>::type variantAs(
|
|
||||||
const VariantData* data) {
|
|
||||||
return data != 0 ? data->asString() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T variantAs(VariantData* data, MemoryPool*) {
|
|
||||||
// By default use the read-only conversion.
|
|
||||||
// There are specializations for
|
|
||||||
// - ArrayRef
|
|
||||||
return variantAs<T>(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename enable_if<is_same<ArrayConstRef, T>::value, T>::type variantAs(
|
|
||||||
const VariantData* data);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename enable_if<is_same<ObjectConstRef, T>::value, T>::type variantAs(
|
|
||||||
const VariantData* data);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename enable_if<is_same<VariantConstRef, T>::value, T>::type
|
|
||||||
variantAs(const VariantData* data);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename enable_if<IsWriteableString<T>::value, T>::type variantAs(
|
|
||||||
const VariantData* data);
|
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
|
@ -1,57 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2021
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ArduinoJson/Strings/IsWriteableString.hpp>
|
|
||||||
#include <ArduinoJson/Variant/VariantFunctions.hpp>
|
|
||||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename enable_if<is_same<ArrayConstRef, T>::value, T>::type variantAs(
|
|
||||||
const VariantData* _data) {
|
|
||||||
return ArrayConstRef(variantAsArray(_data));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename enable_if<is_same<ObjectConstRef, T>::value, T>::type variantAs(
|
|
||||||
const VariantData* _data) {
|
|
||||||
return ObjectConstRef(variantAsObject(_data));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename enable_if<is_same<VariantConstRef, T>::value, T>::type
|
|
||||||
variantAs(const VariantData* _data) {
|
|
||||||
return VariantConstRef(_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename enable_if<IsWriteableString<T>::value, T>::type variantAs(
|
|
||||||
const VariantData* _data) {
|
|
||||||
const char* cstr = _data != 0 ? _data->asString() : 0;
|
|
||||||
if (cstr)
|
|
||||||
return T(cstr);
|
|
||||||
T s;
|
|
||||||
serializeJson(VariantConstRef(_data), s);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline ArrayRef variantAs<ArrayRef>(VariantData* data, MemoryPool* pool) {
|
|
||||||
return ArrayRef(pool, data != 0 ? data->asArray() : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline ObjectRef variantAs<ObjectRef>(VariantData* data, MemoryPool* pool) {
|
|
||||||
return ObjectRef(pool, data != 0 ? data->asObject() : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline VariantRef variantAs<VariantRef>(VariantData* data, MemoryPool* pool) {
|
|
||||||
return VariantRef(pool, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
|
@ -43,34 +43,6 @@ inline bool variantCopyFrom(VariantData *dst, const VariantData *src,
|
|||||||
|
|
||||||
inline int variantCompare(const VariantData *a, const VariantData *b);
|
inline int variantCompare(const VariantData *a, const VariantData *b);
|
||||||
|
|
||||||
inline bool variantSetBoolean(VariantData *var, bool value) {
|
|
||||||
if (!var)
|
|
||||||
return false;
|
|
||||||
var->setBoolean(value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool variantSetFloat(VariantData *var, Float value) {
|
|
||||||
if (!var)
|
|
||||||
return false;
|
|
||||||
var->setFloat(value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool variantSetLinkedRaw(VariantData *var,
|
|
||||||
SerializedValue<const char *> value) {
|
|
||||||
if (!var)
|
|
||||||
return false;
|
|
||||||
var->setLinkedRaw(value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool variantSetOwnedRaw(VariantData *var, SerializedValue<T> value,
|
|
||||||
MemoryPool *pool) {
|
|
||||||
return var != 0 && var->setOwnedRaw(value, pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void variantSetNull(VariantData *var) {
|
inline void variantSetNull(VariantData *var) {
|
||||||
if (!var)
|
if (!var)
|
||||||
return;
|
return;
|
||||||
@ -85,15 +57,6 @@ inline bool variantSetString(VariantData *var, TAdaptedString value,
|
|||||||
return var->setString(value, pool);
|
return var->setString(value, pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool variantSetInteger(VariantData *var, T value) {
|
|
||||||
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
|
|
||||||
if (!var)
|
|
||||||
return false;
|
|
||||||
var->setInteger(value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t variantSize(const VariantData *var) {
|
inline size_t variantSize(const VariantData *var) {
|
||||||
return var != 0 ? var->size() : 0;
|
return var != 0 ? var->size() : 0;
|
||||||
}
|
}
|
||||||
@ -134,4 +97,8 @@ NO_INLINE VariantData *variantGetOrAddMember(VariantData *var,
|
|||||||
return var != 0 ? var->getOrAddMember(adaptString(key), pool) : 0;
|
return var != 0 ? var->getOrAddMember(adaptString(key), pool) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool variantIsNull(const VariantData *var) {
|
||||||
|
return var == 0 || var->isNull();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
@ -77,13 +77,6 @@ inline const char *VariantData::asString() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TVariant>
|
|
||||||
typename enable_if<IsVisitable<TVariant>::value, bool>::type VariantRef::set(
|
|
||||||
const TVariant &value) const {
|
|
||||||
VariantConstRef v = value;
|
|
||||||
return variantCopyFrom(_data, v._data, _pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline typename enable_if<is_same<T, ArrayRef>::value, ArrayRef>::type
|
inline typename enable_if<is_same<T, ArrayRef>::value, ArrayRef>::type
|
||||||
VariantRef::to() const {
|
VariantRef::to() const {
|
||||||
|
@ -1,146 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2021
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
|
||||||
#include <ArduinoJson/Variant/VariantFunctions.hpp>
|
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
|
|
||||||
inline bool variantIsNull(const VariantData *var) {
|
|
||||||
return var == 0 || var->isNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool is<char>() const;
|
|
||||||
// bool is<signed char>() const;
|
|
||||||
// bool is<signed short>() const;
|
|
||||||
// bool is<signed int>() const;
|
|
||||||
// bool is<signed long>() const;
|
|
||||||
// bool is<unsigned char>() const;
|
|
||||||
// bool is<unsigned short>() const;
|
|
||||||
// bool is<unsigned int>() const;
|
|
||||||
// bool is<unsigned long>() const;
|
|
||||||
template <typename T>
|
|
||||||
NO_INLINE typename enable_if<is_integral<T>::value && !is_same<bool, T>::value,
|
|
||||||
bool>::type
|
|
||||||
variantIs(const VariantData *var) {
|
|
||||||
return var && var->isInteger<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool is<double>() const;
|
|
||||||
// bool is<float>() const;
|
|
||||||
template <typename T>
|
|
||||||
NO_INLINE typename enable_if<is_floating_point<T>::value, bool>::type variantIs(
|
|
||||||
const VariantData *var) {
|
|
||||||
return var && var->isFloat();
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool is<bool>() const
|
|
||||||
template <typename T>
|
|
||||||
NO_INLINE typename enable_if<is_same<T, bool>::value, bool>::type variantIs(
|
|
||||||
const VariantData *var) {
|
|
||||||
return var && var->isBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool is<const char*>() const;
|
|
||||||
// bool is<char*>() const;
|
|
||||||
// bool is<std::string>() const;
|
|
||||||
// bool is<String>() const;
|
|
||||||
template <typename T>
|
|
||||||
NO_INLINE typename enable_if<is_same<T, const char *>::value ||
|
|
||||||
is_same<T, char *>::value ||
|
|
||||||
IsWriteableString<T>::value,
|
|
||||||
bool>::type
|
|
||||||
variantIs(const VariantData *var) {
|
|
||||||
return var && var->isString();
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool is<ArrayConstRef> const;
|
|
||||||
// bool is<const ArrayConstRef> const;
|
|
||||||
template <typename T>
|
|
||||||
NO_INLINE typename enable_if<
|
|
||||||
is_same<typename remove_const<T>::type, ArrayConstRef>::value, bool>::type
|
|
||||||
variantIs(const VariantData *var) {
|
|
||||||
return var && var->isArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool is<ObjectConstRef> const;
|
|
||||||
// bool is<const ObjectConstRef> const;
|
|
||||||
template <typename T>
|
|
||||||
NO_INLINE typename enable_if<
|
|
||||||
is_same<typename remove_const<T>::type, ObjectConstRef>::value, bool>::type
|
|
||||||
variantIs(const VariantData *var) {
|
|
||||||
return var && var->isObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool is<VariantConstRef> const;
|
|
||||||
// bool is<const VariantConstRef> const;
|
|
||||||
template <typename T>
|
|
||||||
NO_INLINE typename enable_if<
|
|
||||||
is_same<typename remove_const<T>::type, VariantConstRef>::value, bool>::type
|
|
||||||
variantIs(const VariantData *var) {
|
|
||||||
return !!var;
|
|
||||||
}
|
|
||||||
#if ARDUINOJSON_HAS_NULLPTR
|
|
||||||
|
|
||||||
// bool is<nullptr_t> const;
|
|
||||||
template <typename T>
|
|
||||||
NO_INLINE typename enable_if<is_same<T, decltype(nullptr)>::value, bool>::type
|
|
||||||
variantIs(const VariantData *var) {
|
|
||||||
return variantIsNull(var);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// bool is<enum>() const;
|
|
||||||
template <typename T>
|
|
||||||
typename enable_if<is_enum<T>::value, bool>::type variantIs(
|
|
||||||
const VariantData *var) {
|
|
||||||
return variantIs<int>(var);
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool is<ArrayRef> const;
|
|
||||||
// bool is<const ArrayRef> const;
|
|
||||||
template <typename T>
|
|
||||||
NO_INLINE
|
|
||||||
typename enable_if<is_same<typename remove_const<T>::type, ArrayRef>::value,
|
|
||||||
bool>::type
|
|
||||||
variantIs(VariantData *var) {
|
|
||||||
return var && var->isArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool is<ObjectRef> const;
|
|
||||||
// bool is<const ObjectRef> const;
|
|
||||||
template <typename T>
|
|
||||||
NO_INLINE typename enable_if<
|
|
||||||
is_same<typename remove_const<T>::type, ObjectRef>::value, bool>::type
|
|
||||||
variantIs(VariantData *var) {
|
|
||||||
return var && var->isObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool is<VariantRef> const;
|
|
||||||
// bool is<const VariantRef> const;
|
|
||||||
template <typename T>
|
|
||||||
NO_INLINE typename enable_if<
|
|
||||||
is_same<typename remove_const<T>::type, VariantRef>::value, bool>::type
|
|
||||||
variantIs(VariantData *var) {
|
|
||||||
return !!var;
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool is<ArrayRef> const;
|
|
||||||
// bool is<const ArrayRef> const;
|
|
||||||
// bool is<ObjectRef> const;
|
|
||||||
// bool is<const ObjectRef> const;
|
|
||||||
// bool is<VariantRef> const;
|
|
||||||
// bool is<const VariantRef> const;
|
|
||||||
template <typename T>
|
|
||||||
typename enable_if<
|
|
||||||
is_same<typename remove_const<T>::type, ArrayRef>::value ||
|
|
||||||
is_same<typename remove_const<T>::type, ObjectRef>::value ||
|
|
||||||
is_same<typename remove_const<T>::type, VariantRef>::value,
|
|
||||||
bool>::type
|
|
||||||
variantIs(const VariantData *) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
|
@ -8,7 +8,6 @@
|
|||||||
#include <ArduinoJson/Numbers/arithmeticCompare.hpp>
|
#include <ArduinoJson/Numbers/arithmeticCompare.hpp>
|
||||||
#include <ArduinoJson/Polyfills/attributes.hpp>
|
#include <ArduinoJson/Polyfills/attributes.hpp>
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantAs.hpp>
|
|
||||||
#include <ArduinoJson/Variant/VariantTag.hpp>
|
#include <ArduinoJson/Variant/VariantTag.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
@ -11,9 +11,8 @@
|
|||||||
#include <ArduinoJson/Misc/Visitable.hpp>
|
#include <ArduinoJson/Misc/Visitable.hpp>
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantAs.hpp>
|
#include <ArduinoJson/Variant/Converter.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantFunctions.hpp>
|
#include <ArduinoJson/Variant/VariantFunctions.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantIs.hpp>
|
|
||||||
#include <ArduinoJson/Variant/VariantOperators.hpp>
|
#include <ArduinoJson/Variant/VariantOperators.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantShortcuts.hpp>
|
#include <ArduinoJson/Variant/VariantShortcuts.hpp>
|
||||||
@ -29,11 +28,6 @@ class ObjectRef;
|
|||||||
template <typename TData>
|
template <typename TData>
|
||||||
class VariantRefBase : public VariantTag {
|
class VariantRefBase : public VariantTag {
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
|
||||||
FORCE_INLINE bool is() const {
|
|
||||||
return variantIs<T>(_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCE_INLINE bool isNull() const {
|
FORCE_INLINE bool isNull() const {
|
||||||
return variantIsNull(_data);
|
return variantIsNull(_data);
|
||||||
}
|
}
|
||||||
@ -57,6 +51,10 @@ class VariantRefBase : public VariantTag {
|
|||||||
protected:
|
protected:
|
||||||
VariantRefBase(TData *data) : _data(data) {}
|
VariantRefBase(TData *data) : _data(data) {}
|
||||||
TData *_data;
|
TData *_data;
|
||||||
|
|
||||||
|
friend TData *getData(const VariantRefBase &variant) {
|
||||||
|
return variant._data;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// A variant that can be a any value serializable to a JSON value.
|
// A variant that can be a any value serializable to a JSON value.
|
||||||
@ -85,120 +83,29 @@ class VariantRef : public VariantRefBase<VariantData>,
|
|||||||
return variantSetNull(_data);
|
return variantSetNull(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set(bool value)
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE bool set(
|
FORCE_INLINE bool set(const T &value) const {
|
||||||
T value, typename enable_if<is_same<T, bool>::value>::type * = 0) const {
|
return Converter<T>::toJson(*this, value);
|
||||||
return variantSetBoolean(_data, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set(double value);
|
|
||||||
// set(float value);
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE bool set(
|
FORCE_INLINE bool set(T *value) const {
|
||||||
T value,
|
return Converter<T *>::toJson(*this, value);
|
||||||
typename enable_if<is_floating_point<T>::value>::type * = 0) const {
|
|
||||||
return variantSetFloat(_data, static_cast<Float>(value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set(char)
|
|
||||||
// set(signed short)
|
|
||||||
// set(signed int)
|
|
||||||
// set(signed long)
|
|
||||||
// set(signed char)
|
|
||||||
// set(unsigned short)
|
|
||||||
// set(unsigned int)
|
|
||||||
// set(unsigned long)
|
|
||||||
template <typename T>
|
|
||||||
FORCE_INLINE bool set(
|
|
||||||
T value,
|
|
||||||
typename enable_if<is_integral<T>::value && !is_same<bool, T>::value &&
|
|
||||||
!is_same<char, T>::value>::type * = 0) const {
|
|
||||||
return variantSetInteger<T>(_data, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set(SerializedValue<const char *>)
|
|
||||||
FORCE_INLINE bool set(SerializedValue<const char *> value) const {
|
|
||||||
return variantSetLinkedRaw(_data, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set(SerializedValue<std::string>)
|
|
||||||
// set(SerializedValue<String>)
|
|
||||||
// set(SerializedValue<const __FlashStringHelper*>)
|
|
||||||
template <typename T>
|
|
||||||
FORCE_INLINE bool set(
|
|
||||||
SerializedValue<T> value,
|
|
||||||
typename enable_if<!is_same<const char *, T>::value>::type * = 0) const {
|
|
||||||
return variantSetOwnedRaw(_data, value, _pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set(const std::string&)
|
|
||||||
// set(const String&)
|
|
||||||
template <typename T>
|
|
||||||
FORCE_INLINE bool set(
|
|
||||||
const T &value,
|
|
||||||
typename enable_if<IsString<T>::value>::type * = 0) const {
|
|
||||||
return variantSetString(_data, adaptString(value), _pool);
|
|
||||||
}
|
|
||||||
// set(char*)
|
|
||||||
// set(const __FlashStringHelper*)
|
|
||||||
// set(const char*)
|
|
||||||
template <typename T>
|
|
||||||
FORCE_INLINE bool set(
|
|
||||||
T *value, typename enable_if<IsString<T *>::value>::type * = 0) const {
|
|
||||||
return variantSetString(_data, adaptString(value), _pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set(VariantRef)
|
|
||||||
// set(VariantConstRef)
|
|
||||||
// set(ArrayRef)
|
|
||||||
// set(ArrayConstRef)
|
|
||||||
// set(ObjectRef)
|
|
||||||
// set(ObjecConstRef)
|
|
||||||
// set(const JsonDocument&)
|
|
||||||
template <typename TVariant>
|
|
||||||
typename enable_if<IsVisitable<TVariant>::value, bool>::type set(
|
|
||||||
const TVariant &value) const;
|
|
||||||
|
|
||||||
// set(enum value)
|
|
||||||
template <typename T>
|
|
||||||
FORCE_INLINE bool set(
|
|
||||||
T value, typename enable_if<is_enum<T>::value>::type * = 0) const {
|
|
||||||
return variantSetInteger(_data, static_cast<Integer>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if ARDUINOJSON_HAS_NULLPTR
|
|
||||||
// set(nullptr_t)
|
|
||||||
FORCE_INLINE bool set(decltype(nullptr)) const {
|
|
||||||
variantSetNull(_data);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE T as() const {
|
FORCE_INLINE T as() const {
|
||||||
/********************************************************************
|
return Converter<T>::fromJson(*this);
|
||||||
** THIS IS NOT A BUG IN THE LIBRARY **
|
}
|
||||||
** -------------------------------- **
|
|
||||||
** Get a compilation error pointing here? **
|
template <typename T>
|
||||||
** It doesn't mean the error *is* here. **
|
FORCE_INLINE bool is() const {
|
||||||
** Often, it's because you try to extract the wrong value type. **
|
return Converter<T>::checkJson(*this);
|
||||||
** **
|
|
||||||
** For example: **
|
|
||||||
** char* name = doc["name"]; **
|
|
||||||
** char age = doc["age"]; **
|
|
||||||
** auto city = doc["city"].as<char*>() **
|
|
||||||
** Instead, use: **
|
|
||||||
** const char* name = doc["name"]; **
|
|
||||||
** int8_t age = doc["age"]; **
|
|
||||||
** auto city = doc["city"].as<const char*>() **
|
|
||||||
********************************************************************/
|
|
||||||
return variantAs<T>(_data, _pool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE operator T() const {
|
FORCE_INLINE operator T() const {
|
||||||
return variantAs<T>(_data, _pool);
|
return Converter<T>::fromJson(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TVisitor>
|
template <typename TVisitor>
|
||||||
@ -273,7 +180,11 @@ class VariantRef : public VariantRefBase<VariantData>,
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
MemoryPool *_pool;
|
MemoryPool *_pool;
|
||||||
}; // namespace ARDUINOJSON_NAMESPACE
|
|
||||||
|
friend MemoryPool *getPool(const VariantRef &variant) {
|
||||||
|
return variant._pool;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class VariantConstRef : public VariantRefBase<const VariantData>,
|
class VariantConstRef : public VariantRefBase<const VariantData>,
|
||||||
public VariantOperators<VariantConstRef>,
|
public VariantOperators<VariantConstRef>,
|
||||||
@ -294,12 +205,17 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE T as() const {
|
FORCE_INLINE T as() const {
|
||||||
return variantAs<T>(_data);
|
return Converter<T>::fromJson(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
FORCE_INLINE bool is() const {
|
||||||
|
return Converter<T>::checkJson(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE operator T() const {
|
FORCE_INLINE operator T() const {
|
||||||
return variantAs<T>(_data);
|
return Converter<T>::fromJson(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE VariantConstRef getElement(size_t) const;
|
FORCE_INLINE VariantConstRef getElement(size_t) const;
|
||||||
@ -344,4 +260,38 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
|
|||||||
return getMember(key);
|
return getMember(key);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<VariantRef> {
|
||||||
|
static bool toJson(VariantRef variant, VariantRef value) {
|
||||||
|
return variantCopyFrom(getData(variant), getData(value), getPool(variant));
|
||||||
|
}
|
||||||
|
static VariantRef fromJson(VariantRef variant) {
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
static bool checkJson(VariantRef variant) {
|
||||||
|
VariantData *data = getData(variant);
|
||||||
|
return !!data;
|
||||||
|
}
|
||||||
|
static bool checkJson(VariantConstRef) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<VariantConstRef> {
|
||||||
|
static bool toJson(VariantRef variant, VariantConstRef value) {
|
||||||
|
return variantCopyFrom(getData(variant), getData(value), getPool(variant));
|
||||||
|
}
|
||||||
|
|
||||||
|
static VariantConstRef fromJson(VariantConstRef variant) {
|
||||||
|
return VariantConstRef(getData(variant));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool checkJson(VariantConstRef variant) {
|
||||||
|
const VariantData *data = getData(variant);
|
||||||
|
return !!data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
Reference in New Issue
Block a user