| 7a956470 |
sago007 |
2016-02-14 17:09 |
1 |
#ifndef RAPIDJSON_RAPIDJSON_H_
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
2 |
#define RAPIDJSON_RAPIDJSON_H_
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
3 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
4 |
// Copyright (c) 2011-2012 Milo Yip (miloyip@gmail.com)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
5 |
// Version 0.11
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
6 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
7 |
#include <cstdlib> // malloc(), realloc(), free()
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
8 |
#include <cstring> // memcpy()
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
9 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
10 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
11 |
// RAPIDJSON_NO_INT64DEFINE
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
12 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
13 |
// Here defines int64_t and uint64_t types in global namespace.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
14 |
// If user have their own definition, can define RAPIDJSON_NO_INT64DEFINE to disable this.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
15 |
#ifndef RAPIDJSON_NO_INT64DEFINE
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
16 |
#ifdef _MSC_VER
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
17 |
typedef __int64 int64_t;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
18 |
typedef unsigned __int64 uint64_t;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
19 |
#else
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
20 |
#include <inttypes.h>
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
21 |
#endif
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
22 |
#endif // RAPIDJSON_NO_INT64TYPEDEF
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
23 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
24 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
25 |
// RAPIDJSON_ENDIAN
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
26 |
#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
27 |
#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
28 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
29 |
//! Endianness of the machine.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
30 |
/*! GCC provided macro for detecting endianness of the target machine. But other
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
31 |
compilers may not have this. User can define RAPIDJSON_ENDIAN to either
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
32 |
RAPIDJSON_LITTLEENDIAN or RAPIDJSON_BIGENDIAN.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
33 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
34 |
#ifndef RAPIDJSON_ENDIAN
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
35 |
#ifdef __BYTE_ORDER__
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
36 |
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
37 |
#define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
38 |
#else
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
39 |
#define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
40 |
#endif // __BYTE_ORDER__
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
41 |
#else
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
42 |
#define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN // Assumes little endian otherwise.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
43 |
#endif
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
44 |
#endif // RAPIDJSON_ENDIAN
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
45 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
46 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
47 |
// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
48 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
49 |
// Enable SSE2 optimization.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
50 |
//#define RAPIDJSON_SSE2
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
51 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
52 |
// Enable SSE4.2 optimization.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
53 |
//#define RAPIDJSON_SSE42
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
54 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
55 |
#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
56 |
#define RAPIDJSON_SIMD
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
57 |
#endif
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
58 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
59 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
60 |
// RAPIDJSON_NO_SIZETYPEDEFINE
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
61 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
62 |
#ifndef RAPIDJSON_NO_SIZETYPEDEFINE
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
63 |
namespace rapidjson {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
64 |
//! Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
65 |
/*! User may override the SizeType by defining RAPIDJSON_NO_SIZETYPEDEFINE.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
66 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
67 |
typedef unsigned SizeType;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
68 |
} // namespace rapidjson
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
69 |
#endif
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
70 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
71 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
72 |
// RAPIDJSON_ASSERT
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
73 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
74 |
//! Assertion.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
75 |
/*! By default, rapidjson uses C assert() for assertion.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
76 |
User can override it by defining RAPIDJSON_ASSERT(x) macro.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
77 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
78 |
#ifndef RAPIDJSON_ASSERT
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
79 |
#include <cassert>
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
80 |
#define RAPIDJSON_ASSERT(x) assert(x)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
81 |
#endif // RAPIDJSON_ASSERT
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
82 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
83 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
84 |
// Helpers
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
85 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
86 |
#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
87 |
#define RAPIDJSON_MULTILINEMACRO_END \
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
88 |
} while((void)0, 0)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
89 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
90 |
namespace rapidjson {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
91 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
92 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
93 |
// Allocator
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
94 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
95 |
/*! \class rapidjson::Allocator
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
96 |
\brief Concept for allocating, resizing and freeing memory block.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
97 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
98 |
Note that Malloc() and Realloc() are non-static but Free() is static.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
99 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
100 |
So if an allocator need to support Free(), it needs to put its pointer in
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
101 |
the header of memory block.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
102 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
103 |
\code
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
104 |
concept Allocator {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
105 |
static const bool kNeedFree; //!< Whether this allocator needs to call Free().
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
106 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
107 |
// Allocate a memory block.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
108 |
// \param size of the memory block in bytes.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
109 |
// \returns pointer to the memory block.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
110 |
void* Malloc(size_t size);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
111 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
112 |
// Resize a memory block.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
113 |
// \param originalPtr The pointer to current memory block. Null_ pointer is permitted.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
114 |
// \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
115 |
// \param newSize the new size in bytes.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
116 |
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
117 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
118 |
// Free a memory block.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
119 |
// \param pointer to the memory block. Null_ pointer is permitted.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
120 |
static void Free(void *ptr);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
121 |
};
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
122 |
\endcode
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
123 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
124 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
125 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
126 |
// CrtAllocator
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
127 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
128 |
//! C-runtime library allocator.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
129 |
/*! This class is just wrapper for standard C library memory routines.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
130 |
\implements Allocator
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
131 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
132 |
class CrtAllocator {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
133 |
public:
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
134 |
static const bool kNeedFree = true;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
135 |
void* Malloc(size_t size) { return malloc(size); }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
136 |
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; return realloc(originalPtr, newSize); }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
137 |
static void Free(void *ptr) { free(ptr); }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
138 |
};
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
139 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
140 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
141 |
// MemoryPoolAllocator
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
142 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
143 |
//! Default memory allocator used by the parser and DOM.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
144 |
/*! This allocator allocate memory blocks from pre-allocated memory chunks.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
145 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
146 |
It does not free memory blocks. And Realloc() only allocate new memory.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
147 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
148 |
The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
149 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
150 |
User may also supply a buffer as the first chunk.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
151 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
152 |
If the user-buffer is full then additional chunks are allocated by BaseAllocator.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
153 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
154 |
The user-buffer is not deallocated by this allocator.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
155 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
156 |
\tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
157 |
\implements Allocator
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
158 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
159 |
template <typename BaseAllocator = CrtAllocator>
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
160 |
class MemoryPoolAllocator {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
161 |
public:
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
162 |
static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
163 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
164 |
//! Constructor with chunkSize.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
165 |
/*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
166 |
\param baseAllocator The allocator for allocating memory chunks.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
167 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
168 |
MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
169 |
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
170 |
{
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
171 |
if (!baseAllocator_)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
172 |
ownBaseAllocator_ = baseAllocator_ = new BaseAllocator();
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
173 |
AddChunk(chunk_capacity_);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
174 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
175 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
176 |
//! Constructor with user-supplied buffer.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
177 |
/*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
178 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
179 |
The user buffer will not be deallocated when this allocator is destructed.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
180 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
181 |
\param buffer User supplied buffer.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
182 |
\param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader).
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
183 |
\param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
184 |
\param baseAllocator The allocator for allocating memory chunks.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
185 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
186 |
MemoryPoolAllocator(char *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
187 |
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
188 |
{
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
189 |
RAPIDJSON_ASSERT(buffer != 0);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
190 |
RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
191 |
chunkHead_ = (ChunkHeader*)buffer;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
192 |
chunkHead_->capacity = size - sizeof(ChunkHeader);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
193 |
chunkHead_->size = 0;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
194 |
chunkHead_->next = 0;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
195 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
196 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
197 |
//! Destructor.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
198 |
/*! This deallocates all memory chunks, excluding the user-supplied buffer.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
199 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
200 |
~MemoryPoolAllocator() {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
201 |
Clear();
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
202 |
delete ownBaseAllocator_;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
203 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
204 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
205 |
//! Deallocates all memory chunks, excluding the user-supplied buffer.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
206 |
void Clear() {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
207 |
while(chunkHead_ != 0 && chunkHead_ != (ChunkHeader *)userBuffer_) {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
208 |
ChunkHeader* next = chunkHead_->next;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
209 |
baseAllocator_->Free(chunkHead_);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
210 |
chunkHead_ = next;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
211 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
212 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
213 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
214 |
//! Computes the total capacity of allocated memory chunks.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
215 |
/*! \return total capacity in bytes.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
216 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
217 |
size_t Capacity() {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
218 |
size_t capacity = 0;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
219 |
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
220 |
capacity += c->capacity;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
221 |
return capacity;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
222 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
223 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
224 |
//! Computes the memory blocks allocated.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
225 |
/*! \return total used bytes.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
226 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
227 |
size_t Size() {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
228 |
size_t size = 0;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
229 |
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
230 |
size += c->size;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
231 |
return size;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
232 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
233 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
234 |
//! Allocates a memory block. (concept Allocator)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
235 |
void* Malloc(size_t size) {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
236 |
size = (size + 3) & ~3; // Force aligning size to 4
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
237 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
238 |
if (chunkHead_->size + size > chunkHead_->capacity)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
239 |
AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
240 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
241 |
char *buffer = (char *)(chunkHead_ + 1) + chunkHead_->size;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
242 |
RAPIDJSON_ASSERT(((uintptr_t)buffer & 3) == 0); // returned buffer is aligned to 4
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
243 |
chunkHead_->size += size;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
244 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
245 |
return buffer;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
246 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
247 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
248 |
//! Resizes a memory block (concept Allocator)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
249 |
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
250 |
if (originalPtr == 0)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
251 |
return Malloc(newSize);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
252 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
253 |
// Do not shrink if new size is smaller than original
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
254 |
if (originalSize >= newSize)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
255 |
return originalPtr;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
256 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
257 |
// Simply expand it if it is the last allocation and there is sufficient space
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
258 |
if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
259 |
size_t increment = newSize - originalSize;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
260 |
increment = (increment + 3) & ~3; // Force aligning size to 4
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
261 |
if (chunkHead_->size + increment <= chunkHead_->capacity) {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
262 |
chunkHead_->size += increment;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
263 |
RAPIDJSON_ASSERT(((uintptr_t)originalPtr & 3) == 0); // returned buffer is aligned to 4
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
264 |
return originalPtr;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
265 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
266 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
267 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
268 |
// Realloc process: allocate and copy memory, do not free original buffer.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
269 |
void* newBuffer = Malloc(newSize);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
270 |
RAPIDJSON_ASSERT(newBuffer != 0); // Do not handle out-of-memory explicitly.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
271 |
return memcpy(newBuffer, originalPtr, originalSize);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
272 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
273 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
274 |
//! Frees a memory block (concept Allocator)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
275 |
static void Free(void *) {} // Do nothing
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
276 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
277 |
private:
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
278 |
//! Creates a new chunk.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
279 |
/*! \param capacity Capacity of the chunk in bytes.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
280 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
281 |
void AddChunk(size_t capacity) {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
282 |
ChunkHeader* chunk = (ChunkHeader*)baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
283 |
chunk->capacity = capacity;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
284 |
chunk->size = 0;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
285 |
chunk->next = chunkHead_;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
286 |
chunkHead_ = chunk;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
287 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
288 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
289 |
static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
290 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
291 |
//! Chunk header for perpending to each chunk.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
292 |
/*! Chunks are stored as a singly linked list.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
293 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
294 |
struct ChunkHeader {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
295 |
size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself).
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
296 |
size_t size; //!< Current size of allocated memory in bytes.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
297 |
ChunkHeader *next; //!< Next chunk in the linked list.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
298 |
};
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
299 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
300 |
ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
301 |
size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
302 |
char *userBuffer_; //!< User supplied buffer.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
303 |
BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
304 |
BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
305 |
};
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
306 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
307 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
308 |
// Encoding
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
309 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
310 |
/*! \class rapidjson::Encoding
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
311 |
\brief Concept for encoding of Unicode characters.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
312 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
313 |
\code
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
314 |
concept Encoding {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
315 |
typename Ch; //! Type of character.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
316 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
317 |
//! \brief Encode a Unicode codepoint to a buffer.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
318 |
//! \param buffer pointer to destination buffer to store the result. It should have sufficient size of encoding one character.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
319 |
//! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
320 |
//! \returns the pointer to the next character after the encoded data.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
321 |
static Ch* Encode(Ch *buffer, unsigned codepoint);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
322 |
};
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
323 |
\endcode
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
324 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
325 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
326 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
327 |
// UTF8
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
328 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
329 |
//! UTF-8 encoding.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
330 |
/*! http://en.wikipedia.org/wiki/UTF-8
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
331 |
\tparam CharType Type for storing 8-bit UTF-8 data. Default is char.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
332 |
\implements Encoding
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
333 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
334 |
template<typename CharType = char>
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
335 |
struct UTF8 {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
336 |
typedef CharType Ch;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
337 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
338 |
static Ch* Encode(Ch *buffer, unsigned codepoint) {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
339 |
if (codepoint <= 0x7F)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
340 |
*buffer++ = codepoint & 0xFF;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
341 |
else if (codepoint <= 0x7FF) {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
342 |
*buffer++ = 0xC0 | ((codepoint >> 6) & 0xFF);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
343 |
*buffer++ = 0x80 | ((codepoint & 0x3F));
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
344 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
345 |
else if (codepoint <= 0xFFFF) {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
346 |
*buffer++ = 0xE0 | ((codepoint >> 12) & 0xFF);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
347 |
*buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
348 |
*buffer++ = 0x80 | (codepoint & 0x3F);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
349 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
350 |
else {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
351 |
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
352 |
*buffer++ = 0xF0 | ((codepoint >> 18) & 0xFF);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
353 |
*buffer++ = 0x80 | ((codepoint >> 12) & 0x3F);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
354 |
*buffer++ = 0x80 | ((codepoint >> 6) & 0x3F);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
355 |
*buffer++ = 0x80 | (codepoint & 0x3F);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
356 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
357 |
return buffer;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
358 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
359 |
};
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
360 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
361 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
362 |
// UTF16
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
363 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
364 |
//! UTF-16 encoding.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
365 |
/*! http://en.wikipedia.org/wiki/UTF-16
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
366 |
\tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
367 |
\implements Encoding
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
368 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
369 |
template<typename CharType = wchar_t>
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
370 |
struct UTF16 {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
371 |
typedef CharType Ch;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
372 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
373 |
static Ch* Encode(Ch* buffer, unsigned codepoint) {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
374 |
if (codepoint <= 0xFFFF) {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
375 |
RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
376 |
*buffer++ = static_cast<Ch>(codepoint);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
377 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
378 |
else {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
379 |
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
380 |
unsigned v = codepoint - 0x10000;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
381 |
*buffer++ = static_cast<Ch>((v >> 10) + 0xD800);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
382 |
*buffer++ = (v & 0x3FF) + 0xDC00;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
383 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
384 |
return buffer;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
385 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
386 |
};
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
387 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
388 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
389 |
// UTF32
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
390 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
391 |
//! UTF-32 encoding.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
392 |
/*! http://en.wikipedia.org/wiki/UTF-32
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
393 |
\tparam Ch Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
394 |
\implements Encoding
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
395 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
396 |
template<typename CharType = unsigned>
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
397 |
struct UTF32 {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
398 |
typedef CharType Ch;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
399 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
400 |
static Ch *Encode(Ch* buffer, unsigned codepoint) {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
401 |
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
402 |
*buffer++ = codepoint;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
403 |
return buffer;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
404 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
405 |
};
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
406 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
407 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
408 |
// Stream
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
409 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
410 |
/*! \class rapidjson::Stream
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
411 |
\brief Concept for reading and writing characters.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
412 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
413 |
For read-only stream, no need to implement PutBegin(), Put() and PutEnd().
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
414 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
415 |
For write-only stream, only need to implement Put().
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
416 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
417 |
\code
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
418 |
concept Stream {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
419 |
typename Ch; //!< Character type of the stream.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
420 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
421 |
//! Read the current character from stream without moving the read cursor.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
422 |
Ch Peek() const;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
423 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
424 |
//! Read the current character from stream and moving the read cursor to next character.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
425 |
Ch Take();
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
426 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
427 |
//! Get the current read cursor.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
428 |
//! \return Number of characters read from start.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
429 |
size_t Tell();
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
430 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
431 |
//! Begin writing operation at the current read pointer.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
432 |
//! \return The begin writer pointer.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
433 |
Ch* PutBegin();
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
434 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
435 |
//! Write a character.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
436 |
void Put(Ch c);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
437 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
438 |
//! End the writing operation.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
439 |
//! \param begin The begin write pointer returned by PutBegin().
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
440 |
//! \return Number of characters written.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
441 |
size_t PutEnd(Ch* begin);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
442 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
443 |
\endcode
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
444 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
445 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
446 |
//! Put N copies of a character to a stream.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
447 |
template<typename Stream, typename Ch>
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
448 |
inline void PutN(Stream& stream, Ch c, size_t n) {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
449 |
for (size_t i = 0; i < n; i++)
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
450 |
stream.Put(c);
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
451 |
}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
452 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
453 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
454 |
// StringStream
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
455 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
456 |
//! Read-only string stream.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
457 |
/*! \implements Stream
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
458 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
459 |
template <typename Encoding>
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
460 |
struct GenericStringStream {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
461 |
typedef typename Encoding::Ch Ch;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
462 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
463 |
GenericStringStream(const Ch *src) : src_(src), head_(src) {}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
464 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
465 |
Ch Peek() const { return *src_; }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
466 |
Ch Take() { return *src_++; }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
467 |
size_t Tell() const { return src_ - head_; }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
468 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
469 |
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
470 |
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
471 |
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
472 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
473 |
const Ch* src_; //!< Current read position.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
474 |
const Ch* head_; //!< Original head of the string.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
475 |
};
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
476 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
477 |
typedef GenericStringStream<UTF8<> > StringStream;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
478 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
479 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
480 |
// InsituStringStream
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
481 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
482 |
//! A read-write string stream.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
483 |
/*! This string stream is particularly designed for in-situ parsing.
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
484 |
\implements Stream
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
485 |
*/
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
486 |
template <typename Encoding>
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
487 |
struct GenericInsituStringStream {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
488 |
typedef typename Encoding::Ch Ch;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
489 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
490 |
GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
491 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
492 |
// Read
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
493 |
Ch Peek() { return *src_; }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
494 |
Ch Take() { return *src_++; }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
495 |
size_t Tell() { return src_ - head_; }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
496 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
497 |
// Write
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
498 |
Ch* PutBegin() { return dst_ = src_; }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
499 |
void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
500 |
size_t PutEnd(Ch* begin) { return dst_ - begin; }
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
501 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
502 |
Ch* src_;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
503 |
Ch* dst_;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
504 |
Ch* head_;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
505 |
};
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
506 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
507 |
typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
508 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
509 |
///////////////////////////////////////////////////////////////////////////////
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
510 |
// Type
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
511 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
512 |
//! Type of JSON value
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
513 |
enum Type {
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
514 |
kNull_Type = 0, //!< null
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
515 |
kFalseType = 1, //!< false
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
516 |
kTrueType = 2, //!< true
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
517 |
kObjectType = 3, //!< object
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
518 |
kArrayType = 4, //!< array
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
519 |
kStringType = 5, //!< string
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
520 |
kNumberType = 6, //!< number
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
521 |
};
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
522 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
523 |
} // namespace rapidjson
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
524 |
|
| 7a956470 |
sago007 |
2016-02-14 17:09 |
525 |
#endif // RAPIDJSON_RAPIDJSON_H_
|
|
|
1970-01-01 00:00 |
526 |
|