All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
rapidjson.h
Go to the documentation of this file.
1 // Copyright (C) 2011 Milo Yip
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE.
20 
21 #ifndef RAPIDJSON_RAPIDJSON_H_
22 #define RAPIDJSON_RAPIDJSON_H_
23 
24 // Copyright (c) 2011 Milo Yip (miloyip@gmail.com)
25 // Version 0.1
26 
27 /*!\file rapidjson.h
28  \brief common definitions and configuration
29 
30  \todo Complete Doxygen documentation for configure macros.
31  */
32 
33 #include <cstdlib> // malloc(), realloc(), free()
34 #include <cstring> // memcpy()
35 
36 ///////////////////////////////////////////////////////////////////////////////
37 // RAPIDJSON_NO_INT64DEFINE
38 
39 // Here defines int64_t and uint64_t types in global namespace
40 // If user have their own definition, can define RAPIDJSON_NO_INT64DEFINE to disable this.
41 #ifndef RAPIDJSON_NO_INT64DEFINE
42 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
43 #ifdef _MSC_VER
44 #include "msinttypes/stdint.h"
45 #include "msinttypes/inttypes.h"
46 #else
47 // Other compilers should have this.
48 #include <stdint.h>
49 #include <inttypes.h>
50 #endif
51 //!@endcond
52 #endif // RAPIDJSON_NO_INT64TYPEDEF
53 
54 ///////////////////////////////////////////////////////////////////////////////
55 // RAPIDJSON_FORCEINLINE
56 
57 #ifndef RAPIDJSON_FORCEINLINE
58 #ifdef _MSC_VER
59 #define RAPIDJSON_FORCEINLINE __forceinline
60 #elif defined(__GNUC__) && __GNUC__ >= 4
61 #define RAPIDJSON_FORCEINLINE __attribute__((always_inline))
62 #else
63 #define RAPIDJSON_FORCEINLINE
64 #endif
65 #endif // RAPIDJSON_FORCEINLINE
66 
67 ///////////////////////////////////////////////////////////////////////////////
68 // RAPIDJSON_ENDIAN
69 #define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine
70 #define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine
71 
72 //! Endianness of the machine.
73 /*! GCC 4.6 provided macro for detecting endianness of the target machine. But other
74  compilers may not have this. User can define RAPIDJSON_ENDIAN to either
75  \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN.
76 
77  Implemented with reference to
78  https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html
79  http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp
80 */
81 #ifndef RAPIDJSON_ENDIAN
82 // Detect with GCC 4.6's macro
83 # ifdef __BYTE_ORDER__
84 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
85 # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
86 # elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
87 # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
88 # else
89 # error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
90 # endif // __BYTE_ORDER__
91 // Detect with GLIBC's endian.h
92 # elif defined(__GLIBC__)
93 # include <endian.h>
94 # if (__BYTE_ORDER == __LITTLE_ENDIAN)
95 # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
96 # elif (__BYTE_ORDER == __BIG_ENDIAN)
97 # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
98 # else
99 # error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
100 # endif // __GLIBC__
101 // Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro
102 # elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
103 # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
104 # elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
105 # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
106 // Detect with architecture macros
107 # elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
108 # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
109 # elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
110 # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
111 # else
112 # error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
113 # endif
114 #endif // RAPIDJSON_ENDIAN
115 
116 ///////////////////////////////////////////////////////////////////////////////
117 // RAPIDJSON_ALIGNSIZE
118 
119 //! Data alignment of the machine.
120 /*!
121  Some machine requires strict data alignment.
122  Currently the default uses 4 bytes alignment. User can customize this.
123 */
124 #ifndef RAPIDJSON_ALIGN
125 #define RAPIDJSON_ALIGN(x) ((x + 3u) & ~3u)
126 #endif
127 
128 ///////////////////////////////////////////////////////////////////////////////
129 // RAPIDJSON_UINT64_C2
130 
131 //! Construct a 64-bit literal by a pair of 32-bit integer.
132 /*!
133  64-bit literal with or without ULL suffix is prone to compiler warnings.
134  UINT64_C() is C macro which cause compilation problems.
135  Use this macro to define 64-bit constants by a pair of 32-bit integer.
136 */
137 #ifndef RAPIDJSON_UINT64_C2
138 #define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
139 #endif
140 
141 ///////////////////////////////////////////////////////////////////////////////
142 // RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD
143 
144 // Enable SSE2 optimization.
145 //#define RAPIDJSON_SSE2
146 
147 // Enable SSE4.2 optimization.
148 //#define RAPIDJSON_SSE42
149 
150 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
151 #define RAPIDJSON_SIMD
152 #endif
153 
154 ///////////////////////////////////////////////////////////////////////////////
155 // RAPIDJSON_NO_SIZETYPEDEFINE
156 
157 #ifndef RAPIDJSON_NO_SIZETYPEDEFINE
158 namespace rapidjson {
159 //! Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
160 /*! User may override the SizeType by defining RAPIDJSON_NO_SIZETYPEDEFINE.
161 */
162 typedef unsigned SizeType;
163 } // namespace rapidjson
164 #endif
165 
166 ///////////////////////////////////////////////////////////////////////////////
167 // RAPIDJSON_ASSERT
168 
169 //! Assertion.
170 /*! By default, rapidjson uses C assert() for assertion.
171  User can override it by defining RAPIDJSON_ASSERT(x) macro.
172 */
173 #ifndef RAPIDJSON_ASSERT
174 #include <cassert>
175 #define RAPIDJSON_ASSERT(x) assert(x)
176 #endif // RAPIDJSON_ASSERT
177 
178 ///////////////////////////////////////////////////////////////////////////////
179 // RAPIDJSON_STATIC_ASSERT
180 
181 // Adopt from boost
182 #ifndef RAPIDJSON_STATIC_ASSERT
183 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
184 namespace rapidjson {
185 
186 template <bool x> struct STATIC_ASSERTION_FAILURE;
187 template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
188 template<int x> struct StaticAssertTest {};
189 } // namespace rapidjson
190 
191 #define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y)
192 #define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y)
193 #define RAPIDJSON_DO_JOIN2(X, Y) X##Y
194 
195 #if defined(__GNUC__)
196 #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
197 #else
198 #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
199 #endif
200 //!@endcond
201 
202 /*! \def RAPIDJSON_STATIC_ASSERT
203  \brief (internal) macro to check for conditions at compile-time
204  \param x compile-time condition
205  \hideinitializer
206  */
207 #define RAPIDJSON_STATIC_ASSERT(x) typedef ::rapidjson::StaticAssertTest<\
208  sizeof(::rapidjson::STATIC_ASSERTION_FAILURE<bool(x) >)>\
209  RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
210 #endif
211 
212 ///////////////////////////////////////////////////////////////////////////////
213 // Helpers
214 
215 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
216 
217 #define RAPIDJSON_MULTILINEMACRO_BEGIN do {
218 #define RAPIDJSON_MULTILINEMACRO_END \
219 } while((void)0, 0)
220 
221 // adopted from Boost
222 #define RAPIDJSON_VERSION_CODE(x,y,z) \
223  (((x)*100000) + ((y)*100) + (z))
224 
225 // token stringification
226 #define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x)
227 #define RAPIDJSON_DO_STRINGIFY(x) #x
228 
229 ///////////////////////////////////////////////////////////////////////////////
230 // RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
231 
232 #if defined(__clang__) || (defined(__GNUC__) && RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) >= RAPIDJSON_VERSION_CODE(4,2,0))
233 
234 #define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x))
235 #define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x)
236 #define RAPIDJSON_DIAG_OFF(x) \
237  RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x)))
238 
239 // push/pop support in Clang and GCC>=4.6
240 #if defined(__clang__) || (defined(__GNUC__) && RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) >= RAPIDJSON_VERSION_CODE(4,6,0))
241 #define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
242 #define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop)
243 #else // GCC >= 4.2, < 4.6
244 #define RAPIDJSON_DIAG_PUSH /* ignored */
245 #define RAPIDJSON_DIAG_POP /* ignored */
246 #endif
247 
248 #elif defined(_MSC_VER)
249 
250 // pragma (MSVC specific)
251 #define RAPIDJSON_PRAGMA(x) __pragma(x)
252 #define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x))
253 
254 #define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x)
255 #define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
256 #define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop)
257 
258 #else
259 
260 #define RAPIDJSON_DIAG_OFF(x) /* ignored */
261 #define RAPIDJSON_DIAG_PUSH /* ignored */
262 #define RAPIDJSON_DIAG_POP /* ignored */
263 
264 #endif // RAPIDJSON_DIAG_*
265 
266 //!@endcond
267 
268 ///////////////////////////////////////////////////////////////////////////////
269 // Allocators and Encodings
270 
271 #include "allocators.h"
272 #include "encodings.h"
273 
274 //! main RapidJSON namespace
275 namespace rapidjson {
276 
277 ///////////////////////////////////////////////////////////////////////////////
278 // Stream
279 
280 /*! \class rapidjson::Stream
281  \brief Concept for reading and writing characters.
282 
283  For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().
284 
285  For write-only stream, only need to implement Put() and Flush().
286 
287 \code
288 concept Stream {
289  typename Ch; //!< Character type of the stream.
290 
291  //! Read the current character from stream without moving the read cursor.
292  Ch Peek() const;
293 
294  //! Read the current character from stream and moving the read cursor to next character.
295  Ch Take();
296 
297  //! Get the current read cursor.
298  //! \return Number of characters read from start.
299  size_t Tell();
300 
301  //! Begin writing operation at the current read pointer.
302  //! \return The begin writer pointer.
303  Ch* PutBegin();
304 
305  //! Write a character.
306  void Put(Ch c);
307 
308  //! Flush the buffer.
309  void Flush();
310 
311  //! End the writing operation.
312  //! \param begin The begin write pointer returned by PutBegin().
313  //! \return Number of characters written.
314  size_t PutEnd(Ch* begin);
315 }
316 \endcode
317 */
318 
319 //! Provides additional information for stream.
320 /*!
321  By using traits pattern, this type provides a default configuration for stream.
322  For custom stream, this type can be specialized for other configuration.
323  See TEST(Reader, CustomStringStream) in readertest.cpp for example.
324 */
325 template<typename Stream>
326 struct StreamTraits {
327  //! Whether to make local copy of stream for optimization during parsing.
328  /*!
329  By default, for safety, streams do not use local copy optimization.
330  Stream that can be copied fast should specialize this, like StreamTraits<StringStream>.
331  */
332  enum { copyOptimization = 0 };
333 };
334 
335 //! Put N copies of a character to a stream.
336 template<typename Stream, typename Ch>
337 inline void PutN(Stream& stream, Ch c, size_t n) {
338  for (size_t i = 0; i < n; i++)
339  stream.Put(c);
340 }
341 
342 ///////////////////////////////////////////////////////////////////////////////
343 // StringStream
344 
345 //! Read-only string stream.
346 /*! \note implements Stream concept
347 */
348 template <typename Encoding>
350  typedef typename Encoding::Ch Ch;
351 
352  GenericStringStream(const Ch *src) : src_(src), head_(src) {}
353 
354  Ch Peek() const { return *src_; }
355  Ch Take() { return *src_++; }
356  size_t Tell() const { return static_cast<size_t>(src_ - head_); }
357 
358  Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
359  void Put(Ch) { RAPIDJSON_ASSERT(false); }
360  void Flush() { RAPIDJSON_ASSERT(false); }
361  size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
362 
363  const Ch* src_; //!< Current read position.
364  const Ch* head_; //!< Original head of the string.
365 };
366 
367 template <typename Encoding>
369  enum { copyOptimization = 1 };
370 };
371 
372 //! String stream with UTF8 encoding.
374 
375 ///////////////////////////////////////////////////////////////////////////////
376 // InsituStringStream
377 
378 //! A read-write string stream.
379 /*! This string stream is particularly designed for in-situ parsing.
380  \note implements Stream concept
381 */
382 template <typename Encoding>
384  typedef typename Encoding::Ch Ch;
385 
386  GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
387 
388  // Read
389  Ch Peek() { return *src_; }
390  Ch Take() { return *src_++; }
391  size_t Tell() { return static_cast<size_t>(src_ - head_); }
392 
393  // Write
394  void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
395 
396  Ch* PutBegin() { return dst_ = src_; }
397  size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }
398  void Flush() {}
399 
400  Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; }
401  void Pop(size_t count) { dst_ -= count; }
402 
403  Ch* src_;
404  Ch* dst_;
405  Ch* head_;
406 };
407 
408 template <typename Encoding>
410  enum { copyOptimization = 1 };
411 };
412 
413 //! Insitu string stream with UTF8 encoding.
415 
416 ///////////////////////////////////////////////////////////////////////////////
417 // Type
418 
419 //! Type of JSON value
420 enum Type {
421  kNullType = 0, //!< null
422  kFalseType = 1, //!< false
423  kTrueType = 2, //!< true
424  kObjectType = 3, //!< object
425  kArrayType = 4, //!< array
426  kStringType = 5, //!< string
427  kNumberType = 6 //!< number
428 };
429 
430 } // namespace rapidjson
431 
432 #endif // RAPIDJSON_RAPIDJSON_H_
true
Definition: rapidjson.h:423
Read-only string stream.
Definition: rapidjson.h:349
unsigned SizeType
Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
Definition: rapidjson.h:162
false
Definition: rapidjson.h:422
const Ch * head_
Original head of the string.
Definition: rapidjson.h:364
const Ch * src_
Current read position.
Definition: rapidjson.h:363
GenericInsituStringStream< UTF8<> > InsituStringStream
Insitu string stream with UTF8 encoding.
Definition: rapidjson.h:414
Concept for encoding of Unicode characters.
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:175
Type
Type of JSON value.
Definition: rapidjson.h:420
object
Definition: rapidjson.h:424
GenericStringStream< UTF8<> > StringStream
String stream with UTF8 encoding.
Definition: rapidjson.h:373
array
Definition: rapidjson.h:425
void PutN(FileWriteStream &stream, char c, size_t n)
Implement specialized version of PutN() with memset() for better performance.
Definition: filewritestream.h:91
null
Definition: rapidjson.h:421
Concept for reading and writing characters.
string
Definition: rapidjson.h:426
number
Definition: rapidjson.h:427
Provides additional information for stream.
Definition: rapidjson.h:326
A read-write string stream.
Definition: rapidjson.h:383