forked from bblanchon/ArduinoJson
Added copy-constructor and copy-assignment-operator for JsonDocument
(issue #827)
This commit is contained in:
@ -11,6 +11,7 @@ HEAD
|
|||||||
* Increased the default capacity of `DynamicJsonDocument`
|
* Increased the default capacity of `DynamicJsonDocument`
|
||||||
* Fixed `JsonVariant::is<String>()` (closes #763)
|
* Fixed `JsonVariant::is<String>()` (closes #763)
|
||||||
* Added `JsonArrayConst`, `JsonObjectConst`, and `JsonVariantConst`
|
* Added `JsonArrayConst`, `JsonObjectConst`, and `JsonVariantConst`
|
||||||
|
* Added copy-constructor and copy-assignment-operator for `JsonDocument` (issue #827)
|
||||||
|
|
||||||
v6.4.0-beta (2018-09-11)
|
v6.4.0-beta (2018-09-11)
|
||||||
-----------
|
-----------
|
||||||
|
@ -20,7 +20,7 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript>,
|
|||||||
: _array(array), _index(index) {}
|
: _array(array), _index(index) {}
|
||||||
|
|
||||||
FORCE_INLINE JsonArraySubscript& operator=(const JsonArraySubscript& src) {
|
FORCE_INLINE JsonArraySubscript& operator=(const JsonArraySubscript& src) {
|
||||||
get_impl().set(src.as<JsonVariant>());
|
get_impl().set(src.as<JsonVariantConst>());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,9 +18,9 @@ class JsonDocument : public Visitable {
|
|||||||
|
|
||||||
JsonDocument() : nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {}
|
JsonDocument() : nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename Visitor>
|
||||||
bool is() const {
|
void accept(Visitor& visitor) const {
|
||||||
return getVariant().template is<T>();
|
return getVariant().accept(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -33,30 +33,37 @@ class JsonDocument : public Visitable {
|
|||||||
return getVariant().template as<T>();
|
return getVariant().template as<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
typename JsonVariantTo<T>::type to() {
|
|
||||||
_memoryPool.clear();
|
|
||||||
return getVariant().template to<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
_memoryPool.clear();
|
_memoryPool.clear();
|
||||||
_rootData.type = JSON_NULL;
|
_rootData.type = JSON_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool is() const {
|
||||||
|
return getVariant().template is<T>();
|
||||||
|
}
|
||||||
|
|
||||||
size_t memoryUsage() const {
|
size_t memoryUsage() const {
|
||||||
return _memoryPool.size();
|
return _memoryPool.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
void accept(Visitor& visitor) const {
|
|
||||||
return getVariant().accept(visitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
TMemoryPool& memoryPool() {
|
TMemoryPool& memoryPool() {
|
||||||
return _memoryPool;
|
return _memoryPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
typename JsonVariantTo<T>::type to() {
|
||||||
|
_memoryPool.clear();
|
||||||
|
return getVariant().template to<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template <typename T>
|
||||||
|
void copy(const JsonDocument<T>& src) {
|
||||||
|
nestingLimit = src.nestingLimit;
|
||||||
|
to<JsonVariant>().set(src.template as<JsonVariant>());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JsonVariant getVariant() {
|
JsonVariant getVariant() {
|
||||||
return JsonVariant(&_memoryPool, &_rootData);
|
return JsonVariant(&_memoryPool, &_rootData);
|
||||||
@ -76,14 +83,49 @@ class DynamicJsonDocument : public JsonDocument<DynamicMemoryPool> {
|
|||||||
DynamicJsonDocument(size_t capacity) {
|
DynamicJsonDocument(size_t capacity) {
|
||||||
memoryPool().reserve(capacity);
|
memoryPool().reserve(capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DynamicJsonDocument(const DynamicJsonDocument& src) {
|
||||||
|
memoryPool().reserve(src.memoryUsage());
|
||||||
|
copy(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
DynamicJsonDocument(const JsonDocument<T>& src) {
|
||||||
|
memoryPool().reserve(src.memoryUsage());
|
||||||
|
copy(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicJsonDocument& operator=(const DynamicJsonDocument& src) {
|
||||||
|
copy(src);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
DynamicJsonDocument& operator=(const JsonDocument<T>& src) {
|
||||||
|
copy(src);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <size_t CAPACITY>
|
template <size_t CAPACITY>
|
||||||
class StaticJsonDocument : public JsonDocument<StaticMemoryPool<CAPACITY> > {
|
class StaticJsonDocument : public JsonDocument<StaticMemoryPool<CAPACITY> > {
|
||||||
public:
|
public:
|
||||||
|
StaticJsonDocument() {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
StaticJsonDocument(const JsonDocument<T>& src) {
|
||||||
|
this->copy(src);
|
||||||
|
}
|
||||||
|
|
||||||
StaticMemoryPoolBase& memoryPool() {
|
StaticMemoryPoolBase& memoryPool() {
|
||||||
return JsonDocument<StaticMemoryPool<CAPACITY> >::memoryPool();
|
return JsonDocument<StaticMemoryPool<CAPACITY> >::memoryPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
StaticJsonDocument operator=(const JsonDocument<T>& src) {
|
||||||
|
this->copy(src);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
@ -209,7 +209,8 @@ class JsonVariant : public JsonVariantProxy<JsonVariantData>,
|
|||||||
return variantSetString(_data, value, _memoryPool);
|
return variantSetString(_data, value, _memoryPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set(const JsonVariant &value) const;
|
bool set(JsonVariantConst value) const;
|
||||||
|
bool set(JsonVariant value) const;
|
||||||
|
|
||||||
FORCE_INLINE bool set(JsonArray array) const;
|
FORCE_INLINE bool set(JsonArray array) const;
|
||||||
FORCE_INLINE bool set(const JsonArraySubscript &) const;
|
FORCE_INLINE bool set(const JsonArraySubscript &) const;
|
||||||
@ -284,6 +285,7 @@ class JsonVariantConst : public JsonVariantProxy<const JsonVariantData>,
|
|||||||
public JsonVariantBase<JsonVariantConst>,
|
public JsonVariantBase<JsonVariantConst>,
|
||||||
public Visitable {
|
public Visitable {
|
||||||
typedef JsonVariantProxy<const JsonVariantData> proxy_type;
|
typedef JsonVariantProxy<const JsonVariantData> proxy_type;
|
||||||
|
friend class JsonVariant;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JsonVariantConst() : proxy_type(0) {}
|
JsonVariantConst() : proxy_type(0) {}
|
||||||
|
@ -30,7 +30,11 @@ inline bool JsonVariant::set(const JsonObjectSubscript<TString>& value) const {
|
|||||||
return set(value.template as<JsonVariant>());
|
return set(value.template as<JsonVariant>());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool JsonVariant::set(const JsonVariant& value) const {
|
inline bool JsonVariant::set(JsonVariantConst value) const {
|
||||||
|
return variantCopy(_data, value._data, _memoryPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool JsonVariant::set(JsonVariant value) const {
|
||||||
return variantCopy(_data, value._data, _memoryPool);
|
return variantCopy(_data, value._data, _memoryPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,4 +38,58 @@ TEST_CASE("DynamicJsonDocument") {
|
|||||||
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(0));
|
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("Copy constructor") {
|
||||||
|
deserializeJson(doc, "{\"hello\":\"world\"}");
|
||||||
|
doc.nestingLimit = 42;
|
||||||
|
|
||||||
|
DynamicJsonDocument doc2 = doc;
|
||||||
|
|
||||||
|
std::string json;
|
||||||
|
serializeJson(doc2, json);
|
||||||
|
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||||
|
REQUIRE(doc2.nestingLimit == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Copy assignment") {
|
||||||
|
DynamicJsonDocument doc2;
|
||||||
|
deserializeJson(doc2, "{\"hello\":\"world\"}");
|
||||||
|
doc2.nestingLimit = 42;
|
||||||
|
|
||||||
|
doc = doc2;
|
||||||
|
|
||||||
|
std::string json;
|
||||||
|
serializeJson(doc, json);
|
||||||
|
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||||
|
REQUIRE(doc.nestingLimit == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Construct from StaticJsonDocument") {
|
||||||
|
StaticJsonDocument<200> sdoc;
|
||||||
|
deserializeJson(sdoc, "{\"hello\":\"world\"}");
|
||||||
|
sdoc.nestingLimit = 42;
|
||||||
|
|
||||||
|
DynamicJsonDocument ddoc = sdoc;
|
||||||
|
|
||||||
|
std::string json;
|
||||||
|
serializeJson(ddoc, json);
|
||||||
|
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||||
|
REQUIRE(ddoc.nestingLimit == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Assign from StaticJsonDocument") {
|
||||||
|
DynamicJsonDocument ddoc;
|
||||||
|
ddoc.to<JsonVariant>().set(666);
|
||||||
|
|
||||||
|
StaticJsonDocument<200> sdoc;
|
||||||
|
deserializeJson(sdoc, "{\"hello\":\"world\"}");
|
||||||
|
sdoc.nestingLimit = 42;
|
||||||
|
|
||||||
|
ddoc = sdoc;
|
||||||
|
|
||||||
|
std::string json;
|
||||||
|
serializeJson(ddoc, json);
|
||||||
|
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||||
|
REQUIRE(ddoc.nestingLimit == 42);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,8 @@
|
|||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
TEST_CASE("StaticJsonDocument") {
|
TEST_CASE("StaticJsonDocument") {
|
||||||
StaticJsonDocument<200> doc;
|
|
||||||
|
|
||||||
SECTION("serializeJson()") {
|
SECTION("serializeJson()") {
|
||||||
|
StaticJsonDocument<200> doc;
|
||||||
JsonObject obj = doc.to<JsonObject>();
|
JsonObject obj = doc.to<JsonObject>();
|
||||||
obj["hello"] = "world";
|
obj["hello"] = "world";
|
||||||
|
|
||||||
@ -17,4 +16,87 @@ TEST_CASE("StaticJsonDocument") {
|
|||||||
|
|
||||||
REQUIRE(json == "{\"hello\":\"world\"}");
|
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("Copy assignment") {
|
||||||
|
StaticJsonDocument<200> doc1, doc2;
|
||||||
|
doc1.to<JsonVariant>().set(666);
|
||||||
|
deserializeJson(doc2, "{\"hello\":\"world\"}");
|
||||||
|
doc2.nestingLimit = 42;
|
||||||
|
|
||||||
|
doc1 = doc2;
|
||||||
|
|
||||||
|
std::string json;
|
||||||
|
serializeJson(doc1, json);
|
||||||
|
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||||
|
REQUIRE(doc1.nestingLimit == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Copy constructor") {
|
||||||
|
StaticJsonDocument<200> doc1;
|
||||||
|
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||||
|
doc1.nestingLimit = 42;
|
||||||
|
|
||||||
|
StaticJsonDocument<200> doc2 = doc1;
|
||||||
|
|
||||||
|
std::string json;
|
||||||
|
serializeJson(doc2, json);
|
||||||
|
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||||
|
REQUIRE(doc2.nestingLimit == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Assign from StaticJsonDocument of different capacity") {
|
||||||
|
StaticJsonDocument<200> doc1;
|
||||||
|
StaticJsonDocument<300> doc2;
|
||||||
|
doc1.to<JsonVariant>().set(666);
|
||||||
|
deserializeJson(doc2, "{\"hello\":\"world\"}");
|
||||||
|
doc2.nestingLimit = 42;
|
||||||
|
|
||||||
|
doc1 = doc2;
|
||||||
|
|
||||||
|
std::string json;
|
||||||
|
serializeJson(doc1, json);
|
||||||
|
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||||
|
REQUIRE(doc1.nestingLimit == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Assign from DynamicJsonDocument") {
|
||||||
|
StaticJsonDocument<200> doc1;
|
||||||
|
DynamicJsonDocument doc2;
|
||||||
|
doc1.to<JsonVariant>().set(666);
|
||||||
|
deserializeJson(doc2, "{\"hello\":\"world\"}");
|
||||||
|
doc2.nestingLimit = 42;
|
||||||
|
|
||||||
|
doc1 = doc2;
|
||||||
|
|
||||||
|
std::string json;
|
||||||
|
serializeJson(doc1, json);
|
||||||
|
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||||
|
REQUIRE(doc1.nestingLimit == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Construct from StaticJsonDocument of different size") {
|
||||||
|
StaticJsonDocument<300> doc2;
|
||||||
|
deserializeJson(doc2, "{\"hello\":\"world\"}");
|
||||||
|
doc2.nestingLimit = 42;
|
||||||
|
|
||||||
|
StaticJsonDocument<200> doc1 = doc2;
|
||||||
|
|
||||||
|
std::string json;
|
||||||
|
serializeJson(doc1, json);
|
||||||
|
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||||
|
REQUIRE(doc1.nestingLimit == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Construct from DynamicJsonDocument") {
|
||||||
|
DynamicJsonDocument doc2;
|
||||||
|
deserializeJson(doc2, "{\"hello\":\"world\"}");
|
||||||
|
doc2.nestingLimit = 42;
|
||||||
|
|
||||||
|
StaticJsonDocument<200> doc1 = doc2;
|
||||||
|
|
||||||
|
std::string json;
|
||||||
|
serializeJson(doc1, json);
|
||||||
|
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||||
|
REQUIRE(doc1.nestingLimit == 42);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user