mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 08:42:39 +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` | ||||
| * 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