Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MemoryPool.hpp
00001 // ArduinoJson - arduinojson.org 00002 // Copyright Benoit Blanchon 2014-2021 00003 // MIT License 00004 00005 #pragma once 00006 00007 #include <ArduinoJson/Memory/Alignment.hpp> 00008 #include <ArduinoJson/Polyfills/assert.hpp> 00009 #include <ArduinoJson/Polyfills/mpl/max.hpp> 00010 #include <ArduinoJson/Variant/VariantSlot.hpp> 00011 00012 #include <string.h> // memmove 00013 00014 #define JSON_STRING_SIZE(SIZE) (SIZE + 1) 00015 00016 namespace ARDUINOJSON_NAMESPACE { 00017 00018 // _begin _end 00019 // v v 00020 // +-------------+--------------+--------------+ 00021 // | strings... | (free) | ...variants | 00022 // +-------------+--------------+--------------+ 00023 // ^ ^ 00024 // _left _right 00025 00026 class MemoryPool { 00027 public: 00028 MemoryPool(char* buf, size_t capa) 00029 : _begin(buf), 00030 _left(buf), 00031 _right(buf ? buf + capa : 0), 00032 _end(buf ? buf + capa : 0), 00033 _overflowed(false) { 00034 ARDUINOJSON_ASSERT(isAligned(_begin)); 00035 ARDUINOJSON_ASSERT(isAligned(_right)); 00036 ARDUINOJSON_ASSERT(isAligned(_end)); 00037 } 00038 00039 void* buffer() { 00040 return _begin; 00041 } 00042 00043 // Gets the capacity of the memoryPool in bytes 00044 size_t capacity() const { 00045 return size_t(_end - _begin); 00046 } 00047 00048 size_t size() const { 00049 return size_t(_left - _begin + _end - _right); 00050 } 00051 00052 bool overflowed() const { 00053 return _overflowed; 00054 } 00055 00056 VariantSlot* allocVariant() { 00057 return allocRight<VariantSlot>(); 00058 } 00059 00060 template <typename TAdaptedString> 00061 const char* saveString(const TAdaptedString& str) { 00062 if (str.isNull()) 00063 return 0; 00064 00065 #if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 00066 const char* existingCopy = findString(str.begin()); 00067 if (existingCopy) 00068 return existingCopy; 00069 #endif 00070 00071 size_t n = str.size(); 00072 00073 char* newCopy = allocString(n + 1); 00074 if (newCopy) { 00075 str.copyTo(newCopy, n); 00076 newCopy[n] = 0; // force null-terminator 00077 } 00078 return newCopy; 00079 } 00080 00081 void getFreeZone(char** zoneStart, size_t* zoneSize) const { 00082 *zoneStart = _left; 00083 *zoneSize = size_t(_right - _left); 00084 } 00085 00086 const char* saveStringFromFreeZone(size_t len) { 00087 #if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 00088 const char* dup = findString(_left); 00089 if (dup) 00090 return dup; 00091 #endif 00092 00093 const char* str = _left; 00094 _left += len; 00095 checkInvariants(); 00096 return str; 00097 } 00098 00099 void markAsOverflowed() { 00100 _overflowed = true; 00101 } 00102 00103 void clear() { 00104 _left = _begin; 00105 _right = _end; 00106 _overflowed = false; 00107 } 00108 00109 bool canAlloc(size_t bytes) const { 00110 return _left + bytes <= _right; 00111 } 00112 00113 bool owns(void* p) const { 00114 return _begin <= p && p < _end; 00115 } 00116 00117 // Workaround for missing placement new 00118 void* operator new(size_t, void* p) { 00119 return p; 00120 } 00121 00122 // Squash the free space between strings and variants 00123 // 00124 // _begin _end 00125 // v v 00126 // +-------------+--------------+ 00127 // | strings... | ...variants | 00128 // +-------------+--------------+ 00129 // ^ 00130 // _left _right 00131 // 00132 // This funcion is called before a realloc. 00133 ptrdiff_t squash() { 00134 char* new_right = addPadding(_left); 00135 if (new_right >= _right) 00136 return 0; 00137 00138 size_t right_size = static_cast<size_t>(_end - _right); 00139 memmove(new_right, _right, right_size); 00140 00141 ptrdiff_t bytes_reclaimed = _right - new_right; 00142 _right = new_right; 00143 _end = new_right + right_size; 00144 return bytes_reclaimed; 00145 } 00146 00147 // Move all pointers together 00148 // This funcion is called after a realloc. 00149 void movePointers(ptrdiff_t offset) { 00150 _begin += offset; 00151 _left += offset; 00152 _right += offset; 00153 _end += offset; 00154 } 00155 00156 private: 00157 void checkInvariants() { 00158 ARDUINOJSON_ASSERT(_begin <= _left); 00159 ARDUINOJSON_ASSERT(_left <= _right); 00160 ARDUINOJSON_ASSERT(_right <= _end); 00161 ARDUINOJSON_ASSERT(isAligned(_right)); 00162 } 00163 00164 #if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 00165 template <typename TIterator> 00166 const char* findString(TIterator str) { 00167 for (char* next = _begin; next < _left; ++next) { 00168 char* begin = next; 00169 00170 // try to match 00171 for (TIterator it = str; *it == *next; ++it) { 00172 if (*next++ == 0) 00173 return begin; 00174 } 00175 00176 // jump to next terminator 00177 while (*next) ++next; 00178 } 00179 return 0; 00180 } 00181 #endif 00182 00183 char* allocString(size_t n) { 00184 if (!canAlloc(n)) { 00185 _overflowed = true; 00186 return 0; 00187 } 00188 char* s = _left; 00189 _left += n; 00190 checkInvariants(); 00191 return s; 00192 } 00193 00194 template <typename T> 00195 T* allocRight() { 00196 return reinterpret_cast<T*>(allocRight(sizeof(T))); 00197 } 00198 00199 void* allocRight(size_t bytes) { 00200 if (!canAlloc(bytes)) { 00201 _overflowed = true; 00202 return 0; 00203 } 00204 _right -= bytes; 00205 return _right; 00206 } 00207 00208 char *_begin, *_left, *_right, *_end; 00209 bool _overflowed; 00210 }; 00211 00212 } // namespace ARDUINOJSON_NAMESPACE
Generated on Wed Jul 13 2022 01:10:36 by
1.7.2