diff --git a/src/ArduinoJson/Strings/ArduinoStringAdapter.hpp b/src/ArduinoJson/Strings/ArduinoStringAdapter.hpp index 5850a3b0..ac7bbdc3 100644 --- a/src/ArduinoJson/Strings/ArduinoStringAdapter.hpp +++ b/src/ArduinoJson/Strings/ArduinoStringAdapter.hpp @@ -7,6 +7,7 @@ #include #include +#include namespace ARDUINOJSON_NAMESPACE { @@ -39,17 +40,11 @@ class ArduinoStringAdapter { return compare(expected) == 0; } - const char* data() const { - return _str->c_str(); - } - size_t size() const { return _str->length(); } - bool isStatic() const { - return false; - } + typedef storage_policy::store_by_copy storage_policy; private: const ::String* _str; diff --git a/src/ArduinoJson/Strings/ConstRamStringAdapter.hpp b/src/ArduinoJson/Strings/ConstRamStringAdapter.hpp index a7176b08..407f584d 100644 --- a/src/ArduinoJson/Strings/ConstRamStringAdapter.hpp +++ b/src/ArduinoJson/Strings/ConstRamStringAdapter.hpp @@ -8,6 +8,7 @@ #include // strcmp #include +#include namespace ARDUINOJSON_NAMESPACE { @@ -27,11 +28,6 @@ class ConstRamStringAdapter { return !_str; } - template - char* save(TMemoryPool*) const { - return 0; - } - size_t size() const { if (!_str) return 0; @@ -42,9 +38,7 @@ class ConstRamStringAdapter { return _str; } - bool isStatic() const { - return true; - } + typedef storage_policy::store_by_address storage_policy; protected: const char* _str; diff --git a/src/ArduinoJson/Strings/FlashStringAdapter.hpp b/src/ArduinoJson/Strings/FlashStringAdapter.hpp index 74bc3950..328f040f 100644 --- a/src/ArduinoJson/Strings/FlashStringAdapter.hpp +++ b/src/ArduinoJson/Strings/FlashStringAdapter.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include namespace ARDUINOJSON_NAMESPACE { @@ -40,19 +41,13 @@ class FlashStringAdapter { return dup; } - const char* data() const { - return 0; - } - size_t size() const { if (!_str) return 0; return strlen_P(reinterpret_cast(_str)); } - bool isStatic() const { - return false; - } + typedef storage_policy::store_by_copy storage_policy; private: const __FlashStringHelper* _str; diff --git a/src/ArduinoJson/Strings/RamStringAdapter.hpp b/src/ArduinoJson/Strings/RamStringAdapter.hpp index 6909bf98..05db2e84 100644 --- a/src/ArduinoJson/Strings/RamStringAdapter.hpp +++ b/src/ArduinoJson/Strings/RamStringAdapter.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include namespace ARDUINOJSON_NAMESPACE { @@ -22,9 +23,7 @@ class RamStringAdapter : public ConstRamStringAdapter { return dup; } - bool isStatic() const { - return false; - } + typedef ARDUINOJSON_NAMESPACE::storage_policy::store_by_copy storage_policy; }; template diff --git a/src/ArduinoJson/Strings/SizedFlashStringAdapter.hpp b/src/ArduinoJson/Strings/SizedFlashStringAdapter.hpp index 48fe2855..41a6cf6d 100644 --- a/src/ArduinoJson/Strings/SizedFlashStringAdapter.hpp +++ b/src/ArduinoJson/Strings/SizedFlashStringAdapter.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include namespace ARDUINOJSON_NAMESPACE { @@ -45,9 +46,7 @@ class SizedFlashStringAdapter { return _size; } - bool isStatic() const { - return false; - } + typedef storage_policy::store_by_copy storage_policy; private: const __FlashStringHelper* _str; diff --git a/src/ArduinoJson/Strings/SizedRamStringAdapter.hpp b/src/ArduinoJson/Strings/SizedRamStringAdapter.hpp index 04c5630b..911f4af6 100644 --- a/src/ArduinoJson/Strings/SizedRamStringAdapter.hpp +++ b/src/ArduinoJson/Strings/SizedRamStringAdapter.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include #include // strcmp @@ -39,9 +40,7 @@ class SizedRamStringAdapter { return _size; } - bool isStatic() const { - return false; - } + typedef storage_policy::store_by_copy storage_policy; private: const char* _str; diff --git a/src/ArduinoJson/Strings/StlStringAdapter.hpp b/src/ArduinoJson/Strings/StlStringAdapter.hpp index 617e8231..defec413 100644 --- a/src/ArduinoJson/Strings/StlStringAdapter.hpp +++ b/src/ArduinoJson/Strings/StlStringAdapter.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include #include @@ -39,17 +40,11 @@ class StlStringAdapter { return *_str == expected; } - const char* data() const { - return _str->data(); - } - size_t size() const { return _str->size(); } - bool isStatic() const { - return false; - } + typedef storage_policy::store_by_copy storage_policy; private: const TString* _str; diff --git a/src/ArduinoJson/Strings/StoragePolicy.hpp b/src/ArduinoJson/Strings/StoragePolicy.hpp new file mode 100644 index 00000000..ea9adcf4 --- /dev/null +++ b/src/ArduinoJson/Strings/StoragePolicy.hpp @@ -0,0 +1,15 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2020 +// MIT License + +#pragma once + +namespace ARDUINOJSON_NAMESPACE { + +namespace storage_policy { +struct store_by_address {}; +struct store_by_copy {}; +struct decide_at_runtime {}; +} // namespace storage_policy + +} // namespace ARDUINOJSON_NAMESPACE diff --git a/src/ArduinoJson/Strings/String.hpp b/src/ArduinoJson/Strings/String.hpp index 1cc42068..eeced00c 100644 --- a/src/ArduinoJson/Strings/String.hpp +++ b/src/ArduinoJson/Strings/String.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include namespace ARDUINOJSON_NAMESPACE { @@ -36,6 +37,8 @@ class String { return strcmp(lhs._data, rhs._data) == 0; } + typedef storage_policy::decide_at_runtime storage_policy; + private: const char* _data; bool _isStatic; diff --git a/src/ArduinoJson/Variant/SlotFunctions.hpp b/src/ArduinoJson/Variant/SlotFunctions.hpp index fb16177b..ef75a94d 100644 --- a/src/ArduinoJson/Variant/SlotFunctions.hpp +++ b/src/ArduinoJson/Variant/SlotFunctions.hpp @@ -13,17 +13,39 @@ template inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool) { if (!var) return false; + return slotSetKey(var, key, pool, typename TAdaptedString::storage_policy()); +} + +template +inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool, + storage_policy::decide_at_runtime) { if (key.isStatic()) { - var->setLinkedKey(make_not_null(key.data())); + return slotSetKey(var, key, pool, storage_policy::store_by_address()); } else { - const char* dup = key.save(pool); - if (!dup) - return false; - var->setOwnedKey(make_not_null(dup)); + return slotSetKey(var, key, pool, storage_policy::store_by_copy()); } return true; } +template +inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool*, + storage_policy::store_by_address) { + ARDUINOJSON_ASSERT(var); + var->setLinkedKey(make_not_null(key.data())); + return true; +} + +template +inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool, + storage_policy::store_by_copy) { + const char* dup = key.save(pool); + if (!dup) + return false; + ARDUINOJSON_ASSERT(var); + var->setOwnedKey(make_not_null(dup)); + return true; +} + inline size_t slotSize(const VariantSlot* var) { size_t n = 0; while (var) {