mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 08:42:39 +01:00 
			
		
		
		
	Inverted dependency between MemoryPool and string adapters.
Inserted a null after each raw string in the pool.
This commit is contained in:
		| @@ -102,13 +102,13 @@ TEST_CASE("JsonArray::add()") { | ||||
|  | ||||
|   SECTION("should duplicate char*") { | ||||
|     array.add(const_cast<char*>("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(5); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string") { | ||||
|     array.add(std::string("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(5); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -119,13 +119,13 @@ TEST_CASE("JsonArray::operator[]") { | ||||
|  | ||||
|   SECTION("should duplicate char*") { | ||||
|     array[0] = const_cast<char*>("world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(5); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string") { | ||||
|     array[0] = std::string("world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(5); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -56,7 +56,7 @@ TEST_CASE("deserialize JSON array with a StaticJsonDocument") { | ||||
|  | ||||
|     deserializeJson(doc, "  [ \"1234567\" ] "); | ||||
|  | ||||
|     REQUIRE(JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(8) == doc.memoryUsage()); | ||||
|     REQUIRE(JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(7) == doc.memoryUsage()); | ||||
|     // note: we use a string of 8 bytes to be sure that the StaticMemoryPool | ||||
|     // will not insert bytes to enforce alignement | ||||
|   } | ||||
|   | ||||
| @@ -94,8 +94,8 @@ TEST_CASE("BasicJsonDocument::shrinkToFit()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("owned raw") { | ||||
|     doc.set(serialized(std::string("[{},123]"))); | ||||
|     testShrinkToFit(doc, "[{},123]", 8); | ||||
|     doc.set(serialized(std::string("[{},12]"))); | ||||
|     testShrinkToFit(doc, "[{},12]", 8); | ||||
|   } | ||||
|  | ||||
|   SECTION("linked key") { | ||||
|   | ||||
| @@ -107,43 +107,43 @@ TEST_CASE("JsonObject::operator[]") { | ||||
|  | ||||
|   SECTION("should duplicate char* value") { | ||||
|     obj["hello"] = const_cast<char*>("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(5); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* key") { | ||||
|     obj[const_cast<char*>("hello")] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(5); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* key&value") { | ||||
|     obj[const_cast<char*>("hello")] = const_cast<char*>("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 2 * JSON_STRING_SIZE(6); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 2 * JSON_STRING_SIZE(5); | ||||
|     REQUIRE(expectedSize <= doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string value") { | ||||
|     obj["hello"] = std::string("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(5); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string key") { | ||||
|     obj[std::string("hello")] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(5); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string key&value") { | ||||
|     obj[std::string("hello")] = std::string("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 2 * JSON_STRING_SIZE(6); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 2 * JSON_STRING_SIZE(5); | ||||
|     REQUIRE(expectedSize <= doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate a non-static JsonString key") { | ||||
|     obj[JsonString("hello", false)] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(5); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -47,20 +47,20 @@ TEST_CASE("JsonVariant::set(JsonVariant)") { | ||||
|     var1.set(str); | ||||
|     var2.set(var1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(7)); | ||||
|     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7)); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores std::string by copy") { | ||||
|     var1.set(std::string("hello!!")); | ||||
|     var2.set(var1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(7)); | ||||
|     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7)); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores Serialized<const char*> by reference") { | ||||
|     var1.set(serialized("hello!!", JSON_STRING_SIZE(8))); | ||||
|     var1.set(serialized("hello!!", 8)); | ||||
|     var2.set(var1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == 0); | ||||
| @@ -69,18 +69,18 @@ TEST_CASE("JsonVariant::set(JsonVariant)") { | ||||
|  | ||||
|   SECTION("stores Serialized<char*> by copy") { | ||||
|     char str[] = "hello!!"; | ||||
|     var1.set(serialized(str, 8)); | ||||
|     var1.set(serialized(str, 7)); | ||||
|     var2.set(var1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(7)); | ||||
|     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7)); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores Serialized<std::string> by copy") { | ||||
|     var1.set(serialized(std::string("hello!!!"))); | ||||
|     var1.set(serialized(std::string("hello!!"))); | ||||
|     var2.set(var1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(7)); | ||||
|     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7)); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -36,6 +36,6 @@ TEST_CASE("StringBuilder") { | ||||
|     str.append('h'); | ||||
|     str.complete(); | ||||
|  | ||||
|     REQUIRE(JSON_STRING_SIZE(2) == pool.size()); | ||||
|     REQUIRE(JSON_STRING_SIZE(1) == pool.size()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -30,19 +30,19 @@ TEST_CASE("MemoryPool::size()") { | ||||
|   SECTION("Decreases after freezeString()") { | ||||
|     StringSlot a = pool.allocExpandableString(); | ||||
|     pool.freezeString(a, 1); | ||||
|     REQUIRE(pool.size() == JSON_STRING_SIZE(1)); | ||||
|     REQUIRE(pool.size() == 1); | ||||
|  | ||||
|     StringSlot b = pool.allocExpandableString(); | ||||
|     pool.freezeString(b, 1); | ||||
|     REQUIRE(pool.size() == 2 * JSON_STRING_SIZE(1)); | ||||
|     REQUIRE(pool.size() == 2); | ||||
|   } | ||||
|  | ||||
|   SECTION("Increases after allocFrozenString()") { | ||||
|     pool.allocFrozenString(0); | ||||
|     REQUIRE(pool.size() == JSON_STRING_SIZE(0)); | ||||
|     pool.allocFrozenString(1); | ||||
|     REQUIRE(pool.size() == 1); | ||||
|  | ||||
|     pool.allocFrozenString(0); | ||||
|     REQUIRE(pool.size() == 2 * JSON_STRING_SIZE(0)); | ||||
|     pool.allocFrozenString(2); | ||||
|     REQUIRE(pool.size() == 3); | ||||
|   } | ||||
|  | ||||
|   SECTION("Doesn't grow when memory pool is full") { | ||||
|   | ||||
| @@ -145,4 +145,12 @@ TEST_CASE("IsString<T>") { | ||||
|   SECTION("const __FlashStringHelper*") { | ||||
|     CHECK(IsString<const __FlashStringHelper*>::value == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("const char*") { | ||||
|     CHECK(IsString<const char*>::value == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("const char[]") { | ||||
|     CHECK(IsString<const char[8]>::value == true); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -7,9 +7,9 @@ | ||||
|  | ||||
| template <size_t Capacity> | ||||
| static void check(const char* input, DeserializationError expected) { | ||||
|   StaticJsonDocument<Capacity> variant; | ||||
|   StaticJsonDocument<Capacity> doc; | ||||
|  | ||||
|   DeserializationError error = deserializeMsgPack(variant, input); | ||||
|   DeserializationError error = deserializeMsgPack(doc, input); | ||||
|  | ||||
|   CAPTURE(input); | ||||
|   REQUIRE(error == expected); | ||||
| @@ -17,7 +17,7 @@ static void check(const char* input, DeserializationError expected) { | ||||
|  | ||||
| template <size_t Size> | ||||
| static void checkString(const char* input, DeserializationError expected) { | ||||
|   check<JSON_STRING_SIZE(Size)>(input, expected); | ||||
|   check<Size>(input, expected); | ||||
| } | ||||
|  | ||||
| TEST_CASE("deserializeMsgPack(StaticJsonDocument&)") { | ||||
|   | ||||
| @@ -60,6 +60,19 @@ class MemoryPool { | ||||
|     return s; | ||||
|   } | ||||
|  | ||||
|   template <typename TAdaptedString> | ||||
|   char* saveString(const TAdaptedString& str) { | ||||
|     if (str.isNull()) | ||||
|       return 0; | ||||
|     size_t n = str.size(); | ||||
|     char* dup = allocFrozenString(n + 1); | ||||
|     if (dup) { | ||||
|       str.copyTo(dup, n); | ||||
|       dup[n] = 0;  // force null-terminator | ||||
|     } | ||||
|     return dup; | ||||
|   } | ||||
|  | ||||
|   StringSlot allocExpandableString() { | ||||
|     StringSlot s; | ||||
|     s.value = _left; | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  | ||||
| #include <ArduinoJson/Namespace.hpp> | ||||
|  | ||||
| #define JSON_STRING_SIZE(SIZE) (SIZE) | ||||
| #define JSON_STRING_SIZE(SIZE) (SIZE + 1) | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
|   | ||||
| @@ -16,14 +16,8 @@ class ArduinoStringAdapter { | ||||
|  public: | ||||
|   ArduinoStringAdapter(const ::String& str) : _str(&str) {} | ||||
|  | ||||
|   char* save(MemoryPool* pool) const { | ||||
|     if (isNull()) | ||||
|       return NULL; | ||||
|     size_t n = _str->length() + 1; | ||||
|     char* dup = pool->allocFrozenString(n); | ||||
|     if (dup) | ||||
|       memcpy(dup, _str->c_str(), n); | ||||
|     return dup; | ||||
|   void copyTo(char* p, size_t n) const { | ||||
|     memcpy(p, _str->c_str(), n); | ||||
|   } | ||||
|  | ||||
|   bool isNull() const { | ||||
| @@ -45,7 +39,7 @@ class ArduinoStringAdapter { | ||||
|     return _str->length(); | ||||
|   } | ||||
|  | ||||
|   typedef storage_policy::store_by_copy storage_policy; | ||||
|   typedef storage_policies::store_by_copy storage_policy; | ||||
|  | ||||
|  private: | ||||
|   const ::String* _str; | ||||
|   | ||||
| @@ -39,12 +39,18 @@ class ConstRamStringAdapter { | ||||
|     return _str; | ||||
|   } | ||||
|  | ||||
|   typedef storage_policy::store_by_address storage_policy; | ||||
|   typedef storage_policies::store_by_address storage_policy; | ||||
|  | ||||
|  protected: | ||||
|   const char* _str; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct IsString<const char*> : true_type {}; | ||||
|  | ||||
| template <int N> | ||||
| struct IsString<const char[N]> : true_type {}; | ||||
|  | ||||
| inline ConstRamStringAdapter adaptString(const char* str) { | ||||
|   return ConstRamStringAdapter(str); | ||||
| } | ||||
|   | ||||
| @@ -4,7 +4,6 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ArduinoJson/Memory/MemoryPool.hpp> | ||||
| #include <ArduinoJson/Polyfills/pgmspace.hpp> | ||||
| #include <ArduinoJson/Strings/IsString.hpp> | ||||
| #include <ArduinoJson/Strings/StoragePolicy.hpp> | ||||
| @@ -33,14 +32,8 @@ class FlashStringAdapter { | ||||
|     return !_str; | ||||
|   } | ||||
|  | ||||
|   char* save(MemoryPool* pool) const { | ||||
|     if (!_str) | ||||
|       return NULL; | ||||
|     size_t n = size() + 1;  // copy the terminator | ||||
|     char* dup = pool->allocFrozenString(n); | ||||
|     if (dup) | ||||
|       memcpy_P(dup, reinterpret_cast<const char*>(_str), n); | ||||
|     return dup; | ||||
|   void copyTo(char* p, size_t n) const { | ||||
|     memcpy_P(p, reinterpret_cast<const char*>(_str), n); | ||||
|   } | ||||
|  | ||||
|   size_t size() const { | ||||
| @@ -49,7 +42,7 @@ class FlashStringAdapter { | ||||
|     return strlen_P(reinterpret_cast<const char*>(_str)); | ||||
|   } | ||||
|  | ||||
|   typedef storage_policy::store_by_copy storage_policy; | ||||
|   typedef storage_policies::store_by_copy storage_policy; | ||||
|  | ||||
|  private: | ||||
|   const __FlashStringHelper* _str; | ||||
|   | ||||
| @@ -4,7 +4,6 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ArduinoJson/Memory/MemoryPool.hpp> | ||||
| #include <ArduinoJson/Strings/ConstRamStringAdapter.hpp> | ||||
| #include <ArduinoJson/Strings/IsString.hpp> | ||||
| #include <ArduinoJson/Strings/StoragePolicy.hpp> | ||||
| @@ -15,17 +14,11 @@ class RamStringAdapter : public ConstRamStringAdapter { | ||||
|  public: | ||||
|   RamStringAdapter(const char* str) : ConstRamStringAdapter(str) {} | ||||
|  | ||||
|   char* save(MemoryPool* pool) const { | ||||
|     if (!_str) | ||||
|       return NULL; | ||||
|     size_t n = size() + 1; | ||||
|     char* dup = pool->allocFrozenString(n); | ||||
|     if (dup) | ||||
|       memcpy(dup, _str, n); | ||||
|     return dup; | ||||
|   void copyTo(char* p, size_t n) const { | ||||
|     memcpy(p, _str, n); | ||||
|   } | ||||
|  | ||||
|   typedef ARDUINOJSON_NAMESPACE::storage_policy::store_by_copy storage_policy; | ||||
|   typedef ARDUINOJSON_NAMESPACE::storage_policies::store_by_copy storage_policy; | ||||
| }; | ||||
|  | ||||
| template <typename TChar> | ||||
|   | ||||
| @@ -33,20 +33,15 @@ class SizedFlashStringAdapter { | ||||
|     return !_str; | ||||
|   } | ||||
|  | ||||
|   char* save(MemoryPool* pool) const { | ||||
|     if (!_str) | ||||
|       return NULL; | ||||
|     char* dup = pool->allocFrozenString(_size); | ||||
|     if (dup) | ||||
|       memcpy_P(dup, reinterpret_cast<const char*>(_str), _size); | ||||
|     return dup; | ||||
|   void copyTo(char* p, size_t n) const { | ||||
|     memcpy_P(p, reinterpret_cast<const char*>(_str), n); | ||||
|   } | ||||
|  | ||||
|   size_t size() const { | ||||
|     return _size; | ||||
|   } | ||||
|  | ||||
|   typedef storage_policy::store_by_copy storage_policy; | ||||
|   typedef storage_policies::store_by_copy storage_policy; | ||||
|  | ||||
|  private: | ||||
|   const __FlashStringHelper* _str; | ||||
|   | ||||
| @@ -28,20 +28,15 @@ class SizedRamStringAdapter { | ||||
|     return !_str; | ||||
|   } | ||||
|  | ||||
|   char* save(MemoryPool* pool) const { | ||||
|     if (!_str) | ||||
|       return NULL; | ||||
|     char* dup = pool->allocFrozenString(_size); | ||||
|     if (dup) | ||||
|       memcpy(dup, _str, _size); | ||||
|     return dup; | ||||
|   void copyTo(char* p, size_t n) const { | ||||
|     memcpy(p, _str, n); | ||||
|   } | ||||
|  | ||||
|   size_t size() const { | ||||
|     return _size; | ||||
|   } | ||||
|  | ||||
|   typedef storage_policy::store_by_copy storage_policy; | ||||
|   typedef storage_policies::store_by_copy storage_policy; | ||||
|  | ||||
|  private: | ||||
|   const char* _str; | ||||
|   | ||||
| @@ -4,7 +4,6 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ArduinoJson/Memory/MemoryPool.hpp> | ||||
| #include <ArduinoJson/Namespace.hpp> | ||||
| #include <ArduinoJson/Strings/IsString.hpp> | ||||
| #include <ArduinoJson/Strings/StoragePolicy.hpp> | ||||
| @@ -18,12 +17,8 @@ class StlStringAdapter { | ||||
|  public: | ||||
|   StlStringAdapter(const TString& str) : _str(&str) {} | ||||
|  | ||||
|   char* save(MemoryPool* pool) const { | ||||
|     size_t n = _str->length() + 1; | ||||
|     char* dup = pool->allocFrozenString(n); | ||||
|     if (dup) | ||||
|       memcpy(dup, _str->c_str(), n); | ||||
|     return dup; | ||||
|   void copyTo(char* p, size_t n) const { | ||||
|     memcpy(p, _str->c_str(), n); | ||||
|   } | ||||
|  | ||||
|   bool isNull() const { | ||||
| @@ -46,7 +41,7 @@ class StlStringAdapter { | ||||
|     return _str->size(); | ||||
|   } | ||||
|  | ||||
|   typedef storage_policy::store_by_copy storage_policy; | ||||
|   typedef storage_policies::store_by_copy storage_policy; | ||||
|  | ||||
|  private: | ||||
|   const TString* _str; | ||||
|   | ||||
| @@ -6,10 +6,10 @@ | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| namespace storage_policy { | ||||
| namespace storage_policies { | ||||
| struct store_by_address {}; | ||||
| struct store_by_copy {}; | ||||
| struct decide_at_runtime {}; | ||||
| }  // namespace storage_policy | ||||
| }  // namespace storage_policies | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
| @@ -38,8 +38,6 @@ class String { | ||||
|     return strcmp(lhs._data, rhs._data) == 0; | ||||
|   } | ||||
|  | ||||
|   typedef storage_policy::decide_at_runtime storage_policy; | ||||
|  | ||||
|  private: | ||||
|   const char* _data; | ||||
|   bool _isStatic; | ||||
| @@ -54,11 +52,7 @@ class StringAdapter : public RamStringAdapter { | ||||
|     return _isStatic; | ||||
|   } | ||||
|  | ||||
|   const char* save(MemoryPool* pool) const { | ||||
|     if (_isStatic) | ||||
|       return data(); | ||||
|     return RamStringAdapter::save(pool); | ||||
|   } | ||||
|   typedef storage_policies::decide_at_runtime storage_policy; | ||||
|  | ||||
|  private: | ||||
|   bool _isStatic; | ||||
|   | ||||
| @@ -18,17 +18,17 @@ inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool) { | ||||
|  | ||||
| template <typename TAdaptedString> | ||||
| inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool, | ||||
|                        storage_policy::decide_at_runtime) { | ||||
|                        storage_policies::decide_at_runtime) { | ||||
|   if (key.isStatic()) { | ||||
|     return slotSetKey(var, key, pool, storage_policy::store_by_address()); | ||||
|     return slotSetKey(var, key, pool, storage_policies::store_by_address()); | ||||
|   } else { | ||||
|     return slotSetKey(var, key, pool, storage_policy::store_by_copy()); | ||||
|     return slotSetKey(var, key, pool, storage_policies::store_by_copy()); | ||||
|   } | ||||
| } | ||||
|  | ||||
| template <typename TAdaptedString> | ||||
| inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool*, | ||||
|                        storage_policy::store_by_address) { | ||||
|                        storage_policies::store_by_address) { | ||||
|   ARDUINOJSON_ASSERT(var); | ||||
|   var->setLinkedKey(make_not_null(key.data())); | ||||
|   return true; | ||||
| @@ -36,8 +36,8 @@ inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool*, | ||||
|  | ||||
| template <typename TAdaptedString> | ||||
| inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool, | ||||
|                        storage_policy::store_by_copy) { | ||||
|   const char* dup = key.save(pool); | ||||
|                        storage_policies::store_by_copy) { | ||||
|   const char* dup = pool->saveString(key); | ||||
|   if (!dup) | ||||
|     return false; | ||||
|   ARDUINOJSON_ASSERT(var); | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ArduinoJson/Memory/MemoryPool.hpp> | ||||
| #include <ArduinoJson/Misc/SerializedValue.hpp> | ||||
| #include <ArduinoJson/Numbers/convertNumber.hpp> | ||||
| #include <ArduinoJson/Polyfills/gsl/not_null.hpp> | ||||
| @@ -191,7 +192,7 @@ class VariantData { | ||||
|  | ||||
|   template <typename T> | ||||
|   bool setOwnedRaw(SerializedValue<T> value, MemoryPool *pool) { | ||||
|     char *dup = adaptString(value.data(), value.size()).save(pool); | ||||
|     char *dup = pool->saveString(adaptString(value.data(), value.size())); | ||||
|     if (dup) { | ||||
|       setType(VALUE_IS_OWNED_RAW); | ||||
|       _content.asRaw.data = dup; | ||||
| @@ -265,9 +266,9 @@ class VariantData { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   bool setOwnedString(T value, MemoryPool *pool) { | ||||
|     return setOwnedString(value.save(pool)); | ||||
|   template <typename TAdaptedString> | ||||
|   bool setOwnedString(TAdaptedString value, MemoryPool *pool) { | ||||
|     return setOwnedString(pool->saveString(value)); | ||||
|   } | ||||
|  | ||||
|   CollectionData &toArray() { | ||||
|   | ||||
| @@ -119,11 +119,44 @@ inline bool variantSetOwnedString(VariantData *var, char *value) { | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| template <typename T> | ||||
| inline bool variantSetOwnedString(VariantData *var, T value, MemoryPool *pool) { | ||||
| template <typename TAdaptedString> | ||||
| inline bool variantSetOwnedString(VariantData *var, TAdaptedString value, | ||||
|                                   MemoryPool *pool) { | ||||
|   return var != 0 && var->setOwnedString(value, pool); | ||||
| } | ||||
|  | ||||
| template <typename TAdaptedString> | ||||
| inline bool variantSetString(VariantData *var, TAdaptedString value, | ||||
|                              MemoryPool *pool, | ||||
|                              storage_policies::decide_at_runtime) { | ||||
|   if (value.isStatic()) | ||||
|     return variantSetString(var, value, pool, | ||||
|                             storage_policies::store_by_address()); | ||||
|   else | ||||
|     return variantSetString(var, value, pool, | ||||
|                             storage_policies::store_by_copy()); | ||||
| } | ||||
|  | ||||
| template <typename TAdaptedString> | ||||
| inline bool variantSetString(VariantData *var, TAdaptedString value, | ||||
|                              MemoryPool *pool) { | ||||
|   return variantSetString(var, value, pool, | ||||
|                           typename TAdaptedString::storage_policy()); | ||||
| } | ||||
|  | ||||
| template <typename TAdaptedString> | ||||
| inline bool variantSetString(VariantData *var, TAdaptedString value, | ||||
|                              MemoryPool *, storage_policies::store_by_address) { | ||||
|   return variantSetLinkedString(var, value.data()); | ||||
| } | ||||
|  | ||||
| template <typename TAdaptedString> | ||||
| inline bool variantSetString(VariantData *var, TAdaptedString value, | ||||
|                              MemoryPool *pool, | ||||
|                              storage_policies::store_by_copy) { | ||||
|   return variantSetOwnedString(var, value, pool); | ||||
| } | ||||
|  | ||||
| template <typename T> | ||||
| inline bool variantSetInteger(VariantData *var, T value) { | ||||
|   ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T); | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
| #include <ArduinoJson/Memory/MemoryPool.hpp> | ||||
| #include <ArduinoJson/Misc/Visitable.hpp> | ||||
| #include <ArduinoJson/Polyfills/type_traits.hpp> | ||||
| #include <ArduinoJson/Strings/StringAdapters.hpp> | ||||
| #include <ArduinoJson/Variant/VariantAs.hpp> | ||||
| #include <ArduinoJson/Variant/VariantFunctions.hpp> | ||||
| #include <ArduinoJson/Variant/VariantOperators.hpp> | ||||
| @@ -213,20 +214,15 @@ class VariantRef : public VariantRefBase<VariantData>, | ||||
|   FORCE_INLINE bool set( | ||||
|       const T &value, | ||||
|       typename enable_if<IsString<T>::value>::type * = 0) const { | ||||
|     return variantSetOwnedString(_data, adaptString(value), _pool); | ||||
|     return variantSetString(_data, adaptString(value), _pool); | ||||
|   } | ||||
|  | ||||
|   // set(char*) | ||||
|   // set(const __FlashStringHelper*) | ||||
|   // set(const char*) | ||||
|   template <typename T> | ||||
|   FORCE_INLINE bool set( | ||||
|       T *value, typename enable_if<IsString<T *>::value>::type * = 0) const { | ||||
|     return variantSetOwnedString(_data, adaptString(value), _pool); | ||||
|   } | ||||
|  | ||||
|   // set(const char*); | ||||
|   FORCE_INLINE bool set(const char *value) const { | ||||
|     return variantSetLinkedString(_data, value); | ||||
|     return variantSetString(_data, adaptString(value), _pool); | ||||
|   } | ||||
|  | ||||
|   // set(VariantRef) | ||||
| @@ -247,6 +243,14 @@ class VariantRef : public VariantRefBase<VariantData>, | ||||
|     return variantSetInteger(_data, static_cast<Integer>(value)); | ||||
|   } | ||||
|  | ||||
| #if ARDUINOJSON_HAS_NULLPTR | ||||
|   // set(nullptr_t) | ||||
|   FORCE_INLINE bool set(decltype(nullptr)) const { | ||||
|     variantSetNull(_data); | ||||
|     return true; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   template <typename T> | ||||
|   FORCE_INLINE typename VariantAs<T>::type as() const { | ||||
|     return variantAs<typename VariantAs<T>::type>(_data, _pool); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user