mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Add CopiedString and LinkedString
				
					
				
			This commit is contained in:
		| @@ -19,7 +19,8 @@ TEST_CASE("StringCopier") { | |||||||
|     str.append('\0'); |     str.append('\0'); | ||||||
|  |  | ||||||
|     REQUIRE(str.isValid() == true); |     REQUIRE(str.isValid() == true); | ||||||
|     REQUIRE(str.c_str() == std::string("hello")); |     REQUIRE(std::string(str.str()) == "hello"); | ||||||
|  |     REQUIRE(pool.overflowed() == false); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("Returns null when too small") { |   SECTION("Returns null when too small") { | ||||||
| @@ -49,7 +50,7 @@ static const char* addStringToPool(MemoryPool& pool, const char* s) { | |||||||
|   str.startString(); |   str.startString(); | ||||||
|   str.append(s); |   str.append(s); | ||||||
|   str.append('\0'); |   str.append('\0'); | ||||||
|   return str.save(); |   return str.save().c_str(); | ||||||
| } | } | ||||||
|  |  | ||||||
| TEST_CASE("StringCopier::save() deduplicates strings") { | TEST_CASE("StringCopier::save() deduplicates strings") { | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ static void testCodepoint(uint32_t codepoint, std::string expected) { | |||||||
|   Utf8::encodeCodepoint(codepoint, str); |   Utf8::encodeCodepoint(codepoint, str); | ||||||
|  |  | ||||||
|   str.append('\0'); |   str.append('\0'); | ||||||
|   REQUIRE(str.c_str() == expected); |   REQUIRE(str.str().c_str() == expected); | ||||||
| } | } | ||||||
|  |  | ||||||
| TEST_CASE("Utf8::encodeCodepoint()") { | TEST_CASE("Utf8::encodeCodepoint()") { | ||||||
|   | |||||||
| @@ -231,12 +231,12 @@ class JsonDeserializer { | |||||||
|         return false; |         return false; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       const char *key = _stringStorage.c_str(); |       typename TStringStorage::string_type key = _stringStorage.str(); | ||||||
|  |  | ||||||
|       TFilter memberFilter = filter[key]; |       TFilter memberFilter = filter[key.c_str()]; | ||||||
|  |  | ||||||
|       if (memberFilter.allow()) { |       if (memberFilter.allow()) { | ||||||
|         VariantData *variant = object.getMember(adaptString(key)); |         VariantData *variant = object.getMember(adaptString(key.c_str())); | ||||||
|         if (!variant) { |         if (!variant) { | ||||||
|           // Save key in memory pool. |           // Save key in memory pool. | ||||||
|           // This MUST be done before adding the slot. |           // This MUST be done before adding the slot. | ||||||
| @@ -249,7 +249,7 @@ class JsonDeserializer { | |||||||
|             return false; |             return false; | ||||||
|           } |           } | ||||||
|  |  | ||||||
|           slot->setKey(key, typename TStringStorage::storage_policy()); |           slot->setKey(key); | ||||||
|  |  | ||||||
|           variant = slot->data(); |           variant = slot->data(); | ||||||
|         } |         } | ||||||
| @@ -345,8 +345,7 @@ class JsonDeserializer { | |||||||
|     _stringStorage.startString(); |     _stringStorage.startString(); | ||||||
|     if (!parseQuotedString()) |     if (!parseQuotedString()) | ||||||
|       return false; |       return false; | ||||||
|     const char *value = _stringStorage.save(); |     variant.setString(_stringStorage.save()); | ||||||
|     variant.setStringPointer(value, typename TStringStorage::storage_policy()); |  | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -331,8 +331,7 @@ class MsgPackDeserializer { | |||||||
|   bool readString(VariantData *variant, size_t n) { |   bool readString(VariantData *variant, size_t n) { | ||||||
|     if (!readString(n)) |     if (!readString(n)) | ||||||
|       return false; |       return false; | ||||||
|     variant->setStringPointer(_stringStorage.save(), |     variant->setString(_stringStorage.save()); | ||||||
|                               typename TStringStorage::storage_policy()); |  | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -419,8 +418,8 @@ class MsgPackDeserializer { | |||||||
|       if (!readKey()) |       if (!readKey()) | ||||||
|         return false; |         return false; | ||||||
|  |  | ||||||
|       const char *key = _stringStorage.c_str(); |       typename TStringStorage::string_type key = _stringStorage.str(); | ||||||
|       TFilter memberFilter = filter[key]; |       TFilter memberFilter = filter[key.c_str()]; | ||||||
|       VariantData *member; |       VariantData *member; | ||||||
|  |  | ||||||
|       if (memberFilter.allow()) { |       if (memberFilter.allow()) { | ||||||
| @@ -434,7 +433,7 @@ class MsgPackDeserializer { | |||||||
|           return false; |           return false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         slot->setKey(key, typename TStringStorage::storage_policy()); |         slot->setKey(key); | ||||||
|  |  | ||||||
|         member = slot->data(); |         member = slot->data(); | ||||||
|       } else { |       } else { | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ | |||||||
| #include <ArduinoJson/Namespace.hpp> | #include <ArduinoJson/Namespace.hpp> | ||||||
|  |  | ||||||
| #include <stdint.h>  // int8_t | #include <stdint.h>  // int8_t | ||||||
|  | #include <string.h>  // strcmp | ||||||
|  |  | ||||||
| namespace ARDUINOJSON_NAMESPACE { | namespace ARDUINOJSON_NAMESPACE { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,6 +10,8 @@ namespace ARDUINOJSON_NAMESPACE { | |||||||
|  |  | ||||||
| class StringCopier { | class StringCopier { | ||||||
|  public: |  public: | ||||||
|  |   typedef CopiedString string_type; | ||||||
|  |  | ||||||
|   StringCopier(MemoryPool& pool) : _pool(&pool) {} |   StringCopier(MemoryPool& pool) : _pool(&pool) {} | ||||||
|  |  | ||||||
|   void startString() { |   void startString() { | ||||||
| @@ -17,7 +19,7 @@ class StringCopier { | |||||||
|     _size = 0; |     _size = 0; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   const char* save() { |   string_type save() { | ||||||
|     ARDUINOJSON_ASSERT(_ptr); |     ARDUINOJSON_ASSERT(_ptr); | ||||||
|     return _pool->saveStringFromFreeZone(_size); |     return _pool->saveStringFromFreeZone(_size); | ||||||
|   } |   } | ||||||
| @@ -47,12 +49,10 @@ class StringCopier { | |||||||
|     return _ptr != 0; |     return _ptr != 0; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   const char* c_str() { |   string_type str() const { | ||||||
|     return _ptr; |     return _ptr; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   typedef storage_policies::store_by_copy storage_policy; |  | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   MemoryPool* _pool; |   MemoryPool* _pool; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,19 +5,21 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <ArduinoJson/Namespace.hpp> | #include <ArduinoJson/Namespace.hpp> | ||||||
| #include <ArduinoJson/Strings/StoragePolicy.hpp> | #include <ArduinoJson/Strings/StoredString.hpp> | ||||||
|  |  | ||||||
| namespace ARDUINOJSON_NAMESPACE { | namespace ARDUINOJSON_NAMESPACE { | ||||||
|  |  | ||||||
| class StringMover { | class StringMover { | ||||||
|  public: |  public: | ||||||
|  |   typedef LinkedString string_type; | ||||||
|  |  | ||||||
|   StringMover(char* ptr) : _writePtr(ptr) {} |   StringMover(char* ptr) : _writePtr(ptr) {} | ||||||
|  |  | ||||||
|   void startString() { |   void startString() { | ||||||
|     _startPtr = _writePtr; |     _startPtr = _writePtr; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   const char* save() const { |   FORCE_INLINE string_type save() { | ||||||
|     return _startPtr; |     return _startPtr; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -29,12 +31,10 @@ class StringMover { | |||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   const char* c_str() const { |   string_type str() const { | ||||||
|     return _startPtr; |     return string_type(_startPtr); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   typedef storage_policies::store_by_address storage_policy; |  | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   char* _writePtr; |   char* _writePtr; | ||||||
|   char* _startPtr; |   char* _startPtr; | ||||||
|   | |||||||
							
								
								
									
										32
									
								
								src/ArduinoJson/Strings/StoredString.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/ArduinoJson/Strings/StoredString.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | // ArduinoJson - https://arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2021 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <ArduinoJson/Polyfills/safe_strcmp.hpp> | ||||||
|  | #include <ArduinoJson/Strings/StoragePolicy.hpp> | ||||||
|  |  | ||||||
|  | namespace ARDUINOJSON_NAMESPACE { | ||||||
|  |  | ||||||
|  | template <typename TStoragePolicy> | ||||||
|  | class StoredString { | ||||||
|  |  public: | ||||||
|  |   StoredString(const char* p) : _data(p) {} | ||||||
|  |  | ||||||
|  |   operator const char*() const { | ||||||
|  |     return _data; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   const char* c_str() const { | ||||||
|  |     return _data; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   const char* _data; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | typedef StoredString<storage_policies::store_by_address> LinkedString; | ||||||
|  | typedef StoredString<storage_policies::store_by_copy> CopiedString; | ||||||
|  |  | ||||||
|  | }  // namespace ARDUINOJSON_NAMESPACE | ||||||
| @@ -173,7 +173,7 @@ struct Converter<SerializedValue<T>, | |||||||
|     VariantData* data = getData(dst); |     VariantData* data = getData(dst); | ||||||
|     MemoryPool* pool = getPool(dst); |     MemoryPool* pool = getPool(dst); | ||||||
|     if (data) |     if (data) | ||||||
|       data->setOwnedRaw(src, pool); |       data->storeOwnedRaw(src, pool); | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -203,7 +203,7 @@ class MemoryPoolPrint : public Print { | |||||||
|     pool->getFreeZone(&_string, &_capacity); |     pool->getFreeZone(&_string, &_capacity); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   const char* c_str() { |   CopiedString str() { | ||||||
|     _string[_size++] = 0; |     _string[_size++] = 0; | ||||||
|     ARDUINOJSON_ASSERT(_size <= _capacity); |     ARDUINOJSON_ASSERT(_size <= _capacity); | ||||||
|     return _pool->saveStringFromFreeZone(_size); |     return _pool->saveStringFromFreeZone(_size); | ||||||
| @@ -250,7 +250,7 @@ inline void convertToJson(const ::Printable& src, VariantRef dst) { | |||||||
|     data->setNull(); |     data->setNull(); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   data->setStringPointer(print.c_str(), storage_policies::store_by_copy()); |   data->setString(print.str()); | ||||||
| } | } | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -30,18 +30,18 @@ template <typename TAdaptedString> | |||||||
| inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool*, | inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool*, | ||||||
|                        storage_policies::store_by_address) { |                        storage_policies::store_by_address) { | ||||||
|   ARDUINOJSON_ASSERT(var); |   ARDUINOJSON_ASSERT(var); | ||||||
|   var->setKey(key.data(), storage_policies::store_by_address()); |   var->setKey(LinkedString(key.data())); | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TAdaptedString> | template <typename TAdaptedString> | ||||||
| inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool, | inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool, | ||||||
|                        storage_policies::store_by_copy) { |                        storage_policies::store_by_copy) { | ||||||
|   const char* dup = pool->saveString(key); |   CopiedString dup = pool->saveString(key); | ||||||
|   if (!dup) |   if (!dup) | ||||||
|     return false; |     return false; | ||||||
|   ARDUINOJSON_ASSERT(var); |   ARDUINOJSON_ASSERT(var); | ||||||
|   var->setKey(dup, storage_policies::store_by_copy()); |   var->setKey(dup); | ||||||
|   return true; |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -104,10 +104,10 @@ class VariantData { | |||||||
|       case VALUE_IS_OBJECT: |       case VALUE_IS_OBJECT: | ||||||
|         return toObject().copyFrom(src._content.asCollection, pool); |         return toObject().copyFrom(src._content.asCollection, pool); | ||||||
|       case VALUE_IS_OWNED_STRING: |       case VALUE_IS_OWNED_STRING: | ||||||
|         return setString(adaptString(const_cast<char *>(src._content.asString)), |         return storeString( | ||||||
|                          pool); |             adaptString(const_cast<char *>(src._content.asString)), pool); | ||||||
|       case VALUE_IS_OWNED_RAW: |       case VALUE_IS_OWNED_RAW: | ||||||
|         return setOwnedRaw( |         return storeOwnedRaw( | ||||||
|             serialized(src._content.asRaw.data, src._content.asRaw.size), pool); |             serialized(src._content.asRaw.data, src._content.asRaw.size), pool); | ||||||
|       default: |       default: | ||||||
|         setType(src.type()); |         setType(src.type()); | ||||||
| @@ -194,7 +194,7 @@ class VariantData { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   bool setOwnedRaw(SerializedValue<T> value, MemoryPool *pool) { |   bool storeOwnedRaw(SerializedValue<T> value, MemoryPool *pool) { | ||||||
|     const char *dup = pool->saveString(adaptString(value.data(), value.size())); |     const char *dup = pool->saveString(adaptString(value.data(), value.size())); | ||||||
|     if (dup) { |     if (dup) { | ||||||
|       setType(VALUE_IS_OWNED_RAW); |       setType(VALUE_IS_OWNED_RAW); | ||||||
| @@ -223,20 +223,20 @@ class VariantData { | |||||||
|     setType(VALUE_IS_NULL); |     setType(VALUE_IS_NULL); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void setStringPointer(const char *s, storage_policies::store_by_copy) { |   void setString(CopiedString s) { | ||||||
|     ARDUINOJSON_ASSERT(s != 0); |     ARDUINOJSON_ASSERT(s); | ||||||
|     setType(VALUE_IS_OWNED_STRING); |     setType(VALUE_IS_OWNED_STRING); | ||||||
|     _content.asString = s; |     _content.asString = s.c_str(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void setStringPointer(const char *s, storage_policies::store_by_address) { |   void setString(LinkedString s) { | ||||||
|     ARDUINOJSON_ASSERT(s != 0); |     ARDUINOJSON_ASSERT(s); | ||||||
|     setType(VALUE_IS_LINKED_STRING); |     setType(VALUE_IS_LINKED_STRING); | ||||||
|     _content.asString = s; |     _content.asString = s.c_str(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename TAdaptedString> |   template <typename TAdaptedString> | ||||||
|   bool setString(TAdaptedString value, MemoryPool *pool) { |   bool storeString(TAdaptedString value, MemoryPool *pool) { | ||||||
|     return storeString(value, pool, typename TAdaptedString::storage_policy()); |     return storeString(value, pool, typename TAdaptedString::storage_policy()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -342,7 +342,7 @@ class VariantData { | |||||||
|     if (value.isNull()) |     if (value.isNull()) | ||||||
|       setNull(); |       setNull(); | ||||||
|     else |     else | ||||||
|       setStringPointer(value.data(), storage_policies::store_by_address()); |       setString(LinkedString(value.data())); | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -358,7 +358,7 @@ class VariantData { | |||||||
|       setNull(); |       setNull(); | ||||||
|       return false; |       return false; | ||||||
|     } |     } | ||||||
|     setStringPointer(copy, storage_policies::store_by_copy()); |     setString(CopiedString(copy)); | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ inline bool variantSetString(VariantData *var, TAdaptedString value, | |||||||
|                              MemoryPool *pool) { |                              MemoryPool *pool) { | ||||||
|   if (!var) |   if (!var) | ||||||
|     return false; |     return false; | ||||||
|   return var->setString(value, pool); |   return var->storeString(value, pool); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline size_t variantSize(const VariantData *var) { | inline size_t variantSize(const VariantData *var) { | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ | |||||||
| #include <ArduinoJson/Polyfills/limits.hpp> | #include <ArduinoJson/Polyfills/limits.hpp> | ||||||
| #include <ArduinoJson/Polyfills/type_traits.hpp> | #include <ArduinoJson/Polyfills/type_traits.hpp> | ||||||
| #include <ArduinoJson/Strings/StoragePolicy.hpp> | #include <ArduinoJson/Strings/StoragePolicy.hpp> | ||||||
|  | #include <ArduinoJson/Strings/StoredString.hpp> | ||||||
| #include <ArduinoJson/Variant/VariantContent.hpp> | #include <ArduinoJson/Variant/VariantContent.hpp> | ||||||
|  |  | ||||||
| namespace ARDUINOJSON_NAMESPACE { | namespace ARDUINOJSON_NAMESPACE { | ||||||
| @@ -77,16 +78,16 @@ class VariantSlot { | |||||||
|     _next = VariantSlotDiff(slot - this); |     _next = VariantSlotDiff(slot - this); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void setKey(const char* k, storage_policies::store_by_copy) { |   void setKey(CopiedString k) { | ||||||
|     ARDUINOJSON_ASSERT(k != NULL); |     ARDUINOJSON_ASSERT(k); | ||||||
|     _flags |= OWNED_KEY_BIT; |     _flags |= OWNED_KEY_BIT; | ||||||
|     _key = k; |     _key = k.c_str(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void setKey(const char* k, storage_policies::store_by_address) { |   void setKey(LinkedString k) { | ||||||
|     ARDUINOJSON_ASSERT(k != NULL); |     ARDUINOJSON_ASSERT(k); | ||||||
|     _flags &= VALUE_MASK; |     _flags &= VALUE_MASK; | ||||||
|     _key = k; |     _key = k.c_str(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   const char* key() const { |   const char* key() const { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user