allocators.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON
2 // available.
3 //
4 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All
5 // rights reserved.
6 //
7 // Licensed under the MIT License (the "License"); you may not use this file
8 // except in compliance with the License. You may obtain a copy of the License
9 // at
10 //
11 // http://opensource.org/licenses/MIT
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 // License for the specific language governing permissions and limitations under
17 // the License.
18 
19 #ifndef RAPIDJSON_ALLOCATORS_H_
20 #define RAPIDJSON_ALLOCATORS_H_
21 
22 #include "rapidjson.h"
23 
25 
27 // Allocator
28 
69 #ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
70 #define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024)
71 #endif
72 
74 // CrtAllocator
75 
77 
80 class CrtAllocator {
81  public:
82  static const bool kNeedFree = true;
83  void *Malloc(size_t size) {
84  if (size) // behavior of malloc(0) is implementation defined.
85  return std::malloc(size);
86  else
87  return NULL; // standardize to returning NULL.
88  }
89  void *Realloc(void *originalPtr, size_t originalSize, size_t newSize) {
90  (void)originalSize;
91  if (newSize == 0) {
92  std::free(originalPtr);
93  return NULL;
94  }
95  return std::realloc(originalPtr, newSize);
96  }
97  static void Free(void *ptr) { std::free(ptr); }
98 };
99 
101 // MemoryPoolAllocator
102 
104 
121 template <typename BaseAllocator = CrtAllocator>
123  public:
124  static const bool kNeedFree =
125  false;
126 
129 
133  MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity,
134  BaseAllocator *baseAllocator = 0)
135  : chunkHead_(0),
136  chunk_capacity_(chunkSize),
137  userBuffer_(0),
138  baseAllocator_(baseAllocator),
139  ownBaseAllocator_(0) {}
140 
142 
153  MemoryPoolAllocator(void *buffer, size_t size,
154  size_t chunkSize = kDefaultChunkCapacity,
155  BaseAllocator *baseAllocator = 0)
156  : chunkHead_(0),
157  chunk_capacity_(chunkSize),
158  userBuffer_(buffer),
159  baseAllocator_(baseAllocator),
160  ownBaseAllocator_(0) {
161  RAPIDJSON_ASSERT(buffer != 0);
162  RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
163  chunkHead_ = reinterpret_cast<ChunkHeader *>(buffer);
164  chunkHead_->capacity = size - sizeof(ChunkHeader);
165  chunkHead_->size = 0;
166  chunkHead_->next = 0;
167  }
168 
170 
173  Clear();
174  RAPIDJSON_DELETE(ownBaseAllocator_);
175  }
176 
178  void Clear() {
179  while (chunkHead_ && chunkHead_ != userBuffer_) {
180  ChunkHeader *next = chunkHead_->next;
181  baseAllocator_->Free(chunkHead_);
182  chunkHead_ = next;
183  }
184  if (chunkHead_ && chunkHead_ == userBuffer_)
185  chunkHead_->size = 0; // Clear user buffer
186  }
187 
189 
191  size_t Capacity() const {
192  size_t capacity = 0;
193  for (ChunkHeader *c = chunkHead_; c != 0; c = c->next)
194  capacity += c->capacity;
195  return capacity;
196  }
197 
199 
201  size_t Size() const {
202  size_t size = 0;
203  for (ChunkHeader *c = chunkHead_; c != 0; c = c->next) size += c->size;
204  return size;
205  }
206 
208  void *Malloc(size_t size) {
209  if (!size) return NULL;
210 
211  size = RAPIDJSON_ALIGN(size);
212  if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
213  if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
214  return NULL;
215 
216  void *buffer = reinterpret_cast<char *>(chunkHead_) +
217  RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;
218  chunkHead_->size += size;
219  return buffer;
220  }
221 
223  void *Realloc(void *originalPtr, size_t originalSize, size_t newSize) {
224  if (originalPtr == 0) return Malloc(newSize);
225 
226  if (newSize == 0) return NULL;
227 
228  originalSize = RAPIDJSON_ALIGN(originalSize);
229  newSize = RAPIDJSON_ALIGN(newSize);
230 
231  // Do not shrink if new size is smaller than original
232  if (originalSize >= newSize) return originalPtr;
233 
234  // Simply expand it if it is the last allocation and there is sufficient
235  // space
236  if (originalPtr ==
237  reinterpret_cast<char *>(chunkHead_) +
238  RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size -
239  originalSize) {
240  size_t increment = static_cast<size_t>(newSize - originalSize);
241  if (chunkHead_->size + increment <= chunkHead_->capacity) {
242  chunkHead_->size += increment;
243  return originalPtr;
244  }
245  }
246 
247  // Realloc process: allocate and copy memory, do not free original buffer.
248  if (void *newBuffer = Malloc(newSize)) {
249  if (originalSize) std::memcpy(newBuffer, originalPtr, originalSize);
250  return newBuffer;
251  } else
252  return NULL;
253  }
254 
256  static void Free(void *ptr) { (void)ptr; } // Do nothing
257 
258  private:
260  MemoryPoolAllocator(const MemoryPoolAllocator &rhs) /* = delete */;
262  MemoryPoolAllocator &operator=(const MemoryPoolAllocator &rhs) /* = delete */;
263 
265 
268  bool AddChunk(size_t capacity) {
269  if (!baseAllocator_)
270  ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
271  if (ChunkHeader *chunk =
272  reinterpret_cast<ChunkHeader *>(baseAllocator_->Malloc(
273  RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) {
274  chunk->capacity = capacity;
275  chunk->size = 0;
276  chunk->next = chunkHead_;
277  chunkHead_ = chunk;
278  return true;
279  } else
280  return false;
281  }
282 
283  static const int kDefaultChunkCapacity =
285 
287 
289  struct ChunkHeader {
290  size_t capacity;
291  size_t size;
294  };
295 
297  size_t chunk_capacity_;
299  void *userBuffer_;
301  BaseAllocator
303  BaseAllocator *ownBaseAllocator_;
304 };
305 
307 
308 #endif // RAPIDJSON_ENCODINGS_H_
size_t Capacity() const
Computes the total capacity of allocated memory chunks.
Definition: allocators.h:191
#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
User-defined kDefaultChunkCapacity definition.
Definition: allocators.h:70
BaseAllocator * ownBaseAllocator_
base allocator created by this object.
Definition: allocators.h:303
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:433
void * Malloc(size_t size)
Allocates a memory block. (concept Allocator)
Definition: allocators.h:208
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:131
void * Malloc(size_t size)
Definition: allocators.h:83
size_t Size() const
Computes the memory blocks allocated.
Definition: allocators.h:201
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:128
void Clear()
Deallocates all memory chunks, excluding the user-supplied buffer.
Definition: allocators.h:178
Chunk header for perpending to each chunk.
Definition: allocators.h:289
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:690
bool AddChunk(size_t capacity)
Creates a new chunk.
Definition: allocators.h:268
ChunkHeader * chunkHead_
Definition: allocators.h:296
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Definition: allocators.h:89
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:694
BaseAllocator * baseAllocator_
base allocator for allocating memory chunks.
Definition: allocators.h:302
size_t size
Current size of allocated memory in bytes.
Definition: allocators.h:292
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Resizes a memory block (concept Allocator)
Definition: allocators.h:223
C-runtime library allocator.
Definition: allocators.h:80
common definitions and configuration
static void Free(void *ptr)
Definition: allocators.h:97
static void Free(void *ptr)
Frees a memory block (concept Allocator)
Definition: allocators.h:256
static const bool kNeedFree
Definition: allocators.h:82
ChunkHeader * next
Next chunk in the linked list.
Definition: allocators.h:293
#define RAPIDJSON_ALIGN(x)
Data alignment of the machine.
Definition: rapidjson.h:292
MemoryPoolAllocator(size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with chunkSize.
Definition: allocators.h:133
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with user-supplied buffer.
Definition: allocators.h:153
Default memory allocator used by the parser and DOM.
Definition: allocators.h:122
~MemoryPoolAllocator()
Destructor.
Definition: allocators.h:172


livox_ros_driver
Author(s): Livox Dev Team
autogenerated on Mon Mar 15 2021 02:40:45