123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- #ifndef RAPIDJSON_RAPIDJSON_H_
- #define RAPIDJSON_RAPIDJSON_H_
- // Copyright (c) 2011 Milo Yip ([email protected])
- // Version 0.1
- #include <cstdlib> // malloc(), realloc(), free()
- #include <cstring> // memcpy()
- ///////////////////////////////////////////////////////////////////////////////
- // RAPIDJSON_NO_INT64DEFINE
- // Here defines int64_t and uint64_t types in global namespace.
- // If user have their own definition, can define RAPIDJSON_NO_INT64DEFINE to disable this.
- #ifndef RAPIDJSON_NO_INT64DEFINE
- #ifdef _MSC_VER
- typedef __int64 int64_t;
- typedef unsigned __int64 uint64_t;
- #define RAPIDJSON_FORCEINLINE __forceinline
- #else
- #include <inttypes.h>
- #define RAPIDJSON_FORCEINLINE
- #endif
- #endif // RAPIDJSON_NO_INT64TYPEDEF
- ///////////////////////////////////////////////////////////////////////////////
- // RAPIDJSON_ENDIAN
- #define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine
- #define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine
- //! Endianness of the machine.
- /*! GCC provided macro for detecting endianness of the target machine. But other
- compilers may not have this. User can define RAPIDJSON_ENDIAN to either
- RAPIDJSON_LITTLEENDIAN or RAPIDJSON_BIGENDIAN.
- */
- #ifndef RAPIDJSON_ENDIAN
- #ifdef __BYTE_ORDER__
- #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- #define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
- #else
- #define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
- #endif // __BYTE_ORDER__
- #else
- #define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN // Assumes little endian otherwise.
- #endif
- #endif // RAPIDJSON_ENDIAN
- ///////////////////////////////////////////////////////////////////////////////
- // RAPIDJSON_ALIGNSIZE
- //! Data alignment of the machine.
- /*!
- Some machine requires strict data alignment.
- Currently the default uses 4 bytes alignment. User can customize this.
- */
- #ifndef RAPIDJSON_ALIGN
- #define RAPIDJSON_ALIGN(x) ((x + 3) & ~3)
- #endif
- ///////////////////////////////////////////////////////////////////////////////
- // RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD
- // Enable SSE2 optimization.
- //#define RAPIDJSON_SSE2
- // Enable SSE4.2 optimization.
- //#define RAPIDJSON_SSE42
- #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
- #define RAPIDJSON_SIMD
- #endif
- ///////////////////////////////////////////////////////////////////////////////
- // RAPIDJSON_NO_SIZETYPEDEFINE
- #ifndef RAPIDJSON_NO_SIZETYPEDEFINE
- namespace rapidjson {
- //! Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
- /*! User may override the SizeType by defining RAPIDJSON_NO_SIZETYPEDEFINE.
- */
- typedef unsigned SizeType;
- } // namespace rapidjson
- #endif
- ///////////////////////////////////////////////////////////////////////////////
- // RAPIDJSON_ASSERT
- //! Assertion.
- /*! By default, rapidjson uses C assert() for assertion.
- User can override it by defining RAPIDJSON_ASSERT(x) macro.
- */
- #ifndef RAPIDJSON_ASSERT
- #include <cassert>
- #define RAPIDJSON_ASSERT(x) assert(x)
- #endif // RAPIDJSON_ASSERT
- ///////////////////////////////////////////////////////////////////////////////
- // RAPIDJSON_STATIC_ASSERT
- // Adopt from boost
- #ifndef RAPIDJSON_STATIC_ASSERT
- namespace rapidjson {
- template <bool x> struct STATIC_ASSERTION_FAILURE;
- template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
- template<int x> struct StaticAssertTest {};
- } // namespace rapidjson
- #define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y)
- #define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y)
- #define RAPIDJSON_DO_JOIN2(X, Y) X##Y
- #define RAPIDJSON_STATIC_ASSERT(x) typedef ::rapidjson::StaticAssertTest<\
- sizeof(::rapidjson::STATIC_ASSERTION_FAILURE<bool(x) >)>\
- RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__)
- #endif
- ///////////////////////////////////////////////////////////////////////////////
- // Helpers
- #define RAPIDJSON_MULTILINEMACRO_BEGIN do {
- #define RAPIDJSON_MULTILINEMACRO_END \
- } while((void)0, 0)
- ///////////////////////////////////////////////////////////////////////////////
- // Allocators and Encodings
- #include "allocators.h"
- #include "encodings.h"
- namespace rapidjson {
- ///////////////////////////////////////////////////////////////////////////////
- // Stream
- /*! \class rapidjson::Stream
- \brief Concept for reading and writing characters.
- For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().
- For write-only stream, only need to implement Put() and Flush().
- \code
- concept Stream {
- typename Ch; //!< Character type of the stream.
- //! Read the current character from stream without moving the read cursor.
- Ch Peek() const;
- //! Read the current character from stream and moving the read cursor to next character.
- Ch Take();
- //! Get the current read cursor.
- //! \return Number of characters read from start.
- size_t Tell();
- //! Begin writing operation at the current read pointer.
- //! \return The begin writer pointer.
- Ch* PutBegin();
- //! Write a character.
- void Put(Ch c);
- //! Flush the buffer.
- void Flush();
- //! End the writing operation.
- //! \param begin The begin write pointer returned by PutBegin().
- //! \return Number of characters written.
- size_t PutEnd(Ch* begin);
- }
- \endcode
- */
- //! Put N copies of a character to a stream.
- template<typename Stream, typename Ch>
- inline void PutN(Stream& stream, Ch c, size_t n) {
- for (size_t i = 0; i < n; i++)
- stream.Put(c);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // StringStream
- //! Read-only string stream.
- /*! \implements Stream
- */
- template <typename Encoding>
- struct GenericStringStream {
- typedef typename Encoding::Ch Ch;
- GenericStringStream(const Ch *src) : src_(src), head_(src) {}
- Ch Peek() const { return *src_; }
- Ch Take() { return *src_++; }
- size_t Tell() const { return src_ - head_; }
- Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
- void Put(Ch) { RAPIDJSON_ASSERT(false); }
- void Flush() { RAPIDJSON_ASSERT(false); }
- size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
- const Ch* src_; //!< Current read position.
- const Ch* head_; //!< Original head of the string.
- };
- typedef GenericStringStream<UTF8<> > StringStream;
- ///////////////////////////////////////////////////////////////////////////////
- // InsituStringStream
- //! A read-write string stream.
- /*! This string stream is particularly designed for in-situ parsing.
- \implements Stream
- */
- template <typename Encoding>
- struct GenericInsituStringStream {
- typedef typename Encoding::Ch Ch;
- GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
- // Read
- Ch Peek() { return *src_; }
- Ch Take() { return *src_++; }
- size_t Tell() { return src_ - head_; }
- // Write
- Ch* PutBegin() { return dst_ = src_; }
- void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
- void Flush() {}
- size_t PutEnd(Ch* begin) { return dst_ - begin; }
- Ch* src_;
- Ch* dst_;
- Ch* head_;
- };
- typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
- ///////////////////////////////////////////////////////////////////////////////
- // Type
- //! Type of JSON value
- enum Type {
- kNullType = 0, //!< null
- kFalseType = 1, //!< false
- kTrueType = 2, //!< true
- kObjectType = 3, //!< object
- kArrayType = 4, //!< array
- kStringType = 5, //!< string
- kNumberType = 6, //!< number
- };
- } // namespace rapidjson
- #endif // RAPIDJSON_RAPIDJSON_H_
|