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`
|
||||
* Fixed `JsonVariant::is<String>()` (closes #763)
|
||||
* Added `JsonArrayConst`, `JsonObjectConst`, and `JsonVariantConst`
|
||||
* Added copy-constructor and copy-assignment-operator for `JsonDocument` (issue #827)
|
||||
|
||||
v6.4.0-beta (2018-09-11)
|
||||
-----------
|
||||
|
@ -20,7 +20,7 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript>,
|
||||
: _array(array), _index(index) {}
|
||||
|
||||
FORCE_INLINE JsonArraySubscript& operator=(const JsonArraySubscript& src) {
|
||||
get_impl().set(src.as<JsonVariant>());
|
||||
get_impl().set(src.as<JsonVariantConst>());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -18,9 +18,9 @@ class JsonDocument : public Visitable {
|
||||
|
||||
JsonDocument() : nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {}
|
||||
|
||||
template <typename T>
|
||||
bool is() const {
|
||||
return getVariant().template is<T>();
|
||||
template <typename Visitor>
|
||||
void accept(Visitor& visitor) const {
|
||||
return getVariant().accept(visitor);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -33,30 +33,37 @@ class JsonDocument : public Visitable {
|
||||
return getVariant().template as<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename JsonVariantTo<T>::type to() {
|
||||
_memoryPool.clear();
|
||||
return getVariant().template to<T>();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_memoryPool.clear();
|
||||
_rootData.type = JSON_NULL;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is() const {
|
||||
return getVariant().template is<T>();
|
||||
}
|
||||
|
||||
size_t memoryUsage() const {
|
||||
return _memoryPool.size();
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
void accept(Visitor& visitor) const {
|
||||
return getVariant().accept(visitor);
|
||||
}
|
||||
|
||||
TMemoryPool& 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:
|
||||
JsonVariant getVariant() {
|
||||
return JsonVariant(&_memoryPool, &_rootData);
|
||||
@ -76,14 +83,49 @@ class DynamicJsonDocument : public JsonDocument<DynamicMemoryPool> {
|
||||
DynamicJsonDocument(size_t 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>
|
||||
class StaticJsonDocument : public JsonDocument<StaticMemoryPool<CAPACITY> > {
|
||||
public:
|
||||
StaticJsonDocument() {}
|
||||
|
||||
template <typename T>
|
||||
StaticJsonDocument(const JsonDocument<T>& src) {
|
||||
this->copy(src);
|
||||
}
|
||||
|
||||
StaticMemoryPoolBase& memoryPool() {
|
||||
return JsonDocument<StaticMemoryPool<CAPACITY> >::memoryPool();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
StaticJsonDocument operator=(const JsonDocument<T>& src) {
|
||||
this->copy(src);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
@ -209,7 +209,8 @@ class JsonVariant : public JsonVariantProxy<JsonVariantData>,
|
||||
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(const JsonArraySubscript &) const;
|
||||
@ -284,6 +285,7 @@ class JsonVariantConst : public JsonVariantProxy<const JsonVariantData>,
|
||||
public JsonVariantBase<JsonVariantConst>,
|
||||
public Visitable {
|
||||
typedef JsonVariantProxy<const JsonVariantData> proxy_type;
|
||||
friend class JsonVariant;
|
||||
|
||||
public:
|
||||
JsonVariantConst() : proxy_type(0) {}
|
||||
|
@ -30,7 +30,11 @@ inline bool JsonVariant::set(const JsonObjectSubscript<TString>& value) const {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -38,4 +38,58 @@ TEST_CASE("DynamicJsonDocument") {
|
||||
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>
|
||||
|
||||
TEST_CASE("StaticJsonDocument") {
|
||||
StaticJsonDocument<200> doc;
|
||||
|
||||
SECTION("serializeJson()") {
|
||||
StaticJsonDocument<200> doc;
|
||||
JsonObject obj = doc.to<JsonObject>();
|
||||
obj["hello"] = "world";
|
||||
|
||||
@ -17,4 +16,87 @@ TEST_CASE("StaticJsonDocument") {
|
||||
|
||||
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