rapidjson.h
Go to the documentation of this file.
1 #ifndef RAPIDJSON_RAPIDJSON_H_
2 #define RAPIDJSON_RAPIDJSON_H_
3 
4 // Copyright (c) 2011-2023 Milo Yip (miloyip@gmail.com)
5 // Version 0.11
6 
7 #include <cstdlib> // malloc(), realloc(), free()
8 #include <cstring> // memcpy()
9 
11 // RAPIDJSON_NO_INT64DEFINE
12 
13 // Here defines int64_t and uint64_t types in global namespace.
14 // If user have their own definition, can define RAPIDJSON_NO_INT64DEFINE to disable this.
15 #ifndef RAPIDJSON_NO_INT64DEFINE
16 #ifdef _MSC_VER
17 typedef __int64 int64_t;
18 typedef unsigned __int64 uint64_t;
19 #else
20 #include <inttypes.h>
21 #endif
22 #endif // RAPIDJSON_NO_INT64TYPEDEF
23 
25 // RAPIDJSON_ENDIAN
26 #define RAPIDJSON_LITTLEENDIAN 0
27 #define RAPIDJSON_BIGENDIAN 1
28 
30 
34 #ifndef RAPIDJSON_ENDIAN
35 #ifdef __BYTE_ORDER__
36 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
37 #define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
38 #else
39 #define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
40 #endif // __BYTE_ORDER__
41 #else
42 #define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN // Assumes little endian otherwise.
43 #endif
44 #endif // RAPIDJSON_ENDIAN
45 
47 // RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD
48 
49 // Enable SSE2 optimization.
50 //#define RAPIDJSON_SSE2
51 
52 // Enable SSE4.2 optimization.
53 //#define RAPIDJSON_SSE42
54 
55 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
56 #define RAPIDJSON_SIMD
57 #endif
58 
60 // RAPIDJSON_NO_SIZETYPEDEFINE
61 
62 #ifndef RAPIDJSON_NO_SIZETYPEDEFINE
63 namespace rapidjson {
65 
67  typedef unsigned SizeType;
68 } // namespace rapidjson
69 #endif
70 
72 // RAPIDJSON_ASSERT
73 
75 
78 #ifndef RAPIDJSON_ASSERT
79 #include <cassert>
80 #define RAPIDJSON_ASSERT(x) assert(x)
81 #endif // RAPIDJSON_ASSERT
82 
84 // Helpers
85 
86 #define RAPIDJSON_MULTILINEMACRO_BEGIN do {
87 #define RAPIDJSON_MULTILINEMACRO_END \
88 } while((void)0, 0)
89 
90 namespace rapidjson {
91 
93 // Allocator
94 
126 // CrtAllocator
127 
129 
132  class CrtAllocator {
133  public:
134  static const bool kNeedFree = true;
135  void* Malloc(size_t size) { return malloc(size); }
136  void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; return realloc(originalPtr, newSize); }
137  static void Free(void *ptr) { free(ptr); }
138  };
139 
141 // MemoryPoolAllocator
142 
144 
159  template <typename BaseAllocator = CrtAllocator>
161  public:
162  static const bool kNeedFree = false;
163 
165 
168  MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
169  chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
170  {
171  if (!baseAllocator_)
172  ownBaseAllocator_ = baseAllocator_ = new BaseAllocator();
174  }
175 
177 
186  MemoryPoolAllocator(char *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
187  chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
188  {
189  RAPIDJSON_ASSERT(buffer != 0);
190  RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
191  chunkHead_ = (ChunkHeader*)buffer;
192  chunkHead_->capacity = size - sizeof(ChunkHeader);
193  chunkHead_->size = 0;
194  chunkHead_->next = 0;
195  }
196 
198 
201  Clear();
202  delete ownBaseAllocator_;
203  }
204 
206  void Clear() {
207  while(chunkHead_ != 0 && chunkHead_ != (ChunkHeader *)userBuffer_) {
208  ChunkHeader* next = chunkHead_->next;
209  baseAllocator_->Free(chunkHead_);
210  chunkHead_ = next;
211  }
212  }
213 
215 
217  size_t Capacity() {
218  size_t capacity = 0;
219  for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
220  capacity += c->capacity;
221  return capacity;
222  }
223 
225 
227  size_t Size() {
228  size_t size = 0;
229  for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
230  size += c->size;
231  return size;
232  }
233 
235  void* Malloc(size_t size) {
236  size = (size + 3) & ~3; // Force aligning size to 4
237 
240 
241  char *buffer = (char *)(chunkHead_ + 1) + chunkHead_->size;
242  RAPIDJSON_ASSERT(((uintptr_t)buffer & 3) == 0); // returned buffer is aligned to 4
243  chunkHead_->size += size;
244 
245  return buffer;
246  }
247 
249  void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
250  if (originalPtr == 0)
251  return Malloc(newSize);
252 
253  // Do not shrink if new size is smaller than original
254  if (originalSize >= newSize)
255  return originalPtr;
256 
257  // Simply expand it if it is the last allocation and there is sufficient space
258  if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) {
259  size_t increment = newSize - originalSize;
260  increment = (increment + 3) & ~3; // Force aligning size to 4
261  if (chunkHead_->size + increment <= chunkHead_->capacity) {
262  chunkHead_->size += increment;
263  RAPIDJSON_ASSERT(((uintptr_t)originalPtr & 3) == 0); // returned buffer is aligned to 4
264  return originalPtr;
265  }
266  }
267 
268  // Realloc process: allocate and copy memory, do not free original buffer.
269  void* newBuffer = Malloc(newSize);
270  RAPIDJSON_ASSERT(newBuffer != 0); // Do not handle out-of-memory explicitly.
271  return memcpy(newBuffer, originalPtr, originalSize);
272  }
273 
275  static void Free(void *) {} // Do nothing
276 
277  private:
279 
281  void AddChunk(size_t capacity) {
282  ChunkHeader* chunk = (ChunkHeader*)baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity);
283  chunk->capacity = capacity;
284  chunk->size = 0;
285  chunk->next = chunkHead_;
286  chunkHead_ = chunk;
287  }
288 
289  static const int kDefaultChunkCapacity = 64 * 1024;
290 
292 
294  struct ChunkHeader {
295  size_t capacity;
296  size_t size;
298  };
299 
302  char *userBuffer_;
303  BaseAllocator* baseAllocator_;
304  BaseAllocator* ownBaseAllocator_;
305  };
306 
308 // Encoding
309 
321 
327 // UTF8
328 
330 
334  template<typename CharType = char>
335  struct UTF8 {
336  typedef CharType Ch;
337 
338  static Ch* Encode(Ch *buffer, unsigned codepoint) {
339  if (codepoint <= 0x7F)
340  *buffer++ = codepoint & 0xFF;
341  else if (codepoint <= 0x7FF) {
342  *buffer++ = 0xC0 | ((codepoint >> 6) & 0xFF);
343  *buffer++ = 0x80 | ((codepoint & 0x3F));
344  }
345  else if (codepoint <= 0xFFFF) {
346  *buffer++ = 0xE0 | ((codepoint >> 12) & 0xFF);
347  *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);
348  *buffer++ = 0x80 | (codepoint & 0x3F);
349  }
350  else {
351  RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
352  *buffer++ = 0xF0 | ((codepoint >> 18) & 0xFF);
353  *buffer++ = 0x80 | ((codepoint >> 12) & 0x3F);
354  *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);
355  *buffer++ = 0x80 | (codepoint & 0x3F);
356  }
357  return buffer;
358  }
359  };
360 
362 // UTF16
363 
365 
369  template<typename CharType = wchar_t>
370  struct UTF16 {
371  typedef CharType Ch;
372 
373  static Ch* Encode(Ch* buffer, unsigned codepoint) {
374  if (codepoint <= 0xFFFF) {
375  RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair
376  *buffer++ = static_cast<Ch>(codepoint);
377  }
378  else {
379  RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
380  unsigned v = codepoint - 0x10000;
381  *buffer++ = static_cast<Ch>((v >> 10) + 0xD800);
382  *buffer++ = (v & 0x3FF) + 0xDC00;
383  }
384  return buffer;
385  }
386  };
387 
389 // UTF32
390 
392 
396  template<typename CharType = unsigned>
397  struct UTF32 {
398  typedef CharType Ch;
399 
400  static Ch *Encode(Ch* buffer, unsigned codepoint) {
401  RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
402  *buffer++ = codepoint;
403  return buffer;
404  }
405  };
406 
408 // Stream
409 
422 
425 
429 
433 
436 
441 
447  template<typename Stream, typename Ch>
448  inline void PutN(Stream& stream, Ch c, size_t n) {
449  for (size_t i = 0; i < n; i++)
450  stream.Put(c);
451  }
452 
454 // StringStream
455 
457 
459  template <typename Encoding>
461  typedef typename Encoding::Ch Ch;
462 
463  GenericStringStream(const Ch *src) : src_(src), head_(src) {}
464 
465  Ch Peek() const { return *src_; }
466  Ch Take() { return *src_++; }
467  size_t Tell() const { return src_ - head_; }
468 
469  Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
470  void Put(Ch) { RAPIDJSON_ASSERT(false); }
471  size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
472 
473  const Ch* src_;
474  const Ch* head_;
475  };
476 
478 
480 // InsituStringStream
481 
483 
486  template <typename Encoding>
488  typedef typename Encoding::Ch Ch;
489 
490  GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
491 
492  // Read
493  Ch Peek() { return *src_; }
494  Ch Take() { return *src_++; }
495  size_t Tell() { return src_ - head_; }
496 
497  // Write
498  Ch* PutBegin() { return dst_ = src_; }
499  void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
500  size_t PutEnd(Ch* begin) { return dst_ - begin; }
501 
505  };
506 
508 
510 // Type
511 
513  enum Type {
516  kTrueType = 2,
521  };
522 
523 } // namespace rapidjson
524 
525 #endif // RAPIDJSON_RAPIDJSON_H_
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
C-runtime library allocator.
Definition: rapidjson.h:132
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Definition: rapidjson.h:136
static const bool kNeedFree
Definition: rapidjson.h:134
void * Malloc(size_t size)
Definition: rapidjson.h:135
static void Free(void *ptr)
Definition: rapidjson.h:137
Default memory allocator used by the parser and DOM.
Definition: rapidjson.h:160
void * Malloc(size_t size)
Allocates a memory block. (concept Allocator)
Definition: rapidjson.h:235
static const bool kNeedFree
Tell users that no need to call Free() with this allocator. (concept Allocator)
Definition: rapidjson.h:162
char * userBuffer_
User supplied buffer.
Definition: rapidjson.h:302
MemoryPoolAllocator(size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with chunkSize.
Definition: rapidjson.h:168
size_t chunk_capacity_
The minimum capacity of chunk when they are allocated.
Definition: rapidjson.h:301
MemoryPoolAllocator(char *buffer, size_t size, size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with user-supplied buffer.
Definition: rapidjson.h:186
ChunkHeader * chunkHead_
Head of the chunk linked-list. Only the head chunk serves allocation.
Definition: rapidjson.h:300
size_t Capacity()
Computes the total capacity of allocated memory chunks.
Definition: rapidjson.h:217
size_t Size()
Computes the memory blocks allocated.
Definition: rapidjson.h:227
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Resizes a memory block (concept Allocator)
Definition: rapidjson.h:249
void AddChunk(size_t capacity)
Creates a new chunk.
Definition: rapidjson.h:281
void Clear()
Deallocates all memory chunks, excluding the user-supplied buffer.
Definition: rapidjson.h:206
~MemoryPoolAllocator()
Destructor.
Definition: rapidjson.h:200
static void Free(void *)
Frees a memory block (concept Allocator)
Definition: rapidjson.h:275
BaseAllocator * baseAllocator_
base allocator for allocating memory chunks.
Definition: rapidjson.h:303
static const int kDefaultChunkCapacity
Default chunk capacity.
Definition: rapidjson.h:289
BaseAllocator * ownBaseAllocator_
base allocator created by this object.
Definition: rapidjson.h:304
Concept for reading and writing characters.
std::int64_t int64_t
Definition: Meta.h:43
std::uint64_t uint64_t
Definition: Meta.h:42
int c
Definition: calibrate.py:100
Definition: document.h:13
unsigned SizeType
Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
Definition: rapidjson.h:67
GenericInsituStringStream< UTF8<> > InsituStringStream
Definition: rapidjson.h:507
void PutN(GenericWriteStream &stream, char c, size_t n)
Definition: genericstream.h:88
GenericStringStream< UTF8<> > StringStream
Definition: rapidjson.h:477
Type
Type of JSON value.
Definition: rapidjson.h:513
@ kArrayType
array
Definition: rapidjson.h:518
@ kNull_Type
null
Definition: rapidjson.h:514
@ kTrueType
true
Definition: rapidjson.h:516
@ kFalseType
false
Definition: rapidjson.h:515
@ kNumberType
number
Definition: rapidjson.h:520
@ kObjectType
object
Definition: rapidjson.h:517
@ kStringType
string
Definition: rapidjson.h:519
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:80
A read-write string stream.
Definition: rapidjson.h:487
Ch Peek()
Definition: rapidjson.h:493
Ch * PutBegin()
Definition: rapidjson.h:498
size_t Tell()
Definition: rapidjson.h:495
Encoding::Ch Ch
Definition: rapidjson.h:488
GenericInsituStringStream(Ch *src)
Definition: rapidjson.h:490
Ch * head_
Definition: rapidjson.h:504
size_t PutEnd(Ch *begin)
Definition: rapidjson.h:500
Ch Take()
Definition: rapidjson.h:494
void Put(Ch c)
Definition: rapidjson.h:499
Ch * dst_
Definition: rapidjson.h:503
Ch * src_
Definition: rapidjson.h:502
Read-only string stream.
Definition: rapidjson.h:460
size_t PutEnd(Ch *)
Definition: rapidjson.h:471
const Ch * head_
Original head of the string.
Definition: rapidjson.h:474
Ch Take()
Definition: rapidjson.h:466
Encoding::Ch Ch
Definition: rapidjson.h:461
size_t Tell() const
Definition: rapidjson.h:467
const Ch * src_
Current read position.
Definition: rapidjson.h:473
void Put(Ch)
Definition: rapidjson.h:470
Ch Peek() const
Definition: rapidjson.h:465
GenericStringStream(const Ch *src)
Definition: rapidjson.h:463
Ch * PutBegin()
Definition: rapidjson.h:469
Chunk header for perpending to each chunk.
Definition: rapidjson.h:294
size_t capacity
Capacity of the chunk in bytes (excluding the header itself).
Definition: rapidjson.h:295
ChunkHeader * next
Next chunk in the linked list.
Definition: rapidjson.h:297
size_t size
Current size of allocated memory in bytes.
Definition: rapidjson.h:296
UTF-16 encoding.
Definition: rapidjson.h:370
static Ch * Encode(Ch *buffer, unsigned codepoint)
Definition: rapidjson.h:373
CharType Ch
Definition: rapidjson.h:371
UTF-32 encoding.
Definition: rapidjson.h:397
static Ch * Encode(Ch *buffer, unsigned codepoint)
Definition: rapidjson.h:400
CharType Ch
Definition: rapidjson.h:398
UTF-8 encoding.
Definition: rapidjson.h:335
CharType Ch
Definition: rapidjson.h:336
static Ch * Encode(Ch *buffer, unsigned codepoint)
Definition: rapidjson.h:338