1 // Tencent is pleased to support the open source community by making RapidJSON available. 2 // 3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 // 5 // Licensed under the MIT License (the "License"); you may not use this file except 6 // in compliance with the License. You may obtain a copy of the License at 7 // 8 // http://opensource.org/licenses/MIT 9 // 10 // Unless required by applicable law or agreed to in writing, software distributed 11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 // specific language governing permissions and limitations under the License. 14 15 #ifndef RAPIDJSON_RAPIDJSON_H_ 16 #define RAPIDJSON_RAPIDJSON_H_ 17 18 /*!\file rapidjson.h 19 \brief common definitions and configuration 20 21 \see RAPIDJSON_CONFIG 22 */ 23 24 /*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration 25 \brief Configuration macros for library features 26 27 Some RapidJSON features are configurable to adapt the library to a wide 28 variety of platforms, environments and usage scenarios. Most of the 29 features can be configured in terms of overriden or predefined 30 preprocessor macros at compile-time. 31 32 Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs. 33 34 \note These macros should be given on the compiler command-line 35 (where applicable) to avoid inconsistent values when compiling 36 different translation units of a single application. 37 */ 38 39 #include <cstdlib> // malloc(), realloc(), free(), size_t 40 #include <cstring> // memset(), memcpy(), memmove(), memcmp() 41 42 /////////////////////////////////////////////////////////////////////////////// 43 // RAPIDJSON_NAMESPACE_(BEGIN|END) 44 /*! \def RAPIDJSON_NAMESPACE 45 \ingroup RAPIDJSON_CONFIG 46 \brief provide custom rapidjson namespace 47 48 In order to avoid symbol clashes and/or "One Definition Rule" errors 49 between multiple inclusions of (different versions of) RapidJSON in 50 a single binary, users can customize the name of the main RapidJSON 51 namespace. 52 53 In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE 54 to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple 55 levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref 56 RAPIDJSON_NAMESPACE_END need to be defined as well: 57 58 \code 59 // in some .cpp file 60 #define RAPIDJSON_NAMESPACE my::rapidjson 61 #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson { 62 #define RAPIDJSON_NAMESPACE_END } } 63 #include "rapidjson/..." 64 \endcode 65 66 \see rapidjson 67 */ 68 /*! \def RAPIDJSON_NAMESPACE_BEGIN 69 \ingroup RAPIDJSON_CONFIG 70 \brief provide custom rapidjson namespace (opening expression) 71 \see RAPIDJSON_NAMESPACE 72 */ 73 /*! \def RAPIDJSON_NAMESPACE_END 74 \ingroup RAPIDJSON_CONFIG 75 \brief provide custom rapidjson namespace (closing expression) 76 \see RAPIDJSON_NAMESPACE 77 */ 78 #ifndef RAPIDJSON_NAMESPACE 79 #define RAPIDJSON_NAMESPACE rapidjson 80 #endif 81 #ifndef RAPIDJSON_NAMESPACE_BEGIN 82 #define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE { 83 #endif 84 #ifndef RAPIDJSON_NAMESPACE_END 85 #define RAPIDJSON_NAMESPACE_END } 86 #endif 87 88 /////////////////////////////////////////////////////////////////////////////// 89 // RAPIDJSON_NO_INT64DEFINE 90 91 /*! \def RAPIDJSON_NO_INT64DEFINE 92 \ingroup RAPIDJSON_CONFIG 93 \brief Use external 64-bit integer types. 94 95 RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types 96 to be available at global scope. 97 98 If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to 99 prevent RapidJSON from defining its own types. 100 */ 101 #ifndef RAPIDJSON_NO_INT64DEFINE 102 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN 103 #ifdef _MSC_VER 104 #include "msinttypes/stdint.h" 105 #include "msinttypes/inttypes.h" 106 #else 107 // Other compilers should have this. 108 #include <stdint.h> 109 #include <inttypes.h> 110 #endif 111 //!@endcond 112 #ifdef RAPIDJSON_DOXYGEN_RUNNING 113 #define RAPIDJSON_NO_INT64DEFINE 114 #endif 115 #endif // RAPIDJSON_NO_INT64TYPEDEF 116 117 /////////////////////////////////////////////////////////////////////////////// 118 // RAPIDJSON_FORCEINLINE 119 120 #ifndef RAPIDJSON_FORCEINLINE 121 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN 122 #if defined(_MSC_VER) && !defined(NDEBUG) 123 #define RAPIDJSON_FORCEINLINE __forceinline 124 #elif defined(__GNUC__) && __GNUC__ >= 4 && !defined(NDEBUG) 125 #define RAPIDJSON_FORCEINLINE __attribute__((always_inline)) 126 #else 127 #define RAPIDJSON_FORCEINLINE 128 #endif 129 //!@endcond 130 #endif // RAPIDJSON_FORCEINLINE 131 132 /////////////////////////////////////////////////////////////////////////////// 133 // RAPIDJSON_ENDIAN 134 #define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine 135 #define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine 136 137 //! Endianness of the machine. 138 /*! 139 \def RAPIDJSON_ENDIAN 140 \ingroup RAPIDJSON_CONFIG 141 142 GCC 4.6 provided macro for detecting endianness of the target machine. But other 143 compilers may not have this. User can define RAPIDJSON_ENDIAN to either 144 \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN. 145 146 Default detection implemented with reference to 147 \li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html 148 \li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp 149 */ 150 #ifndef RAPIDJSON_ENDIAN 151 // Detect with GCC 4.6's macro 152 # ifdef __BYTE_ORDER__ 153 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 154 # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN 155 # elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 156 # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN 157 # else 158 # error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. 159 # endif // __BYTE_ORDER__ 160 // Detect with GLIBC's endian.h 161 # elif defined(__GLIBC__) 162 # include <endian.h> 163 # if (__BYTE_ORDER == __LITTLE_ENDIAN) 164 # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN 165 # elif (__BYTE_ORDER == __BIG_ENDIAN) 166 # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN 167 # else 168 # error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. 169 # endif // __GLIBC__ 170 // Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro 171 # elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) 172 # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN 173 # elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) 174 # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN 175 // Detect with architecture macros 176 # elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) 177 # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN 178 # 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__) 179 # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN 180 # elif defined(RAPIDJSON_DOXYGEN_RUNNING) 181 # define RAPIDJSON_ENDIAN 182 # else 183 # error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. 184 # endif 185 #endif // RAPIDJSON_ENDIAN 186 187 /////////////////////////////////////////////////////////////////////////////// 188 // RAPIDJSON_64BIT 189 190 //! Whether using 64-bit architecture 191 #ifndef RAPIDJSON_64BIT 192 #if defined(__LP64__) || defined(_WIN64) 193 #define RAPIDJSON_64BIT 1 194 #else 195 #define RAPIDJSON_64BIT 0 196 #endif 197 #endif // RAPIDJSON_64BIT 198 199 /////////////////////////////////////////////////////////////////////////////// 200 // RAPIDJSON_ALIGN 201 202 //! Data alignment of the machine. 203 /*! \ingroup RAPIDJSON_CONFIG 204 \param x pointer to align 205 206 Some machines require strict data alignment. Currently the default uses 4 bytes 207 alignment. User can customize by defining the RAPIDJSON_ALIGN function macro., 208 */ 209 #ifndef RAPIDJSON_ALIGN 210 #define RAPIDJSON_ALIGN(x) ((x + 3u) & ~3u) 211 #endif 212 213 /////////////////////////////////////////////////////////////////////////////// 214 // RAPIDJSON_UINT64_C2 215 216 //! Construct a 64-bit literal by a pair of 32-bit integer. 217 /*! 218 64-bit literal with or without ULL suffix is prone to compiler warnings. 219 UINT64_C() is C macro which cause compilation problems. 220 Use this macro to define 64-bit constants by a pair of 32-bit integer. 221 */ 222 #ifndef RAPIDJSON_UINT64_C2 223 #define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32)) 224 #endif 225 226 /////////////////////////////////////////////////////////////////////////////// 227 // RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD 228 229 /*! \def RAPIDJSON_SIMD 230 \ingroup RAPIDJSON_CONFIG 231 \brief Enable SSE2/SSE4.2 optimization. 232 233 RapidJSON supports optimized implementations for some parsing operations 234 based on the SSE2 or SSE4.2 SIMD extensions on modern Intel-compatible 235 processors. 236 237 To enable these optimizations, two different symbols can be defined; 238 \code 239 // Enable SSE2 optimization. 240 #define RAPIDJSON_SSE2 241 242 // Enable SSE4.2 optimization. 243 #define RAPIDJSON_SSE42 244 \endcode 245 246 \c RAPIDJSON_SSE42 takes precedence, if both are defined. 247 248 If any of these symbols is defined, RapidJSON defines the macro 249 \c RAPIDJSON_SIMD to indicate the availability of the optimized code. 250 */ 251 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \ 252 || defined(RAPIDJSON_DOXYGEN_RUNNING) 253 #define RAPIDJSON_SIMD 254 #endif 255 256 /////////////////////////////////////////////////////////////////////////////// 257 // RAPIDJSON_NO_SIZETYPEDEFINE 258 259 #ifndef RAPIDJSON_NO_SIZETYPEDEFINE 260 /*! \def RAPIDJSON_NO_SIZETYPEDEFINE 261 \ingroup RAPIDJSON_CONFIG 262 \brief User-provided \c SizeType definition. 263 264 In order to avoid using 32-bit size types for indexing strings and arrays, 265 define this preprocessor symbol and provide the type rapidjson::SizeType 266 before including RapidJSON: 267 \code 268 #define RAPIDJSON_NO_SIZETYPEDEFINE 269 namespace rapidjson { typedef ::std::size_t SizeType; } 270 #include "rapidjson/..." 271 \endcode 272 273 \see rapidjson::SizeType 274 */ 275 #ifdef RAPIDJSON_DOXYGEN_RUNNING 276 #define RAPIDJSON_NO_SIZETYPEDEFINE 277 #endif 278 RAPIDJSON_NAMESPACE_BEGIN 279 //! Size type (for string lengths, array sizes, etc.) 280 /*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms, 281 instead of using \c size_t. Users may override the SizeType by defining 282 \ref RAPIDJSON_NO_SIZETYPEDEFINE. 283 */ 284 typedef unsigned SizeType; 285 RAPIDJSON_NAMESPACE_END 286 #endif 287 288 // always import std::size_t to rapidjson namespace 289 RAPIDJSON_NAMESPACE_BEGIN 290 using std::size_t; 291 RAPIDJSON_NAMESPACE_END 292 293 /////////////////////////////////////////////////////////////////////////////// 294 // RAPIDJSON_ASSERT 295 296 //! Assertion. 297 /*! \ingroup RAPIDJSON_CONFIG 298 By default, rapidjson uses C \c assert() for internal assertions. 299 User can override it by defining RAPIDJSON_ASSERT(x) macro. 300 301 \note Parsing errors are handled and can be customized by the 302 \ref RAPIDJSON_ERRORS APIs. 303 */ 304 #ifndef RAPIDJSON_ASSERT 305 #include <cassert> 306 #define RAPIDJSON_ASSERT(x) assert(x) 307 #endif // RAPIDJSON_ASSERT 308 309 /////////////////////////////////////////////////////////////////////////////// 310 // RAPIDJSON_STATIC_ASSERT 311 312 // Adopt from boost 313 #ifndef RAPIDJSON_STATIC_ASSERT 314 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN 315 RAPIDJSON_NAMESPACE_BEGIN 316 template <bool x> struct STATIC_ASSERTION_FAILURE; 317 template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; }; 318 template<int x> struct StaticAssertTest {}; 319 RAPIDJSON_NAMESPACE_END 320 321 #define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y) 322 #define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y) 323 #define RAPIDJSON_DO_JOIN2(X, Y) X##Y 324 325 #if defined(__GNUC__) 326 #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) 327 #else 328 #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE 329 #endif 330 //!@endcond 331 332 /*! \def RAPIDJSON_STATIC_ASSERT 333 \brief (Internal) macro to check for conditions at compile-time 334 \param x compile-time condition 335 \hideinitializer 336 */ 337 #define RAPIDJSON_STATIC_ASSERT(x) \ 338 typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \ 339 sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x) >)> \ 340 RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE 341 #endif 342 343 /////////////////////////////////////////////////////////////////////////////// 344 // Helpers 345 346 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN 347 348 #define RAPIDJSON_MULTILINEMACRO_BEGIN do { 349 #define RAPIDJSON_MULTILINEMACRO_END \ 350 } while((void)0, 0) 351 352 // adopted from Boost 353 #define RAPIDJSON_VERSION_CODE(x,y,z) \ 354 (((x)*100000) + ((y)*100) + (z)) 355 356 // token stringification 357 #define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x) 358 #define RAPIDJSON_DO_STRINGIFY(x) #x 359 360 /////////////////////////////////////////////////////////////////////////////// 361 // RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF 362 363 #if defined(__GNUC__) 364 #define RAPIDJSON_GNUC \ 365 RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) 366 #endif 367 368 #if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0)) 369 370 #define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x)) 371 #define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x) 372 #define RAPIDJSON_DIAG_OFF(x) \ 373 RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x))) 374 375 // push/pop support in Clang and GCC>=4.6 376 #if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) 377 #define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) 378 #define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) 379 #else // GCC >= 4.2, < 4.6 380 #define RAPIDJSON_DIAG_PUSH /* ignored */ 381 #define RAPIDJSON_DIAG_POP /* ignored */ 382 #endif 383 384 #elif defined(_MSC_VER) 385 386 // pragma (MSVC specific) 387 #define RAPIDJSON_PRAGMA(x) __pragma(x) 388 #define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x)) 389 390 #define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x) 391 #define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) 392 #define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) 393 394 #else 395 396 #define RAPIDJSON_DIAG_OFF(x) /* ignored */ 397 #define RAPIDJSON_DIAG_PUSH /* ignored */ 398 #define RAPIDJSON_DIAG_POP /* ignored */ 399 400 #endif // RAPIDJSON_DIAG_* 401 402 /////////////////////////////////////////////////////////////////////////////// 403 // C++11 features 404 405 #ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS 406 #if defined(__clang__) 407 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS __has_feature(cxx_rvalue_references) && \ 408 (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306) 409 #elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ 410 (defined(_MSC_VER) && _MSC_VER >= 1600) 411 412 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 413 #else 414 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 415 #endif 416 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS 417 418 #ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT 419 #if defined(__clang__) 420 #define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept) 421 #elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) 422 // (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported 423 #define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 424 #else 425 #define RAPIDJSON_HAS_CXX11_NOEXCEPT 0 426 #endif 427 #endif 428 #if RAPIDJSON_HAS_CXX11_NOEXCEPT 429 #define RAPIDJSON_NOEXCEPT noexcept 430 #else 431 #define RAPIDJSON_NOEXCEPT /* noexcept */ 432 #endif // RAPIDJSON_HAS_CXX11_NOEXCEPT 433 434 // no automatic detection, yet 435 #ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS 436 #define RAPIDJSON_HAS_CXX11_TYPETRAITS 0 437 #endif 438 439 //!@endcond 440 441 /////////////////////////////////////////////////////////////////////////////// 442 // new/delete 443 444 #ifndef RAPIDJSON_NEW 445 ///! customization point for global \c new 446 #define RAPIDJSON_NEW(x) new x 447 #endif 448 #ifndef RAPIDJSON_DELETE 449 ///! customization point for global \c delete 450 #define RAPIDJSON_DELETE(x) delete x 451 #endif 452 453 /////////////////////////////////////////////////////////////////////////////// 454 // Allocators and Encodings 455 456 #include "allocators.h" 457 #include "encodings.h" 458 459 /*! \namespace rapidjson 460 \brief main RapidJSON namespace 461 \see RAPIDJSON_NAMESPACE 462 */ 463 RAPIDJSON_NAMESPACE_BEGIN 464 465 /////////////////////////////////////////////////////////////////////////////// 466 // Stream 467 468 /*! \class rapidjson::Stream 469 \brief Concept for reading and writing characters. 470 471 For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). 472 473 For write-only stream, only need to implement Put() and Flush(). 474 475 \code 476 concept Stream { 477 typename Ch; //!< Character type of the stream. 478 479 //! Read the current character from stream without moving the read cursor. 480 Ch Peek() const; 481 482 //! Read the current character from stream and moving the read cursor to next character. 483 Ch Take(); 484 485 //! Get the current read cursor. 486 //! \return Number of characters read from start. 487 size_t Tell(); 488 489 //! Begin writing operation at the current read pointer. 490 //! \return The begin writer pointer. 491 Ch* PutBegin(); 492 493 //! Write a character. 494 void Put(Ch c); 495 496 //! Flush the buffer. 497 void Flush(); 498 499 //! End the writing operation. 500 //! \param begin The begin write pointer returned by PutBegin(). 501 //! \return Number of characters written. 502 size_t PutEnd(Ch* begin); 503 } 504 \endcode 505 */ 506 507 //! Provides additional information for stream. 508 /*! 509 By using traits pattern, this type provides a default configuration for stream. 510 For custom stream, this type can be specialized for other configuration. 511 See TEST(Reader, CustomStringStream) in readertest.cpp for example. 512 */ 513 template<typename Stream> 514 struct StreamTraits { 515 //! Whether to make local copy of stream for optimization during parsing. 516 /*! 517 By default, for safety, streams do not use local copy optimization. 518 Stream that can be copied fast should specialize this, like StreamTraits<StringStream>. 519 */ 520 enum { copyOptimization = 0 }; 521 }; 522 523 //! Put N copies of a character to a stream. 524 template<typename Stream, typename Ch> 525 inline void PutN(Stream& stream, Ch c, size_t n) { 526 for (size_t i = 0; i < n; i++) 527 stream.Put(c); 528 } 529 530 /////////////////////////////////////////////////////////////////////////////// 531 // StringStream 532 533 //! Read-only string stream. 534 /*! \note implements Stream concept 535 */ 536 template <typename Encoding> 537 struct GenericStringStream { 538 typedef typename Encoding::Ch Ch; 539 540 GenericStringStream(const Ch *src) : src_(src), head_(src) {} 541 542 Ch Peek() const { return *src_; } 543 Ch Take() { return *src_++; } 544 size_t Tell() const { return static_cast<size_t>(src_ - head_); } 545 546 Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 547 void Put(Ch) { RAPIDJSON_ASSERT(false); } 548 void Flush() { RAPIDJSON_ASSERT(false); } 549 size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 550 551 const Ch* src_; //!< Current read position. 552 const Ch* head_; //!< Original head of the string. 553 }; 554 555 template <typename Encoding> 556 struct StreamTraits<GenericStringStream<Encoding> > { 557 enum { copyOptimization = 1 }; 558 }; 559 560 //! String stream with UTF8 encoding. 561 typedef GenericStringStream<UTF8<> > StringStream; 562 563 /////////////////////////////////////////////////////////////////////////////// 564 // InsituStringStream 565 566 //! A read-write string stream. 567 /*! This string stream is particularly designed for in-situ parsing. 568 \note implements Stream concept 569 */ 570 template <typename Encoding> 571 struct GenericInsituStringStream { 572 typedef typename Encoding::Ch Ch; 573 574 GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} 575 576 // Read 577 Ch Peek() { return *src_; } 578 Ch Take() { return *src_++; } 579 size_t Tell() { return static_cast<size_t>(src_ - head_); } 580 581 // Write 582 void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } 583 584 Ch* PutBegin() { return dst_ = src_; } 585 size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); } 586 void Flush() {} 587 588 Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } 589 void Pop(size_t count) { dst_ -= count; } 590 591 Ch* src_; 592 Ch* dst_; 593 Ch* head_; 594 }; 595 596 template <typename Encoding> 597 struct StreamTraits<GenericInsituStringStream<Encoding> > { 598 enum { copyOptimization = 1 }; 599 }; 600 601 //! Insitu string stream with UTF8 encoding. 602 typedef GenericInsituStringStream<UTF8<> > InsituStringStream; 603 604 /////////////////////////////////////////////////////////////////////////////// 605 // Type 606 607 //! Type of JSON value 608 enum Type { 609 kNullType = 0, //!< null 610 kFalseType = 1, //!< false 611 kTrueType = 2, //!< true 612 kObjectType = 3, //!< object 613 kArrayType = 4, //!< array 614 kStringType = 5, //!< string 615 kNumberType = 6 //!< number 616 }; 617 618 RAPIDJSON_NAMESPACE_END 619 620 #endif // RAPIDJSON_RAPIDJSON_H_ 621