mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Added string deduplication (closes #1303)
This commit is contained in:
		| @@ -51,40 +51,43 @@ class MemoryPool { | ||||
|     return allocRight<VariantSlot>(); | ||||
|   } | ||||
|  | ||||
|   char* allocFrozenString(size_t n) { | ||||
|     if (!canAlloc(n)) | ||||
|       return 0; | ||||
|     char* s = _left; | ||||
|     _left += n; | ||||
|     checkInvariants(); | ||||
|     return s; | ||||
|   } | ||||
|  | ||||
|   template <typename TAdaptedString> | ||||
|   char* saveString(const TAdaptedString& str) { | ||||
|   const char* saveString(const TAdaptedString& str) { | ||||
|     if (str.isNull()) | ||||
|       return 0; | ||||
|  | ||||
| #if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION | ||||
|     const char* existingCopy = findString(str.begin()); | ||||
|     if (existingCopy) | ||||
|       return existingCopy; | ||||
| #endif | ||||
|  | ||||
|     size_t n = str.size(); | ||||
|     char* dup = allocFrozenString(n + 1); | ||||
|     if (dup) { | ||||
|       str.copyTo(dup, n); | ||||
|       dup[n] = 0;  // force null-terminator | ||||
|  | ||||
|     char* newCopy = allocString(n + 1); | ||||
|     if (newCopy) { | ||||
|       str.copyTo(newCopy, n); | ||||
|       newCopy[n] = 0;  // force null-terminator | ||||
|     } | ||||
|     return dup; | ||||
|     return newCopy; | ||||
|   } | ||||
|  | ||||
|   StringSlot allocExpandableString() { | ||||
|     StringSlot s; | ||||
|     s.value = _left; | ||||
|     s.size = size_t(_right - _left); | ||||
|     checkInvariants(); | ||||
|     return s; | ||||
|   void getFreeZone(char** zoneStart, size_t* zoneSize) const { | ||||
|     *zoneStart = _left; | ||||
|     *zoneSize = size_t(_right - _left); | ||||
|   } | ||||
|  | ||||
|   void freezeString(StringSlot& s, size_t newSize) { | ||||
|     _left = (s.value + newSize); | ||||
|     s.size = newSize; | ||||
|   const char* saveStringFromFreeZone(size_t len) { | ||||
| #if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION | ||||
|     const char* dup = findString(_left); | ||||
|     if (dup) | ||||
|       return dup; | ||||
| #endif | ||||
|  | ||||
|     const char* str = _left; | ||||
|     _left += len; | ||||
|     checkInvariants(); | ||||
|     return str; | ||||
|   } | ||||
|  | ||||
|   void clear() { | ||||
| @@ -100,18 +103,6 @@ class MemoryPool { | ||||
|     return _begin <= p && p < _end; | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   T* allocRight() { | ||||
|     return reinterpret_cast<T*>(allocRight(sizeof(T))); | ||||
|   } | ||||
|  | ||||
|   void* allocRight(size_t bytes) { | ||||
|     if (!canAlloc(bytes)) | ||||
|       return 0; | ||||
|     _right -= bytes; | ||||
|     return _right; | ||||
|   } | ||||
|  | ||||
|   // Workaround for missing placement new | ||||
|   void* operator new(size_t, void* p) { | ||||
|     return p; | ||||
| @@ -163,6 +154,46 @@ class MemoryPool { | ||||
|     ARDUINOJSON_ASSERT(isAligned(_right)); | ||||
|   } | ||||
|  | ||||
| #if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION | ||||
|   template <typename TIterator> | ||||
|   const char* findString(TIterator str) { | ||||
|     for (char* next = _begin; next < _left; ++next) { | ||||
|       char* begin = next; | ||||
|  | ||||
|       // try to match | ||||
|       for (TIterator it = str; *it == *next; ++it) { | ||||
|         if (*next++ == 0) | ||||
|           return begin; | ||||
|       } | ||||
|  | ||||
|       // jump to next terminator | ||||
|       while (*next) ++next; | ||||
|     } | ||||
|     return 0; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   char* allocString(size_t n) { | ||||
|     if (!canAlloc(n)) | ||||
|       return 0; | ||||
|     char* s = _left; | ||||
|     _left += n; | ||||
|     checkInvariants(); | ||||
|     return s; | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   T* allocRight() { | ||||
|     return reinterpret_cast<T*>(allocRight(sizeof(T))); | ||||
|   } | ||||
|  | ||||
|   void* allocRight(size_t bytes) { | ||||
|     if (!canAlloc(bytes)) | ||||
|       return 0; | ||||
|     _right -= bytes; | ||||
|     return _right; | ||||
|   } | ||||
|  | ||||
|   char *_begin, *_left, *_right, *_end; | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user