rapidjson.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #ifndef RAPIDJSON_RAPIDJSON_H_
  2. #define RAPIDJSON_RAPIDJSON_H_
  3. // Copyright (c) 2011 Milo Yip ([email protected])
  4. // Version 0.1
  5. #include <cstdlib> // malloc(), realloc(), free()
  6. #include <cstring> // memcpy()
  7. ///////////////////////////////////////////////////////////////////////////////
  8. // RAPIDJSON_NO_INT64DEFINE
  9. // Here defines int64_t and uint64_t types in global namespace.
  10. // If user have their own definition, can define RAPIDJSON_NO_INT64DEFINE to disable this.
  11. #ifndef RAPIDJSON_NO_INT64DEFINE
  12. #ifdef _MSC_VER
  13. typedef __int64 int64_t;
  14. typedef unsigned __int64 uint64_t;
  15. #define RAPIDJSON_FORCEINLINE __forceinline
  16. #else
  17. #include <inttypes.h>
  18. #define RAPIDJSON_FORCEINLINE
  19. #endif
  20. #endif // RAPIDJSON_NO_INT64TYPEDEF
  21. ///////////////////////////////////////////////////////////////////////////////
  22. // RAPIDJSON_ENDIAN
  23. #define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine
  24. #define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine
  25. //! Endianness of the machine.
  26. /*! GCC provided macro for detecting endianness of the target machine. But other
  27. compilers may not have this. User can define RAPIDJSON_ENDIAN to either
  28. RAPIDJSON_LITTLEENDIAN or RAPIDJSON_BIGENDIAN.
  29. */
  30. #ifndef RAPIDJSON_ENDIAN
  31. #ifdef __BYTE_ORDER__
  32. #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  33. #define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
  34. #else
  35. #define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
  36. #endif // __BYTE_ORDER__
  37. #else
  38. #define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN // Assumes little endian otherwise.
  39. #endif
  40. #endif // RAPIDJSON_ENDIAN
  41. ///////////////////////////////////////////////////////////////////////////////
  42. // RAPIDJSON_ALIGNSIZE
  43. //! Data alignment of the machine.
  44. /*!
  45. Some machine requires strict data alignment.
  46. Currently the default uses 4 bytes alignment. User can customize this.
  47. */
  48. #ifndef RAPIDJSON_ALIGN
  49. #define RAPIDJSON_ALIGN(x) ((x + 3) & ~3)
  50. #endif
  51. ///////////////////////////////////////////////////////////////////////////////
  52. // RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD
  53. // Enable SSE2 optimization.
  54. //#define RAPIDJSON_SSE2
  55. // Enable SSE4.2 optimization.
  56. //#define RAPIDJSON_SSE42
  57. #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
  58. #define RAPIDJSON_SIMD
  59. #endif
  60. ///////////////////////////////////////////////////////////////////////////////
  61. // RAPIDJSON_NO_SIZETYPEDEFINE
  62. #ifndef RAPIDJSON_NO_SIZETYPEDEFINE
  63. namespace rapidjson {
  64. //! Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
  65. /*! User may override the SizeType by defining RAPIDJSON_NO_SIZETYPEDEFINE.
  66. */
  67. typedef unsigned SizeType;
  68. } // namespace rapidjson
  69. #endif
  70. ///////////////////////////////////////////////////////////////////////////////
  71. // RAPIDJSON_ASSERT
  72. //! Assertion.
  73. /*! By default, rapidjson uses C assert() for assertion.
  74. User can override it by defining RAPIDJSON_ASSERT(x) macro.
  75. */
  76. #ifndef RAPIDJSON_ASSERT
  77. #include <cassert>
  78. #define RAPIDJSON_ASSERT(x) assert(x)
  79. #endif // RAPIDJSON_ASSERT
  80. ///////////////////////////////////////////////////////////////////////////////
  81. // RAPIDJSON_STATIC_ASSERT
  82. // Adopt from boost
  83. #ifndef RAPIDJSON_STATIC_ASSERT
  84. namespace rapidjson {
  85. template <bool x> struct STATIC_ASSERTION_FAILURE;
  86. template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
  87. template<int x> struct StaticAssertTest {};
  88. } // namespace rapidjson
  89. #define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y)
  90. #define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y)
  91. #define RAPIDJSON_DO_JOIN2(X, Y) X##Y
  92. #define RAPIDJSON_STATIC_ASSERT(x) typedef ::rapidjson::StaticAssertTest<\
  93. sizeof(::rapidjson::STATIC_ASSERTION_FAILURE<bool(x) >)>\
  94. RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__)
  95. #endif
  96. ///////////////////////////////////////////////////////////////////////////////
  97. // Helpers
  98. #define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  99. #define RAPIDJSON_MULTILINEMACRO_END \
  100. } while((void)0, 0)
  101. ///////////////////////////////////////////////////////////////////////////////
  102. // Allocators and Encodings
  103. #include "allocators.h"
  104. #include "encodings.h"
  105. namespace rapidjson {
  106. ///////////////////////////////////////////////////////////////////////////////
  107. // Stream
  108. /*! \class rapidjson::Stream
  109. \brief Concept for reading and writing characters.
  110. For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().
  111. For write-only stream, only need to implement Put() and Flush().
  112. \code
  113. concept Stream {
  114. typename Ch; //!< Character type of the stream.
  115. //! Read the current character from stream without moving the read cursor.
  116. Ch Peek() const;
  117. //! Read the current character from stream and moving the read cursor to next character.
  118. Ch Take();
  119. //! Get the current read cursor.
  120. //! \return Number of characters read from start.
  121. size_t Tell();
  122. //! Begin writing operation at the current read pointer.
  123. //! \return The begin writer pointer.
  124. Ch* PutBegin();
  125. //! Write a character.
  126. void Put(Ch c);
  127. //! Flush the buffer.
  128. void Flush();
  129. //! End the writing operation.
  130. //! \param begin The begin write pointer returned by PutBegin().
  131. //! \return Number of characters written.
  132. size_t PutEnd(Ch* begin);
  133. }
  134. \endcode
  135. */
  136. //! Put N copies of a character to a stream.
  137. template<typename Stream, typename Ch>
  138. inline void PutN(Stream& stream, Ch c, size_t n) {
  139. for (size_t i = 0; i < n; i++)
  140. stream.Put(c);
  141. }
  142. ///////////////////////////////////////////////////////////////////////////////
  143. // StringStream
  144. //! Read-only string stream.
  145. /*! \implements Stream
  146. */
  147. template <typename Encoding>
  148. struct GenericStringStream {
  149. typedef typename Encoding::Ch Ch;
  150. GenericStringStream(const Ch *src) : src_(src), head_(src) {}
  151. Ch Peek() const { return *src_; }
  152. Ch Take() { return *src_++; }
  153. size_t Tell() const { return src_ - head_; }
  154. Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
  155. void Put(Ch) { RAPIDJSON_ASSERT(false); }
  156. void Flush() { RAPIDJSON_ASSERT(false); }
  157. size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
  158. const Ch* src_; //!< Current read position.
  159. const Ch* head_; //!< Original head of the string.
  160. };
  161. typedef GenericStringStream<UTF8<> > StringStream;
  162. ///////////////////////////////////////////////////////////////////////////////
  163. // InsituStringStream
  164. //! A read-write string stream.
  165. /*! This string stream is particularly designed for in-situ parsing.
  166. \implements Stream
  167. */
  168. template <typename Encoding>
  169. struct GenericInsituStringStream {
  170. typedef typename Encoding::Ch Ch;
  171. GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
  172. // Read
  173. Ch Peek() { return *src_; }
  174. Ch Take() { return *src_++; }
  175. size_t Tell() { return src_ - head_; }
  176. // Write
  177. Ch* PutBegin() { return dst_ = src_; }
  178. void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
  179. void Flush() {}
  180. size_t PutEnd(Ch* begin) { return dst_ - begin; }
  181. Ch* src_;
  182. Ch* dst_;
  183. Ch* head_;
  184. };
  185. typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
  186. ///////////////////////////////////////////////////////////////////////////////
  187. // Type
  188. //! Type of JSON value
  189. enum Type {
  190. kNullType = 0, //!< null
  191. kFalseType = 1, //!< false
  192. kTrueType = 2, //!< true
  193. kObjectType = 3, //!< object
  194. kArrayType = 4, //!< array
  195. kStringType = 5, //!< string
  196. kNumberType = 6, //!< number
  197. };
  198. } // namespace rapidjson
  199. #endif // RAPIDJSON_RAPIDJSON_H_