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