diff --git a/extras/tests/JsonArray/add.cpp b/extras/tests/JsonArray/add.cpp index 5309db70..4202fa9e 100644 --- a/extras/tests/JsonArray/add.cpp +++ b/extras/tests/JsonArray/add.cpp @@ -102,13 +102,13 @@ TEST_CASE("JsonArray::add()") { SECTION("should duplicate char*") { array.add(const_cast("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()); } diff --git a/extras/tests/JsonArray/subscript.cpp b/extras/tests/JsonArray/subscript.cpp index 492c70e0..51e89627 100644 --- a/extras/tests/JsonArray/subscript.cpp +++ b/extras/tests/JsonArray/subscript.cpp @@ -119,13 +119,13 @@ TEST_CASE("JsonArray::operator[]") { SECTION("should duplicate char*") { array[0] = const_cast("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()); } diff --git a/extras/tests/JsonDeserializer/array_static.cpp b/extras/tests/JsonDeserializer/array_static.cpp index 510b1595..574448c0 100644 --- a/extras/tests/JsonDeserializer/array_static.cpp +++ b/extras/tests/JsonDeserializer/array_static.cpp @@ -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 } diff --git a/extras/tests/JsonDocument/shrinkToFit.cpp b/extras/tests/JsonDocument/shrinkToFit.cpp index 4298e1f5..615912a3 100644 --- a/extras/tests/JsonDocument/shrinkToFit.cpp +++ b/extras/tests/JsonDocument/shrinkToFit.cpp @@ -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") { diff --git a/extras/tests/JsonObject/subscript.cpp b/extras/tests/JsonObject/subscript.cpp index a7ce6829..fec2928a 100644 --- a/extras/tests/JsonObject/subscript.cpp +++ b/extras/tests/JsonObject/subscript.cpp @@ -107,43 +107,43 @@ TEST_CASE("JsonObject::operator[]") { SECTION("should duplicate char* value") { obj["hello"] = const_cast("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("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("hello")] = const_cast("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()); } diff --git a/extras/tests/JsonVariant/copy.cpp b/extras/tests/JsonVariant/copy.cpp index 54f0ee57..6222b908 100644 --- a/extras/tests/JsonVariant/copy.cpp +++ b/extras/tests/JsonVariant/copy.cpp @@ -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 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 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 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)); } } diff --git a/extras/tests/MemoryPool/StringBuilder.cpp b/extras/tests/MemoryPool/StringBuilder.cpp index aabcd3d2..57810ce6 100644 --- a/extras/tests/MemoryPool/StringBuilder.cpp +++ b/extras/tests/MemoryPool/StringBuilder.cpp @@ -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()); } } diff --git a/extras/tests/MemoryPool/size.cpp b/extras/tests/MemoryPool/size.cpp index cd2799c2..0ab6e900 100644 --- a/extras/tests/MemoryPool/size.cpp +++ b/extras/tests/MemoryPool/size.cpp @@ -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") { diff --git a/extras/tests/Misc/StringAdapters.cpp b/extras/tests/Misc/StringAdapters.cpp index 52167d22..c299bef9 100644 --- a/extras/tests/Misc/StringAdapters.cpp +++ b/extras/tests/Misc/StringAdapters.cpp @@ -145,4 +145,12 @@ TEST_CASE("IsString") { SECTION("const __FlashStringHelper*") { CHECK(IsString::value == true); } + + SECTION("const char*") { + CHECK(IsString::value == true); + } + + SECTION("const char[]") { + CHECK(IsString::value == true); + } } diff --git a/extras/tests/MsgPackDeserializer/deserializeStaticVariant.cpp b/extras/tests/MsgPackDeserializer/deserializeStaticVariant.cpp index bc52fef3..9ae14a86 100644 --- a/extras/tests/MsgPackDeserializer/deserializeStaticVariant.cpp +++ b/extras/tests/MsgPackDeserializer/deserializeStaticVariant.cpp @@ -7,9 +7,9 @@ template static void check(const char* input, DeserializationError expected) { - StaticJsonDocument variant; + StaticJsonDocument 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 static void checkString(const char* input, DeserializationError expected) { - check(input, expected); + check(input, expected); } TEST_CASE("deserializeMsgPack(StaticJsonDocument&)") { diff --git a/src/ArduinoJson/Memory/MemoryPool.hpp b/src/ArduinoJson/Memory/MemoryPool.hpp index 7d3dbac5..439b5baf 100644 --- a/src/ArduinoJson/Memory/MemoryPool.hpp +++ b/src/ArduinoJson/Memory/MemoryPool.hpp @@ -60,6 +60,19 @@ class MemoryPool { return s; } + template + 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; diff --git a/src/ArduinoJson/Memory/StringSlot.hpp b/src/ArduinoJson/Memory/StringSlot.hpp index 05f940b1..47a2eb5f 100644 --- a/src/ArduinoJson/Memory/StringSlot.hpp +++ b/src/ArduinoJson/Memory/StringSlot.hpp @@ -8,7 +8,7 @@ #include -#define JSON_STRING_SIZE(SIZE) (SIZE) +#define JSON_STRING_SIZE(SIZE) (SIZE + 1) namespace ARDUINOJSON_NAMESPACE { diff --git a/src/ArduinoJson/Strings/ArduinoStringAdapter.hpp b/src/ArduinoJson/Strings/ArduinoStringAdapter.hpp index dab1d251..ce228ca7 100644 --- a/src/ArduinoJson/Strings/ArduinoStringAdapter.hpp +++ b/src/ArduinoJson/Strings/ArduinoStringAdapter.hpp @@ -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; diff --git a/src/ArduinoJson/Strings/ConstRamStringAdapter.hpp b/src/ArduinoJson/Strings/ConstRamStringAdapter.hpp index 7014079d..1edba1f5 100644 --- a/src/ArduinoJson/Strings/ConstRamStringAdapter.hpp +++ b/src/ArduinoJson/Strings/ConstRamStringAdapter.hpp @@ -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 : true_type {}; + +template +struct IsString : true_type {}; + inline ConstRamStringAdapter adaptString(const char* str) { return ConstRamStringAdapter(str); } diff --git a/src/ArduinoJson/Strings/FlashStringAdapter.hpp b/src/ArduinoJson/Strings/FlashStringAdapter.hpp index 8d78c1d6..1c280b95 100644 --- a/src/ArduinoJson/Strings/FlashStringAdapter.hpp +++ b/src/ArduinoJson/Strings/FlashStringAdapter.hpp @@ -4,7 +4,6 @@ #pragma once -#include #include #include #include @@ -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(_str), n); - return dup; + void copyTo(char* p, size_t n) const { + memcpy_P(p, reinterpret_cast(_str), n); } size_t size() const { @@ -49,7 +42,7 @@ class FlashStringAdapter { return strlen_P(reinterpret_cast(_str)); } - typedef storage_policy::store_by_copy storage_policy; + typedef storage_policies::store_by_copy storage_policy; private: const __FlashStringHelper* _str; diff --git a/src/ArduinoJson/Strings/RamStringAdapter.hpp b/src/ArduinoJson/Strings/RamStringAdapter.hpp index 9a80c0aa..572095e1 100644 --- a/src/ArduinoJson/Strings/RamStringAdapter.hpp +++ b/src/ArduinoJson/Strings/RamStringAdapter.hpp @@ -4,7 +4,6 @@ #pragma once -#include #include #include #include @@ -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 diff --git a/src/ArduinoJson/Strings/SizedFlashStringAdapter.hpp b/src/ArduinoJson/Strings/SizedFlashStringAdapter.hpp index 8e418b70..b6809a80 100644 --- a/src/ArduinoJson/Strings/SizedFlashStringAdapter.hpp +++ b/src/ArduinoJson/Strings/SizedFlashStringAdapter.hpp @@ -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(_str), _size); - return dup; + void copyTo(char* p, size_t n) const { + memcpy_P(p, reinterpret_cast(_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; diff --git a/src/ArduinoJson/Strings/SizedRamStringAdapter.hpp b/src/ArduinoJson/Strings/SizedRamStringAdapter.hpp index 1c16ffd5..2c1e87f6 100644 --- a/src/ArduinoJson/Strings/SizedRamStringAdapter.hpp +++ b/src/ArduinoJson/Strings/SizedRamStringAdapter.hpp @@ -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; diff --git a/src/ArduinoJson/Strings/StlStringAdapter.hpp b/src/ArduinoJson/Strings/StlStringAdapter.hpp index 37f857bf..fd6bf6d0 100644 --- a/src/ArduinoJson/Strings/StlStringAdapter.hpp +++ b/src/ArduinoJson/Strings/StlStringAdapter.hpp @@ -4,7 +4,6 @@ #pragma once -#include #include #include #include @@ -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; diff --git a/src/ArduinoJson/Strings/StoragePolicy.hpp b/src/ArduinoJson/Strings/StoragePolicy.hpp index ea9adcf4..92dee5f7 100644 --- a/src/ArduinoJson/Strings/StoragePolicy.hpp +++ b/src/ArduinoJson/Strings/StoragePolicy.hpp @@ -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 diff --git a/src/ArduinoJson/Strings/String.hpp b/src/ArduinoJson/Strings/String.hpp index c6f16baf..02f0ef2d 100644 --- a/src/ArduinoJson/Strings/String.hpp +++ b/src/ArduinoJson/Strings/String.hpp @@ -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; diff --git a/src/ArduinoJson/Variant/SlotFunctions.hpp b/src/ArduinoJson/Variant/SlotFunctions.hpp index b96b58e4..abd06ba4 100644 --- a/src/ArduinoJson/Variant/SlotFunctions.hpp +++ b/src/ArduinoJson/Variant/SlotFunctions.hpp @@ -18,17 +18,17 @@ inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool) { template 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 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 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); diff --git a/src/ArduinoJson/Variant/VariantData.hpp b/src/ArduinoJson/Variant/VariantData.hpp index c411446e..87caa15f 100644 --- a/src/ArduinoJson/Variant/VariantData.hpp +++ b/src/ArduinoJson/Variant/VariantData.hpp @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include @@ -191,7 +192,7 @@ class VariantData { template bool setOwnedRaw(SerializedValue 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 - bool setOwnedString(T value, MemoryPool *pool) { - return setOwnedString(value.save(pool)); + template + bool setOwnedString(TAdaptedString value, MemoryPool *pool) { + return setOwnedString(pool->saveString(value)); } CollectionData &toArray() { diff --git a/src/ArduinoJson/Variant/VariantFunctions.hpp b/src/ArduinoJson/Variant/VariantFunctions.hpp index e95448a2..8aa2ec39 100644 --- a/src/ArduinoJson/Variant/VariantFunctions.hpp +++ b/src/ArduinoJson/Variant/VariantFunctions.hpp @@ -119,11 +119,44 @@ inline bool variantSetOwnedString(VariantData *var, char *value) { return true; } -template -inline bool variantSetOwnedString(VariantData *var, T value, MemoryPool *pool) { +template +inline bool variantSetOwnedString(VariantData *var, TAdaptedString value, + MemoryPool *pool) { return var != 0 && var->setOwnedString(value, pool); } +template +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 +inline bool variantSetString(VariantData *var, TAdaptedString value, + MemoryPool *pool) { + return variantSetString(var, value, pool, + typename TAdaptedString::storage_policy()); +} + +template +inline bool variantSetString(VariantData *var, TAdaptedString value, + MemoryPool *, storage_policies::store_by_address) { + return variantSetLinkedString(var, value.data()); +} + +template +inline bool variantSetString(VariantData *var, TAdaptedString value, + MemoryPool *pool, + storage_policies::store_by_copy) { + return variantSetOwnedString(var, value, pool); +} + template inline bool variantSetInteger(VariantData *var, T value) { ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T); diff --git a/src/ArduinoJson/Variant/VariantRef.hpp b/src/ArduinoJson/Variant/VariantRef.hpp index 3eaeec2f..a258fa26 100644 --- a/src/ArduinoJson/Variant/VariantRef.hpp +++ b/src/ArduinoJson/Variant/VariantRef.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -213,20 +214,15 @@ class VariantRef : public VariantRefBase, FORCE_INLINE bool set( const T &value, typename enable_if::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 FORCE_INLINE bool set( T *value, typename enable_if::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, return variantSetInteger(_data, static_cast(value)); } +#if ARDUINOJSON_HAS_NULLPTR + // set(nullptr_t) + FORCE_INLINE bool set(decltype(nullptr)) const { + variantSetNull(_data); + return true; + } +#endif + template FORCE_INLINE typename VariantAs::type as() const { return variantAs::type>(_data, _pool);