8000 Added copy-constructor and copy-assignment-operator for `JsonDocument… · java64/ArduinoJson@84f199f · GitHub
[go: up one dir, main page]

Skip to content

Commit 84f199f

Browse files
committed
Added copy-constructor and copy-assignment-operator for JsonDocument (issue bblanchon#827)
1 parent 8230f8f commit 84f199f

File tree

7 files changed

+204
-19
lines changed

7 files changed

+204
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ HEAD
1111
* Increased the default capacity of `DynamicJsonDocument`
1212
* Fixed `JsonVariant::is<String>()` (closes #763)
1313
* Added `JsonArrayConst`, `JsonObjectConst`, and `JsonVariantConst`
14+
* Added copy-constructor and copy-assignment-operator for `JsonDocument` (issue #827)
1415

1516
v6.4.0-beta (2018-09-11)
1617
-----------

src/ArduinoJson/JsonArraySubscript.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript>,
2020
: _array(array), _index(index) {}
2121

2222
FORCE_INLINE JsonArraySubscript& operator=(const JsonArraySubscript& src) {
23-
get_impl().set(src.as<JsonVariant>());
23+
get_impl().set(src.as<JsonVariantConst>());
2424
return *this;
2525
}
2626

src/ArduinoJson/JsonDocument.hpp

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ class JsonDocument : public Visitable {
1818

1919
JsonDocument() : nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {}
2020

21-
template <typename T>
22-
bool is() const {
23-
return getVariant().template is<T>();
21+
template <typename Visitor>
22+
void accept(Visitor& visitor) const {
23+
return getVariant().accept(visitor);
2424
}
2525

2626
template <typename T>
@@ -33,30 +33,37 @@ class JsonDocument : public Visitable {
3333
return getVariant().template as<T>();
3434
}
3535

36-
template <typename T>
37-
typename JsonVariantTo<T>::type to() {
38-
_memoryPool.clear();
39-
return getVariant().template to<T>();
40-
}
41-
4236
void clear() {
4337
_memoryPool.clear();
4438
_rootData.type = JSON_NULL;
4539
}
4640

47-
size_t memoryUsage() const {
48-
return _memoryPool.size();
41+
template <typename T>
42+
bool is() const {
43+
return getVariant().template is<T>();
4944
}
5045

51-
template <typename Visitor>
52-
void accept(Visitor& visitor) const {
53-
return getVariant().accept(visitor);
46+
size_t memoryUsage() const {
47+
return _memoryPool.size();
5448
}
5549

5650
TMemoryPool& memoryPool() {
5751
return _memoryPool;
5852
}
5953

54+
template <typename T>
55+
typename JsonVariantTo<T>::type to() {
56+
_memoryPool.clear();
57+
return getVariant().template to<T>();
58+
}
59+
60+
protected:
61+
template <typename T>
62+
void copy(const JsonDocument<T>& src) {
63+
nestingLimit = src.nestingLimit;
64+
to<JsonVariant>().set(src.template as<JsonVariant>());
65+
}
66+
6067
private:
6168
JsonVariant getVariant() {
6269
return JsonVariant(&_memoryPool, &_rootData);
@@ -76,14 +83,49 @@ class DynamicJsonDocument : public JsonDocument<DynamicMemoryPool> {
7683
DynamicJsonDocument(size_t capacity) {
7784
memoryPool().reserve(capacity);
7885
}
86+
87+
DynamicJsonDocument(const DynamicJsonDocument& src) {
88+
memoryPool().reserve(src.memoryUsage());
89+
copy(src);
90+
}
91+
92+
template <typename T>
93+
DynamicJsonDocument(const JsonDocument<T>& src) {
94+
memoryPool().reserve(src.memoryUsage());
95+
copy(src);
96+
}
97+
98+
DynamicJsonDocument& operator=(const DynamicJsonDocument& src) {
99+
copy(src);
100+
return *this;
101+
}
102+
103+
template <typename T>
104+
DynamicJsonDocument& operator=(const JsonDocument<T>& src) {
105+
copy(src);
106+
return *this;
107+
}
79108
};
80109

81110
template <size_t CAPACITY>
82111
class StaticJsonDocument : public JsonDocument<StaticMemoryPool<CAPACITY> > {
83112
public:
113+
StaticJsonDocument() {}
114+
115+
template <typename T>
116+
StaticJsonDocument(const JsonDocument<T>& src) {
117+
this->copy(src);
118+
}
119+
84120
StaticMemoryPoolBase& memoryPool() {
85121
return JsonDocument<StaticMemoryPool<CAPACITY> >::memoryPool();
86122
}
123+
124+
template <typename T>
125+
StaticJsonDocument operator=(const JsonDocument<T>& src) {
126+
this->copy(src);
127+
return *this;
128+
}
87129
};
88130

89131
} // namespace ARDUINOJSON_NAMESPACE

src/ArduinoJson/JsonVariant.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ class JsonVariant : public JsonVariantProxy<JsonVariantData>,
209209
return variantSetString(_data, value, _memoryPool);
210210
}
211211

212-
bool set(const JsonVariant &value) const;
212+
bool set(JsonVariantConst value) const;
213+
bool set(JsonVariant value) const;
213214

214215
FORCE_INLINE bool set(JsonArray array) const;
215216
FORCE_INLINE bool set(const JsonArraySubscript &) const;
@@ -284,6 +285,7 @@ class JsonVariantConst : public JsonVariantProxy<const JsonVariantData>,
284285
public JsonVariantBase<JsonVariantConst>,
285286
public Visitable {
286287
typedef JsonVariantProxy<const JsonVariantData> proxy_type;
288+
friend class JsonVariant;
287289

288290
public:
289291
JsonVariantConst() : proxy_type(0) {}

src/ArduinoJson/JsonVariantImpl.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ inline bool JsonVariant::set(const JsonObjectSubscript<TString>& value) const {
3030
return set(value.template as<JsonVariant>());
3131
}
3232

33-
inline bool JsonVariant::set(const JsonVariant& value) const {
33+
inline bool JsonVariant::set(JsonVariantConst value) const {
34+
return variantCopy(_data, value._data, _memoryPool);
35+
}
36+
37+
inline bool JsonVariant::set(JsonVariant value) const {
3438
return variantCopy(_data, value._data, _memoryPool);
3539
}
3640

test/JsonDocument/DynamicJsonDocument.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,58 @@ TEST_CASE("DynamicJsonDocument") {
3838
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(0));
3939
}
4040
}
41+
42+
SECTION("Copy constructor") {
43+
deserializeJson(doc, "{\"hello\":\"world\"}");
44+
doc.nestingLimit = 42;
45+
46+
DynamicJsonDocument doc2 = doc;
47+
48+
std::string json;
49+
serializeJson(doc2, json);
50+
REQUIRE(json == "{\"hello\":\"world\"}");
51+
REQUIRE(doc2.nestingLimit == 42);
52+
}
53+
54+
SECTION("Copy assignment") {
55+
DynamicJsonDocument doc2;
56+
deserializeJson(doc2, "{\"hello\":\"world\"}");
57+
doc2.nestingLimit = 42;
58+
59+
doc = doc2;
60+
61+
std::string json;
62+
serializeJson(doc, json);
63+
REQUIRE(json == "{\"hello\":\"world\"}");
64+
REQUIRE(doc.nestingLimit == 42);
65+
}
66+
67+
SECTION("Construct from StaticJsonDocument") {
68+
StaticJsonDocument<200> sdoc;
69+
deserializeJson(sdoc, "{\"hello\":\"world\"}");
70+
sdoc.nestingLimit = 42;
71+
72+
DynamicJsonDocument ddoc = sdoc;
73+
74+
std::string json;
75+
serializeJson(ddoc, json);
76+
REQUIRE(json == "{\"hello\":\"world\"}");
77+
REQUIRE(ddoc.nestingLimit == 42);
78+
}
79+
80+
SECTION("Assign from StaticJsonDocument") {
81+
DynamicJsonDocument ddoc;
82+
ddoc.to<JsonVariant>().set(666);
83+
84+
StaticJsonDocument<200> sdoc;
85+
deserializeJson(sdoc, "{\"hello\":\"world\"}");
86+
sdoc.nestingLimit = 42;
87+
88+
ddoc = sdoc;
89+
90+
std::string json;
91+
serializeJson(ddoc, json);
92+
REQUIRE(json == "{\"hello\":\"world\"}");
93+
REQUIRE(ddoc.nestingLimit == 42);
94+
}
4195
}

test/JsonDocument/StaticJsonDocument.cpp

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66
#include <catch.hpp>
77

88
TEST_CASE("StaticJsonDocument") {
9-
StaticJsonDocument<200> doc;
10-
119
SECTION("serializeJson()") {
10+
StaticJsonDocument<200> doc;
1211
JsonObject obj = doc.to<JsonObject>();
1312
obj["hello"] = "world";
1413

@@ -17,4 +16,87 @@ TEST_CASE("StaticJsonDocument") {
1716

1817
REQUIRE(json == "{\"hello\":\"world\"}");
1918
}
19+
20+
SECTION("Copy assignment") {
21+
StaticJsonDocument<200> doc1, doc2;
22+
doc1.to<JsonVariant>().set(666);
23+
deserializeJson(doc2, "{\"hello\":\"world\"}");
24+
doc2.nestingLimit = 42;
25+
26+
doc1 = doc2;
27+
28+
std::string json;
29+
serializeJson(doc1, json);
30+
REQUIRE(json == "{\"hello\":\"world\"}");
31+
REQUIRE(doc1.nestingLimit == 42);
32+
}
33+
34+
SECTION("Copy constructor") {
35+
StaticJsonDocument<200> doc1;
36+
deserializeJson(doc1, "{\"hello\":\"world\"}");
37+
doc1.nestingLimit = 42;
38+
39+
StaticJsonDocument<200> doc2 = doc1;
40+
41+
std::string json;
42+
serializeJson(doc2, json);
43+
REQUIRE(json == "{\"hello\":\"world\"}");
44+
REQUIRE(doc2.nestingLimit == 42);
45+
}
46+
47+
SECTION("Assign from StaticJsonDocument of different capacity") {
48+
StaticJsonDocument<200> doc1;
49+
StaticJsonDocument<300> doc2;
50+
doc1.to<JsonVariant>().set(666);
51+
deserializeJson(doc2, "{\"hello\":\"world\"}");
52+
doc2.nestingLimit = 42;
53+
54+
doc1 = doc2;
55+
56+
std::string json;
57+
serializeJson(doc1, json);
58+
REQUIRE(json == "{\"hello\":\"world\"}");
59+
REQUIRE(doc1.nestingLimit == 42);
60+
}
61+
62+
SECTION("Assign from DynamicJsonDocument") {
63+
StaticJsonDocument<200> doc1;
64+
DynamicJsonDocument doc2;
65+
doc1.to<JsonVariant>().set(666);
66+
deserializeJson(doc2, "{\"hello\":\"world\"}");
67+
doc2.nestingLimit = 42;
68+
69+
doc1 = doc2;
70+
71+
std::string json;
72+
serializeJson(doc1, json);
73+
REQUIRE(json == "{\"hello\":\"world\"}");
74+
REQUIRE(doc1.nestingLimit == 42);
75+
}
76+
77+
SECTION("Construct from StaticJsonDocument of different size") {
78+
StaticJsonDocument<300> doc2;
79+
deserializeJson(doc2, "{\"hello\":\"world\"}");
80+
doc2.nestingLimit = 42;
81+
82+
StaticJsonDocument<200> doc1 = doc2;
83+
84+
std::string json;
85+
serializeJson(doc1, json);
86+
REQUIRE(json == "{\"hello\":\"world\"}");
87+
REQUIRE(doc1.nestingLimit == 42);
88+
}
89+
90+
SECTION("Construct from DynamicJsonDocument") {
91+
DynamicJsonDocument doc2;
92+
deserializeJson(doc2, "{\"hello\":\"world\"}");
93+
doc2.nestingLimit = 42;
94+
95+
StaticJsonDocument<200> doc1 = doc2;
96+
97+
std::string json;
98+
serializeJson(doc1, json);
99+
REQUIRE(json == "{\"hello\":\"world\"}");
100+
REQUIRE(doc1.nestingLimit == 42);
101+
}
20102
}

0 commit comments

Comments
 (0)
0