mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Attach copy policy to string adapters
This commit is contained in:
		| @@ -38,15 +38,14 @@ class CollectionData { | ||||
|  | ||||
|   // Object only | ||||
|  | ||||
|   template <typename TAdaptedString, typename TStoragePolicy> | ||||
|   VariantData* addMember(TAdaptedString key, MemoryPool* pool, TStoragePolicy); | ||||
|   template <typename TAdaptedString> | ||||
|   VariantData* addMember(TAdaptedString key, MemoryPool* pool); | ||||
|  | ||||
|   template <typename TAdaptedString> | ||||
|   VariantData* getMember(TAdaptedString key) const; | ||||
|  | ||||
|   template <typename TAdaptedString, typename TStoragePolicy> | ||||
|   VariantData* getOrAddMember(TAdaptedString key, MemoryPool* pool, | ||||
|                               TStoragePolicy); | ||||
|   template <typename TAdaptedString> | ||||
|   VariantData* getOrAddMember(TAdaptedString key, MemoryPool* pool); | ||||
|  | ||||
|   template <typename TAdaptedString> | ||||
|   void removeMember(TAdaptedString key) { | ||||
|   | ||||
| @@ -33,12 +33,11 @@ inline VariantData* CollectionData::addElement(MemoryPool* pool) { | ||||
|   return slotData(addSlot(pool)); | ||||
| } | ||||
|  | ||||
| template <typename TAdaptedString, typename TStoragePolicy> | ||||
| template <typename TAdaptedString> | ||||
| inline VariantData* CollectionData::addMember(TAdaptedString key, | ||||
|                                               MemoryPool* pool, | ||||
|                                               TStoragePolicy storage) { | ||||
|                                               MemoryPool* pool) { | ||||
|   VariantSlot* slot = addSlot(pool); | ||||
|   if (!slotSetKey(slot, key, pool, storage)) { | ||||
|   if (!slotSetKey(slot, key, pool)) { | ||||
|     removeSlot(slot); | ||||
|     return 0; | ||||
|   } | ||||
| @@ -62,7 +61,7 @@ inline bool CollectionData::copyFrom(const CollectionData& src, | ||||
|     VariantData* var; | ||||
|     if (s->key() != 0) { | ||||
|       String key(s->key(), s->ownsKey() ? String::Copied : String::Linked); | ||||
|       var = addMember(adaptString(key), pool, getStringStoragePolicy(key)); | ||||
|       var = addMember(adaptString(key), pool); | ||||
|     } else { | ||||
|       var = addElement(pool); | ||||
|     } | ||||
| @@ -110,9 +109,9 @@ inline VariantData* CollectionData::getMember(TAdaptedString key) const { | ||||
|   return slot ? slot->data() : 0; | ||||
| } | ||||
|  | ||||
| template <typename TAdaptedString, typename TStoragePolicy> | ||||
| inline VariantData* CollectionData::getOrAddMember( | ||||
|     TAdaptedString key, MemoryPool* pool, TStoragePolicy storage_policy) { | ||||
| template <typename TAdaptedString> | ||||
| inline VariantData* CollectionData::getOrAddMember(TAdaptedString key, | ||||
|                                                    MemoryPool* pool) { | ||||
|   // ignore null key | ||||
|   if (key.isNull()) | ||||
|     return 0; | ||||
| @@ -122,7 +121,7 @@ inline VariantData* CollectionData::getOrAddMember( | ||||
|   if (slot) | ||||
|     return slot->data(); | ||||
|  | ||||
|   return addMember(key, pool, storage_policy); | ||||
|   return addMember(key, pool); | ||||
| } | ||||
|  | ||||
| inline VariantData* CollectionData::getElement(size_t index) const { | ||||
|   | ||||
| @@ -208,4 +208,35 @@ class MemoryPool { | ||||
|   bool _overflowed; | ||||
| }; | ||||
|  | ||||
| template <typename TAdaptedString, typename TCallback> | ||||
| bool storeString(MemoryPool* pool, TAdaptedString str, CopyStringStoragePolicy, | ||||
|                  TCallback callback) { | ||||
|   const char* copy = pool->saveString(str); | ||||
|   String storedString(copy, str.size(), String::Copied); | ||||
|   callback(storedString); | ||||
|   return copy != 0; | ||||
| } | ||||
|  | ||||
| template <typename TAdaptedString, typename TCallback> | ||||
| bool storeString(MemoryPool*, TAdaptedString str, LinkStringStoragePolicy, | ||||
|                  TCallback callback) { | ||||
|   String storedString(str.data(), str.size(), String::Linked); | ||||
|   callback(storedString); | ||||
|   return !str.isNull(); | ||||
| } | ||||
|  | ||||
| template <typename TAdaptedString, typename TCallback> | ||||
| bool storeString(MemoryPool* pool, TAdaptedString str, | ||||
|                  LinkOrCopyStringStoragePolicy policy, TCallback callback) { | ||||
|   if (policy.link) | ||||
|     return storeString(pool, str, LinkStringStoragePolicy(), callback); | ||||
|   else | ||||
|     return storeString(pool, str, CopyStringStoragePolicy(), callback); | ||||
| } | ||||
|  | ||||
| template <typename TAdaptedString, typename TCallback> | ||||
| bool storeString(MemoryPool* pool, TAdaptedString str, TCallback callback) { | ||||
|   return storeString(pool, str, str.storagePolicy(), callback); | ||||
| } | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
| @@ -61,6 +61,10 @@ class FlashString { | ||||
|     ::memcpy_P(p, s._str, n); | ||||
|   } | ||||
|  | ||||
|   CopyStringStoragePolicy storagePolicy() { | ||||
|     return CopyStringStoragePolicy(); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   const char* _str; | ||||
|   size_t _size; | ||||
|   | ||||
| @@ -10,8 +10,21 @@ | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| inline SizedRamString adaptString(const String& s) { | ||||
|   return SizedRamString(s.c_str(), s.size()); | ||||
| class JsonStringAdapter : public SizedRamString { | ||||
|  public: | ||||
|   JsonStringAdapter(const String& s) | ||||
|       : SizedRamString(s.c_str(), s.size()), _linked(s.isLinked()) {} | ||||
|  | ||||
|   LinkOrCopyStringStoragePolicy storagePolicy() { | ||||
|     return LinkOrCopyStringStoragePolicy(_linked); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   bool _linked; | ||||
| }; | ||||
|  | ||||
| inline JsonStringAdapter adaptString(const String& s) { | ||||
|   return JsonStringAdapter(s); | ||||
| } | ||||
|  | ||||
| template <> | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
|  | ||||
| #include <ArduinoJson/Polyfills/assert.hpp> | ||||
| #include <ArduinoJson/Strings/IsString.hpp> | ||||
| #include <ArduinoJson/Strings/StoragePolicy.hpp> | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| @@ -48,6 +49,10 @@ class ZeroTerminatedRamString { | ||||
|     return stringCompare(a, b) == 0; | ||||
|   } | ||||
|  | ||||
|   CopyStringStoragePolicy storagePolicy() { | ||||
|     return CopyStringStoragePolicy(); | ||||
|   } | ||||
|  | ||||
|  protected: | ||||
|   const char* _str; | ||||
| }; | ||||
| @@ -55,7 +60,7 @@ class ZeroTerminatedRamString { | ||||
| template <> | ||||
| struct IsString<char*> : true_type {}; | ||||
|  | ||||
| inline ZeroTerminatedRamString adaptString(const char* s) { | ||||
| inline ZeroTerminatedRamString adaptString(char* s) { | ||||
|   return ZeroTerminatedRamString(s); | ||||
| } | ||||
|  | ||||
| @@ -63,14 +68,27 @@ template <> | ||||
| struct IsString<unsigned char*> : true_type {}; | ||||
|  | ||||
| inline ZeroTerminatedRamString adaptString(const unsigned char* s) { | ||||
|   return adaptString(reinterpret_cast<const char*>(s)); | ||||
|   return ZeroTerminatedRamString(reinterpret_cast<const char*>(s)); | ||||
| } | ||||
|  | ||||
| template <> | ||||
| struct IsString<signed char*> : true_type {}; | ||||
|  | ||||
| inline ZeroTerminatedRamString adaptString(const signed char* s) { | ||||
|   return adaptString(reinterpret_cast<const char*>(s)); | ||||
|   return ZeroTerminatedRamString(reinterpret_cast<const char*>(s)); | ||||
| } | ||||
|  | ||||
| class StaticStringAdapter : public ZeroTerminatedRamString { | ||||
|  public: | ||||
|   StaticStringAdapter(const char* str) : ZeroTerminatedRamString(str) {} | ||||
|  | ||||
|   LinkStringStoragePolicy storagePolicy() { | ||||
|     return LinkStringStoragePolicy(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| inline StaticStringAdapter adaptString(const char* s) { | ||||
|   return StaticStringAdapter(s); | ||||
| } | ||||
|  | ||||
| class SizedRamString { | ||||
| @@ -97,6 +115,10 @@ class SizedRamString { | ||||
|     return _str; | ||||
|   } | ||||
|  | ||||
|   CopyStringStoragePolicy storagePolicy() { | ||||
|     return CopyStringStoragePolicy(); | ||||
|   } | ||||
|  | ||||
|  protected: | ||||
|   const char* _str; | ||||
|   size_t _size; | ||||
|   | ||||
| @@ -4,53 +4,16 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ArduinoJson/Memory/MemoryPool.hpp> | ||||
| #include <ArduinoJson/Strings/String.hpp> | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| struct LinkStringStoragePolicy { | ||||
|   template <typename TAdaptedString, typename TCallback> | ||||
|   bool store(TAdaptedString str, MemoryPool*, TCallback callback) { | ||||
|     String storedString(str.data(), str.size(), String::Linked); | ||||
|     callback(storedString); | ||||
|     return !str.isNull(); | ||||
|   } | ||||
| struct LinkStringStoragePolicy {}; | ||||
|  | ||||
| struct CopyStringStoragePolicy {}; | ||||
|  | ||||
| struct LinkOrCopyStringStoragePolicy { | ||||
|   LinkOrCopyStringStoragePolicy(bool l) : link(l) {} | ||||
|  | ||||
|   bool link; | ||||
| }; | ||||
|  | ||||
| struct CopyStringStoragePolicy { | ||||
|   template <typename TAdaptedString, typename TCallback> | ||||
|   bool store(TAdaptedString str, MemoryPool* pool, TCallback callback); | ||||
| }; | ||||
|  | ||||
| class LinkOrCopyStringStoragePolicy : LinkStringStoragePolicy, | ||||
|                                       CopyStringStoragePolicy { | ||||
|  public: | ||||
|   LinkOrCopyStringStoragePolicy(bool link) : _link(link) {} | ||||
|  | ||||
|   template <typename TAdaptedString, typename TCallback> | ||||
|   bool store(TAdaptedString str, MemoryPool* pool, TCallback callback) { | ||||
|     if (_link) | ||||
|       return LinkStringStoragePolicy::store(str, pool, callback); | ||||
|     else | ||||
|       return CopyStringStoragePolicy::store(str, pool, callback); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   bool _link; | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| inline CopyStringStoragePolicy getStringStoragePolicy(const T&) { | ||||
|   return CopyStringStoragePolicy(); | ||||
| } | ||||
|  | ||||
| inline LinkStringStoragePolicy getStringStoragePolicy(const char*) { | ||||
|   return LinkStringStoragePolicy(); | ||||
| } | ||||
|  | ||||
| inline LinkOrCopyStringStoragePolicy getStringStoragePolicy(const String& s) { | ||||
|   return LinkOrCopyStringStoragePolicy(s.isLinked()); | ||||
| } | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
| @@ -118,8 +118,7 @@ struct Converter<T, typename enable_if<is_floating_point<T>::value>::type> | ||||
| template <> | ||||
| struct Converter<const char*> : private VariantAttorney { | ||||
|   static void toJson(const char* src, VariantRef dst) { | ||||
|     variantSetString(getData(dst), adaptString(src), getPool(dst), | ||||
|                      getStringStoragePolicy(src)); | ||||
|     variantSetString(getData(dst), adaptString(src), getPool(dst)); | ||||
|   } | ||||
|  | ||||
|   static const char* fromJson(VariantConstRef src) { | ||||
| @@ -136,8 +135,7 @@ struct Converter<const char*> : private VariantAttorney { | ||||
| template <> | ||||
| struct Converter<String> : private VariantAttorney { | ||||
|   static void toJson(String src, VariantRef dst) { | ||||
|     variantSetString(getData(dst), adaptString(src), getPool(dst), | ||||
|                      getStringStoragePolicy(src)); | ||||
|     variantSetString(getData(dst), adaptString(src), getPool(dst)); | ||||
|   } | ||||
|  | ||||
|   static String fromJson(VariantConstRef src) { | ||||
| @@ -156,8 +154,7 @@ inline typename enable_if<IsString<T>::value, bool>::type convertToJson( | ||||
|     const T& src, VariantRef dst) { | ||||
|   VariantData* data = VariantAttorney::getData(dst); | ||||
|   MemoryPool* pool = VariantAttorney::getPool(dst); | ||||
|   return variantSetString(data, adaptString(src), pool, | ||||
|                           getStringStoragePolicy(src)); | ||||
|   return variantSetString(data, adaptString(src), pool); | ||||
| } | ||||
|  | ||||
| template <> | ||||
|   | ||||
| @@ -23,12 +23,11 @@ struct SlotKeySetter { | ||||
|   VariantSlot* _instance; | ||||
| }; | ||||
|  | ||||
| template <typename TAdaptedString, typename TStoragePolicy> | ||||
| inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool, | ||||
|                        TStoragePolicy storage) { | ||||
| template <typename TAdaptedString> | ||||
| inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool) { | ||||
|   if (!var) | ||||
|     return false; | ||||
|   return storage.store(key, pool, SlotKeySetter(var)); | ||||
|   return storeString(pool, key, SlotKeySetter(var)); | ||||
| } | ||||
|  | ||||
| inline size_t slotSize(const VariantSlot* var) { | ||||
|   | ||||
| @@ -285,14 +285,13 @@ class VariantData { | ||||
|     return col ? col->getMember(key) : 0; | ||||
|   } | ||||
|  | ||||
|   template <typename TAdaptedString, typename TStoragePolicy> | ||||
|   VariantData* getOrAddMember(TAdaptedString key, MemoryPool* pool, | ||||
|                               TStoragePolicy storage_policy) { | ||||
|   template <typename TAdaptedString> | ||||
|   VariantData* getOrAddMember(TAdaptedString key, MemoryPool* pool) { | ||||
|     if (isNull()) | ||||
|       toObject(); | ||||
|     if (!isObject()) | ||||
|       return 0; | ||||
|     return _content.asCollection.getOrAddMember(key, pool, storage_policy); | ||||
|     return _content.asCollection.getOrAddMember(key, pool); | ||||
|   } | ||||
|  | ||||
|   void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance) { | ||||
| @@ -306,15 +305,14 @@ class VariantData { | ||||
|     return _flags & VALUE_MASK; | ||||
|   } | ||||
|  | ||||
|   template <typename TAdaptedString, typename TStoragePolicy> | ||||
|   inline bool storeString(TAdaptedString value, MemoryPool* pool, | ||||
|                           TStoragePolicy storage) { | ||||
|   template <typename TAdaptedString> | ||||
|   inline bool setString(TAdaptedString value, MemoryPool* pool) { | ||||
|     if (value.isNull()) { | ||||
|       setNull(); | ||||
|       return true; | ||||
|     } | ||||
|  | ||||
|     return storage.store(value, pool, VariantStringSetter(this)); | ||||
|     return storeString(pool, value, VariantStringSetter(this)); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   | ||||
| @@ -37,10 +37,10 @@ inline void variantSetNull(VariantData* var) { | ||||
|   var->setNull(); | ||||
| } | ||||
|  | ||||
| template <typename TAdaptedString, typename TStoragePolicy> | ||||
| template <typename TAdaptedString> | ||||
| inline bool variantSetString(VariantData* var, TAdaptedString value, | ||||
|                              MemoryPool* pool, TStoragePolicy storage_policy) { | ||||
|   return var != 0 ? var->storeString(value, pool, storage_policy) : 0; | ||||
|                              MemoryPool* pool) { | ||||
|   return var != 0 ? var->setString(value, pool) : 0; | ||||
| } | ||||
|  | ||||
| inline size_t variantSize(const VariantData* var) { | ||||
| @@ -88,8 +88,7 @@ VariantData* variantGetOrAddMember(VariantData* var, TChar* key, | ||||
|                                    MemoryPool* pool) { | ||||
|   if (!var) | ||||
|     return 0; | ||||
|   return var->getOrAddMember(adaptString(key), pool, | ||||
|                              getStringStoragePolicy(key)); | ||||
|   return var->getOrAddMember(adaptString(key), pool); | ||||
| } | ||||
|  | ||||
| template <typename TString> | ||||
| @@ -97,8 +96,7 @@ VariantData* variantGetOrAddMember(VariantData* var, const TString& key, | ||||
|                                    MemoryPool* pool) { | ||||
|   if (!var) | ||||
|     return 0; | ||||
|   return var->getOrAddMember(adaptString(key), pool, | ||||
|                              getStringStoragePolicy(key)); | ||||
|   return var->getOrAddMember(adaptString(key), pool); | ||||
| } | ||||
|  | ||||
| inline bool variantIsNull(const VariantData* var) { | ||||
|   | ||||
| @@ -91,8 +91,7 @@ inline bool VariantData::copyFrom(const VariantData& src, MemoryPool* pool) { | ||||
|       return toObject().copyFrom(src._content.asCollection, pool); | ||||
|     case VALUE_IS_OWNED_STRING: { | ||||
|       String value = src.asString(); | ||||
|       return storeString(adaptString(value), pool, | ||||
|                          getStringStoragePolicy(value)); | ||||
|       return setString(adaptString(value), pool); | ||||
|     } | ||||
|     case VALUE_IS_OWNED_RAW: | ||||
|       return storeOwnedRaw( | ||||
| @@ -154,14 +153,4 @@ inline void convertToJson(const VariantRefBase<TDataSource>& src, | ||||
|   dst.set(src.template as<VariantConstRef>()); | ||||
| } | ||||
|  | ||||
| // TODO: move somewhere else | ||||
| template <typename TAdaptedString, typename TCallback> | ||||
| bool CopyStringStoragePolicy::store(TAdaptedString str, MemoryPool* pool, | ||||
|                                     TCallback callback) { | ||||
|   const char* copy = pool->saveString(str); | ||||
|   String storedString(copy, str.size(), String::Copied); | ||||
|   callback(storedString); | ||||
|   return copy != 0; | ||||
| } | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
		Reference in New Issue
	
	Block a user