mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	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