rapidjson.h
Go to the documentation of this file.
1 //Copyright (c) 2013-2023, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 #ifndef RAPIDJSON_RAPIDJSON_H_
27 #define RAPIDJSON_RAPIDJSON_H_
28 
29 // Copyright (c) 2011-2023 Milo Yip (miloyip@gmail.com)
30 // Version 0.11
31 
32 #include <cstdlib> // malloc(), realloc(), free()
33 #include <cstring> // memcpy()
34 
36 // RAPIDJSON_NO_INT64DEFINE
37 
38 // Here defines int64_t and uint64_t types in global namespace.
39 // If user have their own definition, can define RAPIDJSON_NO_INT64DEFINE to disable this.
40 #ifndef RAPIDJSON_NO_INT64DEFINE
41 #ifdef _MSC_VER
42 typedef __int64 int64_t;
43 typedef unsigned __int64 uint64_t;
44 #else
45 #include <inttypes.h>
46 #endif
47 #endif // RAPIDJSON_NO_INT64TYPEDEF
48 
50 // RAPIDJSON_ENDIAN
51 #define RAPIDJSON_LITTLEENDIAN 0
52 #define RAPIDJSON_BIGENDIAN 1
53 
55 
59 #ifndef RAPIDJSON_ENDIAN
60 #ifdef __BYTE_ORDER__
61 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
62 #define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
63 #else
64 #define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
65 #endif // __BYTE_ORDER__
66 #else
67 #define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN // Assumes little endian otherwise.
68 #endif
69 #endif // RAPIDJSON_ENDIAN
70 
72 // RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD
73 
74 // Enable SSE2 optimization.
75 //#define RAPIDJSON_SSE2
76 
77 // Enable SSE4.2 optimization.
78 //#define RAPIDJSON_SSE42
79 
80 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
81 #define RAPIDJSON_SIMD
82 #endif
83 
85 // RAPIDJSON_NO_SIZETYPEDEFINE
86 
87 #ifndef RAPIDJSON_NO_SIZETYPEDEFINE
88 namespace rapidjson {
90 
92 typedef unsigned SizeType;
93 } // namespace rapidjson
94 #endif
95 
97 // RAPIDJSON_ASSERT
98 
100 
103 #ifndef RAPIDJSON_ASSERT
104 #include <cassert>
105 #define RAPIDJSON_ASSERT(x) assert(x)
106 #endif // RAPIDJSON_ASSERT
107 
109 // Helpers
110 
111 #define RAPIDJSON_MULTILINEMACRO_BEGIN do {
112 #define RAPIDJSON_MULTILINEMACRO_END \
113 } while((void)0, 0)
114 
115 namespace rapidjson {
116 
118 // Allocator
119 
151 // CrtAllocator
152 
154 
158 public:
159  static const bool kNeedFree = true;
160  void* Malloc(size_t size) { return malloc(size); }
161  void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; return realloc(originalPtr, newSize); }
162  static void Free(void *ptr) { free(ptr); }
163 };
164 
166 // MemoryPoolAllocator
167 
169 
184 template <typename BaseAllocator = CrtAllocator>
186 public:
187  static const bool kNeedFree = false;
188 
190 
193  MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
194  chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
195  {
196  if (!baseAllocator_)
197  ownBaseAllocator_ = baseAllocator_ = new BaseAllocator();
199  }
200 
202 
211  MemoryPoolAllocator(char *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
212  chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
213  {
214  RAPIDJSON_ASSERT(buffer != 0);
215  RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
216  chunkHead_ = (ChunkHeader*)buffer;
217  chunkHead_->capacity = size - sizeof(ChunkHeader);
218  chunkHead_->size = 0;
219  chunkHead_->next = 0;
220  }
221 
223 
226  Clear();
227  delete ownBaseAllocator_;
228  }
229 
231  void Clear() {
232  while(chunkHead_ != 0 && chunkHead_ != (ChunkHeader *)userBuffer_) {
233  ChunkHeader* next = chunkHead_->next;
234  baseAllocator_->Free(chunkHead_);
235  chunkHead_ = next;
236  }
237  }
238 
240 
242  size_t Capacity() {
243  size_t capacity = 0;
244  for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
245  capacity += c->capacity;
246  return capacity;
247  }
248 
250 
252  size_t Size() {
253  size_t size = 0;
254  for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
255  size += c->size;
256  return size;
257  }
258 
260  void* Malloc(size_t size) {
261  size = (size + 3) & ~3; // Force aligning size to 4
262 
263  if (chunkHead_->size + size > chunkHead_->capacity)
264  AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size);
265 
266  char *buffer = (char *)(chunkHead_ + 1) + chunkHead_->size;
267  RAPIDJSON_ASSERT(((uintptr_t)buffer & 3) == 0); // returned buffer is aligned to 4
268  chunkHead_->size += size;
269 
270  return buffer;
271  }
272 
274  void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
275  if (originalPtr == 0)
276  return Malloc(newSize);
277 
278  // Do not shrink if new size is smaller than original
279  if (originalSize >= newSize)
280  return originalPtr;
281 
282  // Simply expand it if it is the last allocation and there is sufficient space
283  if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) {
284  size_t increment = newSize - originalSize;
285  increment = (increment + 3) & ~3; // Force aligning size to 4
286  if (chunkHead_->size + increment <= chunkHead_->capacity) {
287  chunkHead_->size += increment;
288  RAPIDJSON_ASSERT(((uintptr_t)originalPtr & 3) == 0); // returned buffer is aligned to 4
289  return originalPtr;
290  }
291  }
292 
293  // Realloc process: allocate and copy memory, do not free original buffer.
294  void* newBuffer = Malloc(newSize);
295  RAPIDJSON_ASSERT(newBuffer != 0); // Do not handle out-of-memory explicitly.
296  return memcpy(newBuffer, originalPtr, originalSize);
297  }
298 
300  static void Free(void *) {} // Do nothing
301 
302 private:
304 
306  void AddChunk(size_t capacity) {
307  ChunkHeader* chunk = (ChunkHeader*)baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity);
308  chunk->capacity = capacity;
309  chunk->size = 0;
310  chunk->next = chunkHead_;
311  chunkHead_ = chunk;
312  }
313 
314  static const int kDefaultChunkCapacity = 64 * 1024;
315 
317 
319  struct ChunkHeader {
320  size_t capacity;
321  size_t size;
323  };
324 
327  char *userBuffer_;
328  BaseAllocator* baseAllocator_;
329  BaseAllocator* ownBaseAllocator_;
330 };
331 
333 // Encoding
334 
346 
352 // UTF8
353 
355 
359 template<typename CharType = char>
360 struct UTF8 {
361  typedef CharType Ch;
362 
363  static Ch* Encode(Ch *buffer, unsigned codepoint) {
364  if (codepoint <= 0x7F)
365  *buffer++ = codepoint & 0xFF;
366  else if (codepoint <= 0x7FF) {
367  *buffer++ = 0xC0 | ((codepoint >> 6) & 0xFF);
368  *buffer++ = 0x80 | ((codepoint & 0x3F));
369  }
370  else if (codepoint <= 0xFFFF) {
371  *buffer++ = 0xE0 | ((codepoint >> 12) & 0xFF);
372  *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);
373  *buffer++ = 0x80 | (codepoint & 0x3F);
374  }
375  else {
376  RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
377  *buffer++ = 0xF0 | ((codepoint >> 18) & 0xFF);
378  *buffer++ = 0x80 | ((codepoint >> 12) & 0x3F);
379  *buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);
380  *buffer++ = 0x80 | (codepoint & 0x3F);
381  }
382  return buffer;
383  }
384 };
385 
387 // UTF16
388 
390 
394 template<typename CharType = wchar_t>
395 struct UTF16 {
396  typedef CharType Ch;
397 
398  static Ch* Encode(Ch* buffer, unsigned codepoint) {
399  if (codepoint <= 0xFFFF) {
400  RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair
401  *buffer++ = static_cast<Ch>(codepoint);
402  }
403  else {
404  RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
405  unsigned v = codepoint - 0x10000;
406  *buffer++ = static_cast<Ch>((v >> 10) + 0xD800);
407  *buffer++ = (v & 0x3FF) + 0xDC00;
408  }
409  return buffer;
410  }
411 };
412 
414 // UTF32
415 
417 
421 template<typename CharType = unsigned>
422 struct UTF32 {
423  typedef CharType Ch;
424 
425  static Ch *Encode(Ch* buffer, unsigned codepoint) {
426  RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
427  *buffer++ = codepoint;
428  return buffer;
429  }
430 };
431 
433 // Stream
434 
447 
450 
454 
458 
461 
466 
472 template<typename Stream, typename Ch>
473 inline void PutN(Stream& stream, Ch c, size_t n) {
474  for (size_t i = 0; i < n; i++)
475  stream.Put(c);
476 }
477 
479 // StringStream
480 
482 
484 template <typename Encoding>
486  typedef typename Encoding::Ch Ch;
487 
488  GenericStringStream(const Ch *src) : src_(src), head_(src) {}
489 
490  Ch Peek() const { return *src_; }
491  Ch Take() { return *src_++; }
492  size_t Tell() const { return src_ - head_; }
493 
494  Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
495  void Put(Ch) { RAPIDJSON_ASSERT(false); }
496  size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
497 
498  const Ch* src_;
499  const Ch* head_;
500 };
501 
503 
505 // InsituStringStream
506 
508 
511 template <typename Encoding>
513  typedef typename Encoding::Ch Ch;
514 
515  GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
516 
517  // Read
518  Ch Peek() { return *src_; }
519  Ch Take() { return *src_++; }
520  size_t Tell() { return src_ - head_; }
521 
522  // Write
523  Ch* PutBegin() { return dst_ = src_; }
524  void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
525  size_t PutEnd(Ch* begin) { return dst_ - begin; }
526 
530 };
531 
533 
535 // Type
536 
538 enum Type {
541  kTrueType = 2,
546 };
547 
548 } // namespace rapidjson
549 
550 #endif // RAPIDJSON_RAPIDJSON_H_
const unsigned n
Definition: CG3DPackingUnitTest.cpp:32
C-runtime library allocator.
Definition: rapidjson.h:157
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Definition: rapidjson.h:161
static const bool kNeedFree
Definition: rapidjson.h:159
void * Malloc(size_t size)
Definition: rapidjson.h:160
static void Free(void *ptr)
Definition: rapidjson.h:162
Default memory allocator used by the parser and DOM.
Definition: rapidjson.h:185
void * Malloc(size_t size)
Allocates a memory block. (concept Allocator)
Definition: rapidjson.h:260
static const bool kNeedFree
Tell users that no need to call Free() with this allocator. (concept Allocator)
Definition: rapidjson.h:187
char * userBuffer_
User supplied buffer.
Definition: rapidjson.h:327
MemoryPoolAllocator(size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with chunkSize.
Definition: rapidjson.h:193
size_t chunk_capacity_
The minimum capacity of chunk when they are allocated.
Definition: rapidjson.h:326
MemoryPoolAllocator(char *buffer, size_t size, size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with user-supplied buffer.
Definition: rapidjson.h:211
ChunkHeader * chunkHead_
Head of the chunk linked-list. Only the head chunk serves allocation.
Definition: rapidjson.h:325
size_t Capacity()
Computes the total capacity of allocated memory chunks.
Definition: rapidjson.h:242
size_t Size()
Computes the memory blocks allocated.
Definition: rapidjson.h:252
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Resizes a memory block (concept Allocator)
Definition: rapidjson.h:274
void AddChunk(size_t capacity)
Creates a new chunk.
Definition: rapidjson.h:306
void Clear()
Deallocates all memory chunks, excluding the user-supplied buffer.
Definition: rapidjson.h:231
~MemoryPoolAllocator()
Destructor.
Definition: rapidjson.h:225
static void Free(void *)
Frees a memory block (concept Allocator)
Definition: rapidjson.h:300
BaseAllocator * baseAllocator_
base allocator for allocating memory chunks.
Definition: rapidjson.h:328
static const int kDefaultChunkCapacity
Default chunk capacity.
Definition: rapidjson.h:314
BaseAllocator * ownBaseAllocator_
base allocator created by this object.
Definition: rapidjson.h:329
Concept for reading and writing characters.
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51
Definition: document.h:38
unsigned SizeType
Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
Definition: rapidjson.h:92
GenericInsituStringStream< UTF8<> > InsituStringStream
Definition: rapidjson.h:532
void PutN(GenericWriteStream &stream, char c, size_t n)
Definition: genericstream.h:113
GenericStringStream< UTF8<> > StringStream
Definition: rapidjson.h:502
Type
Type of JSON value.
Definition: rapidjson.h:538
@ kArrayType
array
Definition: rapidjson.h:543
@ kNull_Type
null
Definition: rapidjson.h:539
@ kTrueType
true
Definition: rapidjson.h:541
@ kFalseType
false
Definition: rapidjson.h:540
@ kNumberType
number
Definition: rapidjson.h:545
@ kObjectType
object
Definition: rapidjson.h:542
@ kStringType
string
Definition: rapidjson.h:544
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:105
A read-write string stream.
Definition: rapidjson.h:512
Ch Peek()
Definition: rapidjson.h:518
Ch * PutBegin()
Definition: rapidjson.h:523
size_t Tell()
Definition: rapidjson.h:520
Encoding::Ch Ch
Definition: rapidjson.h:513
GenericInsituStringStream(Ch *src)
Definition: rapidjson.h:515
Ch * head_
Definition: rapidjson.h:529
size_t PutEnd(Ch *begin)
Definition: rapidjson.h:525
Ch Take()
Definition: rapidjson.h:519
void Put(Ch c)
Definition: rapidjson.h:524
Ch * dst_
Definition: rapidjson.h:528
Ch * src_
Definition: rapidjson.h:527
Read-only string stream.
Definition: rapidjson.h:485
size_t PutEnd(Ch *)
Definition: rapidjson.h:496
const Ch * head_
Original head of the string.
Definition: rapidjson.h:499
Ch Take()
Definition: rapidjson.h:491
Encoding::Ch Ch
Definition: rapidjson.h:486
size_t Tell() const
Definition: rapidjson.h:492
const Ch * src_
Current read position.
Definition: rapidjson.h:498
void Put(Ch)
Definition: rapidjson.h:495
Ch Peek() const
Definition: rapidjson.h:490
GenericStringStream(const Ch *src)
Definition: rapidjson.h:488
Ch * PutBegin()
Definition: rapidjson.h:494
Chunk header for perpending to each chunk.
Definition: rapidjson.h:319
size_t capacity
Capacity of the chunk in bytes (excluding the header itself).
Definition: rapidjson.h:320
ChunkHeader * next
Next chunk in the linked list.
Definition: rapidjson.h:322
size_t size
Current size of allocated memory in bytes.
Definition: rapidjson.h:321
UTF-16 encoding.
Definition: rapidjson.h:395
static Ch * Encode(Ch *buffer, unsigned codepoint)
Definition: rapidjson.h:398
CharType Ch
Definition: rapidjson.h:396
UTF-32 encoding.
Definition: rapidjson.h:422
static Ch * Encode(Ch *buffer, unsigned codepoint)
Definition: rapidjson.h:425
CharType Ch
Definition: rapidjson.h:423
UTF-8 encoding.
Definition: rapidjson.h:360
CharType Ch
Definition: rapidjson.h:361
static Ch * Encode(Ch *buffer, unsigned codepoint)
Definition: rapidjson.h:363