// Begin file: rapidjson.h | |
// Tencent is pleased to support the open source community by making RapidJSON available. | |
// | |
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. | |
// | |
// Licensed under the MIT License (the "License"); you may not use this file except | |
// in compliance with the License. You may obtain a copy of the License at | |
// | |
// http://opensource.org/licenses/MIT | |
// | |
// Unless required by applicable law or agreed to in writing, software distributed | |
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |
// CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
// specific language governing permissions and limitations under the License. | |
#ifndef RAPIDJSON_RAPIDJSON_H_ | |
#define RAPIDJSON_RAPIDJSON_H_ | |
/*!\file rapidjson.h | |
\brief common definitions and configuration | |
\see RAPIDJSON_CONFIG | |
*/ | |
/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration | |
\brief Configuration macros for library features | |
Some RapidJSON features are configurable to adapt the library to a wide | |
variety of platforms, environments and usage scenarios. Most of the | |
features can be configured in terms of overridden or predefined | |
preprocessor macros at compile-time. | |
Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs. | |
\note These macros should be given on the compiler command-line | |
(where applicable) to avoid inconsistent values when compiling | |
different translation units of a single application. | |
*/ | |
#include <cstdlib> // malloc(), realloc(), free(), size_t | |
#include <cstring> // memset(), memcpy(), memmove(), memcmp() | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_VERSION_STRING | |
// | |
// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt. | |
// | |
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN | |
// token stringification | |
#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x) | |
#define RAPIDJSON_DO_STRINGIFY(x) #x | |
// token concatenation | |
#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 | |
//!@endcond | |
/*! \def RAPIDJSON_MAJOR_VERSION | |
\ingroup RAPIDJSON_CONFIG | |
\brief Major version of RapidJSON in integer. | |
*/ | |
/*! \def RAPIDJSON_MINOR_VERSION | |
\ingroup RAPIDJSON_CONFIG | |
\brief Minor version of RapidJSON in integer. | |
*/ | |
/*! \def RAPIDJSON_PATCH_VERSION | |
\ingroup RAPIDJSON_CONFIG | |
\brief Patch version of RapidJSON in integer. | |
*/ | |
/*! \def RAPIDJSON_VERSION_STRING | |
\ingroup RAPIDJSON_CONFIG | |
\brief Version of RapidJSON in "<major>.<minor>.<patch>" string format. | |
*/ | |
#define RAPIDJSON_MAJOR_VERSION 1 | |
#define RAPIDJSON_MINOR_VERSION 1 | |
#define RAPIDJSON_PATCH_VERSION 0 | |
#define RAPIDJSON_VERSION_STRING \ | |
RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION) | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_NAMESPACE_(BEGIN|END) | |
/*! \def RAPIDJSON_NAMESPACE | |
\ingroup RAPIDJSON_CONFIG | |
\brief provide custom rapidjson namespace | |
In order to avoid symbol clashes and/or "One Definition Rule" errors | |
between multiple inclusions of (different versions of) RapidJSON in | |
a single binary, users can customize the name of the main RapidJSON | |
namespace. | |
In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE | |
to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple | |
levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref | |
RAPIDJSON_NAMESPACE_END need to be defined as well: | |
\code | |
// in some .cpp file | |
#define RAPIDJSON_NAMESPACE my::rapidjson | |
#define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson { | |
#define RAPIDJSON_NAMESPACE_END } } | |
#include "rapidjson/..." | |
\endcode | |
\see rapidjson | |
*/ | |
/*! \def RAPIDJSON_NAMESPACE_BEGIN | |
\ingroup RAPIDJSON_CONFIG | |
\brief provide custom rapidjson namespace (opening expression) | |
\see RAPIDJSON_NAMESPACE | |
*/ | |
/*! \def RAPIDJSON_NAMESPACE_END | |
\ingroup RAPIDJSON_CONFIG | |
\brief provide custom rapidjson namespace (closing expression) | |
\see RAPIDJSON_NAMESPACE | |
*/ | |
#ifndef RAPIDJSON_NAMESPACE | |
#define RAPIDJSON_NAMESPACE rapidjson | |
#endif | |
#ifndef RAPIDJSON_NAMESPACE_BEGIN | |
#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE { | |
#endif | |
#ifndef RAPIDJSON_NAMESPACE_END | |
#define RAPIDJSON_NAMESPACE_END } | |
#endif | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_HAS_STDSTRING | |
#ifndef RAPIDJSON_HAS_STDSTRING | |
#ifdef RAPIDJSON_DOXYGEN_RUNNING | |
#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation | |
#else | |
#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default | |
#endif | |
/*! \def RAPIDJSON_HAS_STDSTRING | |
\ingroup RAPIDJSON_CONFIG | |
\brief Enable RapidJSON support for \c std::string | |
By defining this preprocessor symbol to \c 1, several convenience functions for using | |
\ref rapidjson::GenericValue with \c std::string are enabled, especially | |
for construction and comparison. | |
\hideinitializer | |
*/ | |
#endif // !defined(RAPIDJSON_HAS_STDSTRING) | |
#if RAPIDJSON_HAS_STDSTRING | |
#include <string> | |
#endif // RAPIDJSON_HAS_STDSTRING | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_NO_INT64DEFINE | |
/*! \def RAPIDJSON_NO_INT64DEFINE | |
\ingroup RAPIDJSON_CONFIG | |
\brief Use external 64-bit integer types. | |
RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types | |
to be available at global scope. | |
If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to | |
prevent RapidJSON from defining its own types. | |
*/ | |
#ifndef RAPIDJSON_NO_INT64DEFINE | |
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN | |
#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013 | |
// Begin file: msinttypes/stdint.h | |
// ISO C9x compliant stdint.h for Microsoft Visual Studio | |
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 | |
// | |
// Copyright (c) 2006-2013 Alexander Chemeris | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions are met: | |
// | |
// 1. Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// 2. Redistributions in binary form must reproduce the above copyright | |
// notice, this list of conditions and the following disclaimer in the | |
// documentation and/or other materials provided with the distribution. | |
// | |
// 3. Neither the name of the product nor the names of its contributors may | |
// be used to endorse or promote products derived from this software | |
// without specific prior written permission. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | |
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
// | |
/////////////////////////////////////////////////////////////////////////////// | |
// The above software in this distribution may have been modified by | |
// THL A29 Limited ("Tencent Modifications"). | |
// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. | |
#ifndef _MSC_VER // [ | |
#error "Use this header only with Microsoft Visual C++ compilers!" | |
#endif // _MSC_VER ] | |
#ifndef _MSC_STDINT_H_ // [ | |
#define _MSC_STDINT_H_ | |
#if _MSC_VER > 1000 | |
#pragma once | |
#endif | |
// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010. | |
#if _MSC_VER >= 1600 // [ | |
#include <stdint.h> | |
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 | |
#undef INT8_C | |
#undef INT16_C | |
#undef INT32_C | |
#undef INT64_C | |
#undef UINT8_C | |
#undef UINT16_C | |
#undef UINT32_C | |
#undef UINT64_C | |
// 7.18.4.1 Macros for minimum-width integer constants | |
#define INT8_C(val) val##i8 | |
#define INT16_C(val) val##i16 | |
#define INT32_C(val) val##i32 | |
#define INT64_C(val) val##i64 | |
#define UINT8_C(val) val##ui8 | |
#define UINT16_C(val) val##ui16 | |
#define UINT32_C(val) val##ui32 | |
#define UINT64_C(val) val##ui64 | |
// 7.18.4.2 Macros for greatest-width integer constants | |
// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>. | |
// Check out Issue 9 for the details. | |
#ifndef INTMAX_C // [ | |
# define INTMAX_C INT64_C | |
#endif // INTMAX_C ] | |
#ifndef UINTMAX_C // [ | |
# define UINTMAX_C UINT64_C | |
#endif // UINTMAX_C ] | |
#endif // __STDC_CONSTANT_MACROS ] | |
#else // ] _MSC_VER >= 1700 [ | |
#include <limits.h> | |
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when | |
// compiling for ARM we have to wrap <wchar.h> include with 'extern "C++" {}' | |
// or compiler would give many errors like this: | |
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed | |
#if defined(__cplusplus) && !defined(_M_ARM) | |
extern "C" { | |
#endif | |
# include <wchar.h> | |
#if defined(__cplusplus) && !defined(_M_ARM) | |
} | |
#endif | |
// Define _W64 macros to mark types changing their size, like intptr_t. | |
#ifndef _W64 | |
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 | |
# define _W64 __w64 | |
# else | |
# define _W64 | |
# endif | |
#endif | |
// 7.18.1 Integer types | |
// 7.18.1.1 Exact-width integer types | |
// Visual Studio 6 and Embedded Visual C++ 4 doesn't | |
// realize that, e.g. char has the same size as __int8 | |
// so we give up on __intX for them. | |
#if (_MSC_VER < 1300) | |
typedef signed char int8_t; | |
typedef signed short int16_t; | |
typedef signed int int32_t; | |
typedef unsigned char uint8_t; | |
typedef unsigned short uint16_t; | |
typedef unsigned int uint32_t; | |
#else | |
typedef signed __int8 int8_t; | |
typedef signed __int16 int16_t; | |
typedef signed __int32 int32_t; | |
typedef unsigned __int8 uint8_t; | |
typedef unsigned __int16 uint16_t; | |
typedef unsigned __int32 uint32_t; | |
#endif | |
typedef signed __int64 int64_t; | |
typedef unsigned __int64 uint64_t; | |
// 7.18.1.2 Minimum-width integer types | |
typedef int8_t int_least8_t; | |
typedef int16_t int_least16_t; | |
typedef int32_t int_least32_t; | |
typedef int64_t int_least64_t; | |
typedef uint8_t uint_least8_t; | |
typedef uint16_t uint_least16_t; | |
typedef uint32_t uint_least32_t; | |
typedef uint64_t uint_least64_t; | |
// 7.18.1.3 Fastest minimum-width integer types | |
typedef int8_t int_fast8_t; | |
typedef int16_t int_fast16_t; | |
typedef int32_t int_fast32_t; | |
typedef int64_t int_fast64_t; | |
typedef uint8_t uint_fast8_t; | |
typedef uint16_t uint_fast16_t; | |
typedef uint32_t uint_fast32_t; | |
typedef uint64_t uint_fast64_t; | |
// 7.18.1.4 Integer types capable of holding object pointers | |
#ifdef _WIN64 // [ | |
typedef signed __int64 intptr_t; | |
typedef unsigned __int64 uintptr_t; | |
#else // _WIN64 ][ | |
typedef _W64 signed int intptr_t; | |
typedef _W64 unsigned int uintptr_t; | |
#endif // _WIN64 ] | |
// 7.18.1.5 Greatest-width integer types | |
typedef int64_t intmax_t; | |
typedef uint64_t uintmax_t; | |
// 7.18.2 Limits of specified-width integer types | |
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 | |
// 7.18.2.1 Limits of exact-width integer types | |
#define INT8_MIN ((int8_t)_I8_MIN) | |
#define INT8_MAX _I8_MAX | |
#define INT16_MIN ((int16_t)_I16_MIN) | |
#define INT16_MAX _I16_MAX | |
#define INT32_MIN ((int32_t)_I32_MIN) | |
#define INT32_MAX _I32_MAX | |
#define INT64_MIN ((int64_t)_I64_MIN) | |
#define INT64_MAX _I64_MAX | |
#define UINT8_MAX _UI8_MAX | |
#define UINT16_MAX _UI16_MAX | |
#define UINT32_MAX _UI32_MAX | |
#define UINT64_MAX _UI64_MAX | |
// 7.18.2.2 Limits of minimum-width integer types | |
#define INT_LEAST8_MIN INT8_MIN | |
#define INT_LEAST8_MAX INT8_MAX | |
#define INT_LEAST16_MIN INT16_MIN | |
#define INT_LEAST16_MAX INT16_MAX | |
#define INT_LEAST32_MIN INT32_MIN | |
#define INT_LEAST32_MAX INT32_MAX | |
#define INT_LEAST64_MIN INT64_MIN | |
#define INT_LEAST64_MAX INT64_MAX | |
#define UINT_LEAST8_MAX UINT8_MAX | |
#define UINT_LEAST16_MAX UINT16_MAX | |
#define UINT_LEAST32_MAX UINT32_MAX | |
#define UINT_LEAST64_MAX UINT64_MAX | |
// 7.18.2.3 Limits of fastest minimum-width integer types | |
#define INT_FAST8_MIN INT8_MIN | |
#define INT_FAST8_MAX INT8_MAX | |
#define INT_FAST16_MIN INT16_MIN | |
#define INT_FAST16_MAX INT16_MAX | |
#define INT_FAST32_MIN INT32_MIN | |
#define INT_FAST32_MAX INT32_MAX | |
#define INT_FAST64_MIN INT64_MIN | |
#define INT_FAST64_MAX INT64_MAX | |
#define UINT_FAST8_MAX UINT8_MAX | |
#define UINT_FAST16_MAX UINT16_MAX | |
#define UINT_FAST32_MAX UINT32_MAX | |
#define UINT_FAST64_MAX UINT64_MAX | |
// 7.18.2.4 Limits of integer types capable of holding object pointers | |
#ifdef _WIN64 // [ | |
# define INTPTR_MIN INT64_MIN | |
# define INTPTR_MAX INT64_MAX | |
# define UINTPTR_MAX UINT64_MAX | |
#else // _WIN64 ][ | |
# define INTPTR_MIN INT32_MIN | |
# define INTPTR_MAX INT32_MAX | |
# define UINTPTR_MAX UINT32_MAX | |
#endif // _WIN64 ] | |
// 7.18.2.5 Limits of greatest-width integer types | |
#define INTMAX_MIN INT64_MIN | |
#define INTMAX_MAX INT64_MAX | |
#define UINTMAX_MAX UINT64_MAX | |
// 7.18.3 Limits of other integer types | |
#ifdef _WIN64 // [ | |
# define PTRDIFF_MIN _I64_MIN | |
# define PTRDIFF_MAX _I64_MAX | |
#else // _WIN64 ][ | |
# define PTRDIFF_MIN _I32_MIN | |
# define PTRDIFF_MAX _I32_MAX | |
#endif // _WIN64 ] | |
#define SIG_ATOMIC_MIN INT_MIN | |
#define SIG_ATOMIC_MAX INT_MAX | |
#ifndef SIZE_MAX // [ | |
# ifdef _WIN64 // [ | |
# define SIZE_MAX _UI64_MAX | |
# else // _WIN64 ][ | |
# define SIZE_MAX _UI32_MAX | |
# endif // _WIN64 ] | |
#endif // SIZE_MAX ] | |
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h> | |
#ifndef WCHAR_MIN // [ | |
# define WCHAR_MIN 0 | |
#endif // WCHAR_MIN ] | |
#ifndef WCHAR_MAX // [ | |
# define WCHAR_MAX _UI16_MAX | |
#endif // WCHAR_MAX ] | |
#define WINT_MIN 0 | |
#define WINT_MAX _UI16_MAX | |
#endif // __STDC_LIMIT_MACROS ] | |
// 7.18.4 Limits of other integer types | |
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 | |
// 7.18.4.1 Macros for minimum-width integer constants | |
#define INT8_C(val) val##i8 | |
#define INT16_C(val) val##i16 | |
#define INT32_C(val) val##i32 | |
#define INT64_C(val) val##i64 | |
#define UINT8_C(val) val##ui8 | |
#define UINT16_C(val) val##ui16 | |
#define UINT32_C(val) val##ui32 | |
#define UINT64_C(val) val##ui64 | |
// 7.18.4.2 Macros for greatest-width integer constants | |
// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>. | |
// Check out Issue 9 for the details. | |
#ifndef INTMAX_C // [ | |
# define INTMAX_C INT64_C | |
#endif // INTMAX_C ] | |
#ifndef UINTMAX_C // [ | |
# define UINTMAX_C UINT64_C | |
#endif // UINTMAX_C ] | |
#endif // __STDC_CONSTANT_MACROS ] | |
#endif // _MSC_VER >= 1600 ] | |
#endif // _MSC_STDINT_H_ ] | |
// End file:msinttypes/stdint.h | |
// Begin file: msinttypes/inttypes.h | |
// ISO C9x compliant inttypes.h for Microsoft Visual Studio | |
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 | |
// | |
// Copyright (c) 2006-2013 Alexander Chemeris | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions are met: | |
// | |
// 1. Redistributions of source code must retain the above copyright notice, | |
// this list of conditions and the following disclaimer. | |
// | |
// 2. Redistributions in binary form must reproduce the above copyright | |
// notice, this list of conditions and the following disclaimer in the | |
// documentation and/or other materials provided with the distribution. | |
// | |
// 3. Neither the name of the product nor the names of its contributors may | |
// be used to endorse or promote products derived from this software | |
// without specific prior written permission. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | |
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
// | |
/////////////////////////////////////////////////////////////////////////////// | |
// The above software in this distribution may have been modified by | |
// THL A29 Limited ("Tencent Modifications"). | |
// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. | |
#ifndef _MSC_VER // [ | |
#error "Use this header only with Microsoft Visual C++ compilers!" | |
#endif // _MSC_VER ] | |
#ifndef _MSC_INTTYPES_H_ // [ | |
#define _MSC_INTTYPES_H_ | |
#if _MSC_VER > 1000 | |
#pragma once | |
#endif | |
// Begin file: stdint.h | |
// already included | |
// End file:stdint.h | |
// miloyip: VC supports inttypes.h since VC2013 | |
#if _MSC_VER >= 1800 | |
#include <inttypes.h> | |
#else | |
// 7.8 Format conversion of integer types | |
typedef struct { | |
intmax_t quot; | |
intmax_t rem; | |
} imaxdiv_t; | |
// 7.8.1 Macros for format specifiers | |
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 | |
// The fprintf macros for signed integers are: | |
#define PRId8 "d" | |
#define PRIi8 "i" | |
#define PRIdLEAST8 "d" | |
#define PRIiLEAST8 "i" | |
#define PRIdFAST8 "d" | |
#define PRIiFAST8 "i" | |
#define PRId16 "hd" | |
#define PRIi16 "hi" | |
#define PRIdLEAST16 "hd" | |
#define PRIiLEAST16 "hi" | |
#define PRIdFAST16 "hd" | |
#define PRIiFAST16 "hi" | |
#define PRId32 "I32d" | |
#define PRIi32 "I32i" | |
#define PRIdLEAST32 "I32d" | |
#define PRIiLEAST32 "I32i" | |
#define PRIdFAST32 "I32d" | |
#define PRIiFAST32 "I32i" | |
#define PRId64 "I64d" | |
#define PRIi64 "I64i" | |
#define PRIdLEAST64 "I64d" | |
#define PRIiLEAST64 "I64i" | |
#define PRIdFAST64 "I64d" | |
#define PRIiFAST64 "I64i" | |
#define PRIdMAX "I64d" | |
#define PRIiMAX "I64i" | |
#define PRIdPTR "Id" | |
#define PRIiPTR "Ii" | |
// The fprintf macros for unsigned integers are: | |
#define PRIo8 "o" | |
#define PRIu8 "u" | |
#define PRIx8 "x" | |
#define PRIX8 "X" | |
#define PRIoLEAST8 "o" | |
#define PRIuLEAST8 "u" | |
#define PRIxLEAST8 "x" | |
#define PRIXLEAST8 "X" | |
#define PRIoFAST8 "o" | |
#define PRIuFAST8 "u" | |
#define PRIxFAST8 "x" | |
#define PRIXFAST8 "X" | |
#define PRIo16 "ho" | |
#define PRIu16 "hu" | |
#define PRIx16 "hx" | |
#define PRIX16 "hX" | |
#define PRIoLEAST16 "ho" | |
#define PRIuLEAST16 "hu" | |
#define PRIxLEAST16 "hx" | |
#define PRIXLEAST16 "hX" | |
#define PRIoFAST16 "ho" | |
#define PRIuFAST16 "hu" | |
#define PRIxFAST16 "hx" | |
#define PRIXFAST16 "hX" | |
#define PRIo32 "I32o" | |
#define PRIu32 "I32u" | |
#define PRIx32 "I32x" | |
#define PRIX32 "I32X" | |
#define PRIoLEAST32 "I32o" | |
#define PRIuLEAST32 "I32u" | |
#define PRIxLEAST32 "I32x" | |
#define PRIXLEAST32 "I32X" | |
#define PRIoFAST32 "I32o" | |
#define PRIuFAST32 "I32u" | |
#define PRIxFAST32 "I32x" | |
#define PRIXFAST32 "I32X" | |
#define PRIo64 "I64o" | |
#define PRIu64 "I64u" | |
#define PRIx64 "I64x" | |
#define PRIX64 "I64X" | |
#define PRIoLEAST64 "I64o" | |
#define PRIuLEAST64 "I64u" | |
#define PRIxLEAST64 "I64x" | |
#define PRIXLEAST64 "I64X" | |
#define PRIoFAST64 "I64o" | |
#define PRIuFAST64 "I64u" | |
#define PRIxFAST64 "I64x" | |
#define PRIXFAST64 "I64X" | |
#define PRIoMAX "I64o" | |
#define PRIuMAX "I64u" | |
#define PRIxMAX "I64x" | |
#define PRIXMAX "I64X" | |
#define PRIoPTR "Io" | |
#define PRIuPTR "Iu" | |
#define PRIxPTR "Ix" | |
#define PRIXPTR "IX" | |
// The fscanf macros for signed integers are: | |
#define SCNd8 "d" | |
#define SCNi8 "i" | |
#define SCNdLEAST8 "d" | |
#define SCNiLEAST8 "i" | |
#define SCNdFAST8 "d" | |
#define SCNiFAST8 "i" | |
#define SCNd16 "hd" | |
#define SCNi16 "hi" | |
#define SCNdLEAST16 "hd" | |
#define SCNiLEAST16 "hi" | |
#define SCNdFAST16 "hd" | |
#define SCNiFAST16 "hi" | |
#define SCNd32 "ld" | |
#define SCNi32 "li" | |
#define SCNdLEAST32 "ld" | |
#define SCNiLEAST32 "li" | |
#define SCNdFAST32 "ld" | |
#define SCNiFAST32 "li" | |
#define SCNd64 "I64d" | |
#define SCNi64 "I64i" | |
#define SCNdLEAST64 "I64d" | |
#define SCNiLEAST64 "I64i" | |
#define SCNdFAST64 "I64d" | |
#define SCNiFAST64 "I64i" | |
#define SCNdMAX "I64d" | |
#define SCNiMAX "I64i" | |
#ifdef _WIN64 // [ | |
# define SCNdPTR "I64d" | |
# define SCNiPTR "I64i" | |
#else // _WIN64 ][ | |
# define SCNdPTR "ld" | |
# define SCNiPTR "li" | |
#endif // _WIN64 ] | |
// The fscanf macros for unsigned integers are: | |
#define SCNo8 "o" | |
#define SCNu8 "u" | |
#define SCNx8 "x" | |
#define SCNX8 "X" | |
#define SCNoLEAST8 "o" | |
#define SCNuLEAST8 "u" | |
#define SCNxLEAST8 "x" | |
#define SCNXLEAST8 "X" | |
#define SCNoFAST8 "o" | |
#define SCNuFAST8 "u" | |
#define SCNxFAST8 "x" | |
#define SCNXFAST8 "X" | |
#define SCNo16 "ho" | |
#define SCNu16 "hu" | |
#define SCNx16 "hx" | |
#define SCNX16 "hX" | |
#define SCNoLEAST16 "ho" | |
#define SCNuLEAST16 "hu" | |
#define SCNxLEAST16 "hx" | |
#define SCNXLEAST16 "hX" | |
#define SCNoFAST16 "ho" | |
#define SCNuFAST16 "hu" | |
#define SCNxFAST16 "hx" | |
#define SCNXFAST16 "hX" | |
#define SCNo32 "lo" | |
#define SCNu32 "lu" | |
#define SCNx32 "lx" | |
#define SCNX32 "lX" | |
#define SCNoLEAST32 "lo" | |
#define SCNuLEAST32 "lu" | |
#define SCNxLEAST32 "lx" | |
#define SCNXLEAST32 "lX" | |
#define SCNoFAST32 "lo" | |
#define SCNuFAST32 "lu" | |
#define SCNxFAST32 "lx" | |
#define SCNXFAST32 "lX" | |
#define SCNo64 "I64o" | |
#define SCNu64 "I64u" | |
#define SCNx64 "I64x" | |
#define SCNX64 "I64X" | |
#define SCNoLEAST64 "I64o" | |
#define SCNuLEAST64 "I64u" | |
#define SCNxLEAST64 "I64x" | |
#define SCNXLEAST64 "I64X" | |
#define SCNoFAST64 "I64o" | |
#define SCNuFAST64 "I64u" | |
#define SCNxFAST64 "I64x" | |
#define SCNXFAST64 "I64X" | |
#define SCNoMAX "I64o" | |
#define SCNuMAX "I64u" | |
#define SCNxMAX "I64x" | |
#define SCNXMAX "I64X" | |
#ifdef _WIN64 // [ | |
# define SCNoPTR "I64o" | |
# define SCNuPTR "I64u" | |
# define SCNxPTR "I64x" | |
# define SCNXPTR "I64X" | |
#else // _WIN64 ][ | |
# define SCNoPTR "lo" | |
# define SCNuPTR "lu" | |
# define SCNxPTR "lx" | |
# define SCNXPTR "lX" | |
#endif // _WIN64 ] | |
#endif // __STDC_FORMAT_MACROS ] | |
// 7.8.2 Functions for greatest-width integer types | |
// 7.8.2.1 The imaxabs function | |
#define imaxabs _abs64 | |
// 7.8.2.2 The imaxdiv function | |
// This is modified version of div() function from Microsoft's div.c found | |
// in %MSVC.NET%\crt\src\div.c | |
#ifdef STATIC_IMAXDIV // [ | |
static | |
#else // STATIC_IMAXDIV ][ | |
_inline | |
#endif // STATIC_IMAXDIV ] | |
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) | |
{ | |
imaxdiv_t result; | |
result.quot = numer / denom; | |
result.rem = numer % denom; | |
if (numer < 0 && result.rem > 0) { | |
// did division wrong; must fix up | |
++result.quot; | |
result.rem -= denom; | |
} | |
return result; | |
} | |
// 7.8.2.3 The strtoimax and strtoumax functions | |
#define strtoimax _strtoi64 | |
#define strtoumax _strtoui64 | |
// 7.8.2.4 The wcstoimax and wcstoumax functions | |
#define wcstoimax _wcstoi64 | |
#define wcstoumax _wcstoui64 | |
#endif // _MSC_VER >= 1800 | |
#endif // _MSC_INTTYPES_H_ ] | |
// End file:msinttypes/inttypes.h | |
#else | |
// Other compilers should have this. | |
#include <stdint.h> | |
#include <inttypes.h> | |
#endif | |
//!@endcond | |
#ifdef RAPIDJSON_DOXYGEN_RUNNING | |
#define RAPIDJSON_NO_INT64DEFINE | |
#endif | |
#endif // RAPIDJSON_NO_INT64TYPEDEF | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_FORCEINLINE | |
#ifndef RAPIDJSON_FORCEINLINE | |
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN | |
#if defined(_MSC_VER) && defined(NDEBUG) | |
#define RAPIDJSON_FORCEINLINE __forceinline | |
#elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG) | |
#define RAPIDJSON_FORCEINLINE __attribute__((always_inline)) | |
#else | |
#define RAPIDJSON_FORCEINLINE | |
#endif | |
//!@endcond | |
#endif // RAPIDJSON_FORCEINLINE | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_ENDIAN | |
#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine | |
#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine | |
//! Endianness of the machine. | |
/*! | |
\def RAPIDJSON_ENDIAN | |
\ingroup RAPIDJSON_CONFIG | |
GCC 4.6 provided macro for detecting endianness of the target machine. But other | |
compilers may not have this. User can define RAPIDJSON_ENDIAN to either | |
\ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN. | |
Default detection implemented with reference to | |
\li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html | |
\li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp | |
*/ | |
#ifndef RAPIDJSON_ENDIAN | |
// Detect with GCC 4.6's macro | |
# ifdef __BYTE_ORDER__ | |
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | |
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN | |
# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | |
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN | |
# else | |
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. | |
# endif // __BYTE_ORDER__ | |
// Detect with GLIBC's endian.h | |
# elif defined(__GLIBC__) | |
# include <endian.h> | |
# if (__BYTE_ORDER == __LITTLE_ENDIAN) | |
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN | |
# elif (__BYTE_ORDER == __BIG_ENDIAN) | |
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN | |
# else | |
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. | |
# endif // __GLIBC__ | |
// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro | |
# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) | |
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN | |
# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) | |
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN | |
// Detect with architecture macros | |
# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) | |
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN | |
# 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__) | |
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN | |
# elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) | |
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN | |
# elif defined(RAPIDJSON_DOXYGEN_RUNNING) | |
# define RAPIDJSON_ENDIAN | |
# else | |
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. | |
# endif | |
#endif // RAPIDJSON_ENDIAN | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_64BIT | |
//! Whether using 64-bit architecture | |
#ifndef RAPIDJSON_64BIT | |
#if defined(__LP64__) || (defined(__x86_64__) && defined(__ILP32__)) || defined(_WIN64) || defined(__EMSCRIPTEN__) | |
#define RAPIDJSON_64BIT 1 | |
#else | |
#define RAPIDJSON_64BIT 0 | |
#endif | |
#endif // RAPIDJSON_64BIT | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_ALIGN | |
//! Data alignment of the machine. | |
/*! \ingroup RAPIDJSON_CONFIG | |
\param x pointer to align | |
Some machines require strict data alignment. The default is 8 bytes. | |
User can customize by defining the RAPIDJSON_ALIGN function macro. | |
*/ | |
#ifndef RAPIDJSON_ALIGN | |
#define RAPIDJSON_ALIGN(x) (((x) + static_cast<size_t>(7u)) & ~static_cast<size_t>(7u)) | |
#endif | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_UINT64_C2 | |
//! Construct a 64-bit literal by a pair of 32-bit integer. | |
/*! | |
64-bit literal with or without ULL suffix is prone to compiler warnings. | |
UINT64_C() is C macro which cause compilation problems. | |
Use this macro to define 64-bit constants by a pair of 32-bit integer. | |
*/ | |
#ifndef RAPIDJSON_UINT64_C2 | |
#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32)) | |
#endif | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_48BITPOINTER_OPTIMIZATION | |
//! Use only lower 48-bit address for some pointers. | |
/*! | |
\ingroup RAPIDJSON_CONFIG | |
This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address. | |
The higher 16-bit can be used for storing other data. | |
\c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture. | |
*/ | |
#ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION | |
#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) | |
#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1 | |
#else | |
#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0 | |
#endif | |
#endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION | |
#if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1 | |
#if RAPIDJSON_64BIT != 1 | |
#error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1 | |
#endif | |
#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast<type *>((reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast<uintptr_t>(reinterpret_cast<const void*>(x)))) | |
#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF)))) | |
#else | |
#define RAPIDJSON_SETPOINTER(type, p, x) (p = (x)) | |
#define RAPIDJSON_GETPOINTER(type, p) (p) | |
#endif | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_NEON/RAPIDJSON_SIMD | |
/*! \def RAPIDJSON_SIMD | |
\ingroup RAPIDJSON_CONFIG | |
\brief Enable SSE2/SSE4.2/Neon optimization. | |
RapidJSON supports optimized implementations for some parsing operations | |
based on the SSE2, SSE4.2 or NEon SIMD extensions on modern Intel | |
or ARM compatible processors. | |
To enable these optimizations, three different symbols can be defined; | |
\code | |
// Enable SSE2 optimization. | |
#define RAPIDJSON_SSE2 | |
// Enable SSE4.2 optimization. | |
#define RAPIDJSON_SSE42 | |
\endcode | |
// Enable ARM Neon optimization. | |
#define RAPIDJSON_NEON | |
\endcode | |
\c RAPIDJSON_SSE42 takes precedence over SSE2, if both are defined. | |
If any of these symbols is defined, RapidJSON defines the macro | |
\c RAPIDJSON_SIMD to indicate the availability of the optimized code. | |
*/ | |
#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \ | |
|| defined(RAPIDJSON_NEON) || defined(RAPIDJSON_DOXYGEN_RUNNING) | |
#define RAPIDJSON_SIMD | |
#endif | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_NO_SIZETYPEDEFINE | |
#ifndef RAPIDJSON_NO_SIZETYPEDEFINE | |
/*! \def RAPIDJSON_NO_SIZETYPEDEFINE | |
\ingroup RAPIDJSON_CONFIG | |
\brief User-provided \c SizeType definition. | |
In order to avoid using 32-bit size types for indexing strings and arrays, | |
define this preprocessor symbol and provide the type rapidjson::SizeType | |
before including RapidJSON: | |
\code | |
#define RAPIDJSON_NO_SIZETYPEDEFINE | |
namespace rapidjson { typedef ::std::size_t SizeType; } | |
#include "rapidjson/..." | |
\endcode | |
\see rapidjson::SizeType | |
*/ | |
#ifdef RAPIDJSON_DOXYGEN_RUNNING | |
#define RAPIDJSON_NO_SIZETYPEDEFINE | |
#endif | |
RAPIDJSON_NAMESPACE_BEGIN | |
//! Size type (for string lengths, array sizes, etc.) | |
/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms, | |
instead of using \c size_t. Users may override the SizeType by defining | |
\ref RAPIDJSON_NO_SIZETYPEDEFINE. | |
*/ | |
typedef unsigned SizeType; | |
RAPIDJSON_NAMESPACE_END | |
#endif | |
// always import std::size_t to rapidjson namespace | |
RAPIDJSON_NAMESPACE_BEGIN | |
using std::size_t; | |
RAPIDJSON_NAMESPACE_END | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_ASSERT | |
//! Assertion. | |
/*! \ingroup RAPIDJSON_CONFIG | |
By default, rapidjson uses C \c assert() for internal assertions. | |
User can override it by defining RAPIDJSON_ASSERT(x) macro. | |
\note Parsing errors are handled and can be customized by the | |
\ref RAPIDJSON_ERRORS APIs. | |
*/ | |
#ifndef RAPIDJSON_ASSERT | |
#include <cassert> | |
#define RAPIDJSON_ASSERT(x) assert(x) | |
#endif // RAPIDJSON_ASSERT | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_STATIC_ASSERT | |
// Prefer C++11 static_assert, if available | |
#ifndef RAPIDJSON_STATIC_ASSERT | |
#if __cplusplus >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 ) | |
#define RAPIDJSON_STATIC_ASSERT(x) \ | |
static_assert(x, RAPIDJSON_STRINGIFY(x)) | |
#endif // C++11 | |
#endif // RAPIDJSON_STATIC_ASSERT | |
// Adopt C++03 implementation from boost | |
#ifndef RAPIDJSON_STATIC_ASSERT | |
#ifndef __clang__ | |
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN | |
#endif | |
RAPIDJSON_NAMESPACE_BEGIN | |
template <bool x> struct STATIC_ASSERTION_FAILURE; | |
template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; }; | |
template <size_t x> struct StaticAssertTest {}; | |
RAPIDJSON_NAMESPACE_END | |
#if defined(__GNUC__) || defined(__clang__) | |
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) | |
#else | |
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE | |
#endif | |
#ifndef __clang__ | |
//!@endcond | |
#endif | |
/*! \def RAPIDJSON_STATIC_ASSERT | |
\brief (Internal) macro to check for conditions at compile-time | |
\param x compile-time condition | |
\hideinitializer | |
*/ | |
#define RAPIDJSON_STATIC_ASSERT(x) \ | |
typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \ | |
sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x) >)> \ | |
RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE | |
#endif // RAPIDJSON_STATIC_ASSERT | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY | |
//! Compiler branching hint for expression with high probability to be true. | |
/*! | |
\ingroup RAPIDJSON_CONFIG | |
\param x Boolean expression likely to be true. | |
*/ | |
#ifndef RAPIDJSON_LIKELY | |
#if defined(__GNUC__) || defined(__clang__) | |
#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1) | |
#else | |
#define RAPIDJSON_LIKELY(x) (x) | |
#endif | |
#endif | |
//! Compiler branching hint for expression with low probability to be true. | |
/*! | |
\ingroup RAPIDJSON_CONFIG | |
\param x Boolean expression unlikely to be true. | |
*/ | |
#ifndef RAPIDJSON_UNLIKELY | |
#if defined(__GNUC__) || defined(__clang__) | |
#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0) | |
#else | |
#define RAPIDJSON_UNLIKELY(x) (x) | |
#endif | |
#endif | |
/////////////////////////////////////////////////////////////////////////////// | |
// Helpers | |
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN | |
#define RAPIDJSON_MULTILINEMACRO_BEGIN do { | |
#define RAPIDJSON_MULTILINEMACRO_END \ | |
} while((void)0, 0) | |
// adopted from Boost | |
#define RAPIDJSON_VERSION_CODE(x,y,z) \ | |
(((x)*100000) + ((y)*100) + (z)) | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF | |
#if defined(__GNUC__) | |
#define RAPIDJSON_GNUC \ | |
RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) | |
#endif | |
#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0)) | |
#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x)) | |
#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x) | |
#define RAPIDJSON_DIAG_OFF(x) \ | |
RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x))) | |
// push/pop support in Clang and GCC>=4.6 | |
#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) | |
#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) | |
#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) | |
#else // GCC >= 4.2, < 4.6 | |
#define RAPIDJSON_DIAG_PUSH /* ignored */ | |
#define RAPIDJSON_DIAG_POP /* ignored */ | |
#endif | |
#elif defined(_MSC_VER) | |
// pragma (MSVC specific) | |
#define RAPIDJSON_PRAGMA(x) __pragma(x) | |
#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x)) | |
#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x) | |
#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) | |
#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) | |
#else | |
#define RAPIDJSON_DIAG_OFF(x) /* ignored */ | |
#define RAPIDJSON_DIAG_PUSH /* ignored */ | |
#define RAPIDJSON_DIAG_POP /* ignored */ | |
#endif // RAPIDJSON_DIAG_* | |
/////////////////////////////////////////////////////////////////////////////// | |
// C++11 features | |
#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS | |
#if defined(__clang__) | |
#if __has_feature(cxx_rvalue_references) && \ | |
(defined(_MSC_VER) || defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306) | |
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 | |
#else | |
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 | |
#endif | |
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ | |
(defined(_MSC_VER) && _MSC_VER >= 1600) || \ | |
(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) | |
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 | |
#else | |
#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 | |
#endif | |
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS | |
#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT | |
#if defined(__clang__) | |
#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept) | |
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ | |
(defined(_MSC_VER) && _MSC_VER >= 1900) || \ | |
(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) | |
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 | |
#else | |
#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0 | |
#endif | |
#endif | |
#if RAPIDJSON_HAS_CXX11_NOEXCEPT | |
#define RAPIDJSON_NOEXCEPT noexcept | |
#else | |
#define RAPIDJSON_NOEXCEPT /* noexcept */ | |
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT | |
// no automatic detection, yet | |
#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS | |
#if (defined(_MSC_VER) && _MSC_VER >= 1700) | |
#define RAPIDJSON_HAS_CXX11_TYPETRAITS 1 | |
#else | |
#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0 | |
#endif | |
#endif | |
#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR | |
#if defined(__clang__) | |
#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for) | |
#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ | |
(defined(_MSC_VER) && _MSC_VER >= 1700) || \ | |
(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) | |
#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1 | |
#else | |
#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0 | |
#endif | |
#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR | |
//!@endcond | |
//! Assertion (in non-throwing contexts). | |
/*! \ingroup RAPIDJSON_CONFIG | |
Some functions provide a \c noexcept guarantee, if the compiler supports it. | |
In these cases, the \ref RAPIDJSON_ASSERT macro cannot be overridden to | |
throw an exception. This macro adds a separate customization point for | |
such cases. | |
Defaults to C \c assert() (as \ref RAPIDJSON_ASSERT), if \c noexcept is | |
supported, and to \ref RAPIDJSON_ASSERT otherwise. | |
*/ | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_NOEXCEPT_ASSERT | |
#ifndef RAPIDJSON_NOEXCEPT_ASSERT | |
#ifdef RAPIDJSON_ASSERT_THROWS | |
#if RAPIDJSON_HAS_CXX11_NOEXCEPT | |
#define RAPIDJSON_NOEXCEPT_ASSERT(x) | |
#else | |
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x) | |
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT | |
#else | |
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x) | |
#endif // RAPIDJSON_ASSERT_THROWS | |
#endif // RAPIDJSON_NOEXCEPT_ASSERT | |
/////////////////////////////////////////////////////////////////////////////// | |
// new/delete | |
#ifndef RAPIDJSON_NEW | |
///! customization point for global \c new | |
#define RAPIDJSON_NEW(TypeName) new TypeName | |
#endif | |
#ifndef RAPIDJSON_DELETE | |
///! customization point for global \c delete | |
#define RAPIDJSON_DELETE(x) delete x | |
#endif | |
/////////////////////////////////////////////////////////////////////////////// | |
// Type | |
/*! \namespace rapidjson | |
\brief main RapidJSON namespace | |
\see RAPIDJSON_NAMESPACE | |
*/ | |
RAPIDJSON_NAMESPACE_BEGIN | |
//! 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 | |
}; | |
RAPIDJSON_NAMESPACE_END | |
#endif // RAPIDJSON_RAPIDJSON_H_ | |
// End file:rapidjson.h | |
// Begin file: allocators.h | |
// Tencent is pleased to support the open source community by making RapidJSON available. | |
// | |
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. | |
// | |
// Licensed under the MIT License (the "License"); you may not use this file except | |
// in compliance with the License. You may obtain a copy of the License at | |
// | |
// http://opensource.org/licenses/MIT | |
// | |
// Unless required by applicable law or agreed to in writing, software distributed | |
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |
// CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
// specific language governing permissions and limitations under the License. | |
#ifndef RAPIDJSON_ALLOCATORS_H_ | |
#define RAPIDJSON_ALLOCATORS_H_ | |
// Begin file: rapidjson.h | |
// already included | |
// End file:rapidjson.h | |
RAPIDJSON_NAMESPACE_BEGIN | |
/////////////////////////////////////////////////////////////////////////////// | |
// Allocator | |
/*! \class rapidjson::Allocator | |
\brief Concept for allocating, resizing and freeing memory block. | |
Note that Malloc() and Realloc() are non-static but Free() is static. | |
So if an allocator need to support Free(), it needs to put its pointer in | |
the header of memory block. | |
\code | |
concept Allocator { | |
static const bool kNeedFree; //!< Whether this allocator needs to call Free(). | |
// Allocate a memory block. | |
// \param size of the memory block in bytes. | |
// \returns pointer to the memory block. | |
void* Malloc(size_t size); | |
// Resize a memory block. | |
// \param originalPtr The pointer to current memory block. Null pointer is permitted. | |
// \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) | |
// \param newSize the new size in bytes. | |
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); | |
// Free a memory block. | |
// \param pointer to the memory block. Null pointer is permitted. | |
static void Free(void *ptr); | |
}; | |
\endcode | |
*/ | |
/*! \def RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY | |
\ingroup RAPIDJSON_CONFIG | |
\brief User-defined kDefaultChunkCapacity definition. | |
User can define this as any \c size that is a power of 2. | |
*/ | |
#ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY | |
#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024) | |
#endif | |
/////////////////////////////////////////////////////////////////////////////// | |
// CrtAllocator | |
//! C-runtime library allocator. | |
/*! This class is just wrapper for standard C library memory routines. | |
\note implements Allocator concept | |
*/ | |
class CrtAllocator { | |
public: | |
static const bool kNeedFree = true; | |
void* Malloc(size_t size) { | |
if (size) // behavior of malloc(0) is implementation defined. | |
return std::malloc(size); | |
else | |
return NULL; // standardize to returning NULL. | |
} | |
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { | |
(void)originalSize; | |
if (newSize == 0) { | |
std::free(originalPtr); | |
return NULL; | |
} | |
return std::realloc(originalPtr, newSize); | |
} | |
static void Free(void *ptr) { std::free(ptr); } | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// MemoryPoolAllocator | |
//! Default memory allocator used by the parser and DOM. | |
/*! This allocator allocate memory blocks from pre-allocated memory chunks. | |
It does not free memory blocks. And Realloc() only allocate new memory. | |
The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default. | |
User may also supply a buffer as the first chunk. | |
If the user-buffer is full then additional chunks are allocated by BaseAllocator. | |
The user-buffer is not deallocated by this allocator. | |
\tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. | |
\note implements Allocator concept | |
*/ | |
template <typename BaseAllocator = CrtAllocator> | |
class MemoryPoolAllocator { | |
public: | |
static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) | |
//! Constructor with chunkSize. | |
/*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. | |
\param baseAllocator The allocator for allocating memory chunks. | |
*/ | |
MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : | |
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0) | |
{ | |
} | |
//! Constructor with user-supplied buffer. | |
/*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. | |
The user buffer will not be deallocated when this allocator is destructed. | |
\param buffer User supplied buffer. | |
\param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). | |
\param chunkSize The size of memory chunk. The default is kDefaultChunkSize. | |
\param baseAllocator The allocator for allocating memory chunks. | |
*/ | |
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : | |
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0) | |
{ | |
RAPIDJSON_ASSERT(buffer != 0); | |
RAPIDJSON_ASSERT(size > sizeof(ChunkHeader)); | |
chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer); | |
chunkHead_->capacity = size - sizeof(ChunkHeader); | |
chunkHead_->size = 0; | |
chunkHead_->next = 0; | |
} | |
//! Destructor. | |
/*! This deallocates all memory chunks, excluding the user-supplied buffer. | |
*/ | |
~MemoryPoolAllocator() { | |
Clear(); | |
RAPIDJSON_DELETE(ownBaseAllocator_); | |
} | |
//! Deallocates all memory chunks, excluding the user-supplied buffer. | |
void Clear() { | |
while (chunkHead_ && chunkHead_ != userBuffer_) { | |
ChunkHeader* next = chunkHead_->next; | |
baseAllocator_->Free(chunkHead_); | |
chunkHead_ = next; | |
} | |
if (chunkHead_ && chunkHead_ == userBuffer_) | |
chunkHead_->size = 0; // Clear user buffer | |
} | |
//! Computes the total capacity of allocated memory chunks. | |
/*! \return total capacity in bytes. | |
*/ | |
size_t Capacity() const { | |
size_t capacity = 0; | |
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) | |
capacity += c->capacity; | |
return capacity; | |
} | |
//! Computes the memory blocks allocated. | |
/*! \return total used bytes. | |
*/ | |
size_t Size() const { | |
size_t size = 0; | |
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) | |
size += c->size; | |
return size; | |
} | |
//! Allocates a memory block. (concept Allocator) | |
void* Malloc(size_t size) { | |
if (!size) | |
return NULL; | |
size = RAPIDJSON_ALIGN(size); | |
if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity) | |
if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size)) | |
return NULL; | |
void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size; | |
chunkHead_->size += size; | |
return buffer; | |
} | |
//! Resizes a memory block (concept Allocator) | |
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { | |
if (originalPtr == 0) | |
return Malloc(newSize); | |
if (newSize == 0) | |
return NULL; | |
originalSize = RAPIDJSON_ALIGN(originalSize); | |
newSize = RAPIDJSON_ALIGN(newSize); | |
// Do not shrink if new size is smaller than original | |
if (originalSize >= newSize) | |
return originalPtr; | |
// Simply expand it if it is the last allocation and there is sufficient space | |
if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) { | |
size_t increment = static_cast<size_t>(newSize - originalSize); | |
if (chunkHead_->size + increment <= chunkHead_->capacity) { | |
chunkHead_->size += increment; | |
return originalPtr; | |
} | |
} | |
// Realloc process: allocate and copy memory, do not free original buffer. | |
if (void* newBuffer = Malloc(newSize)) { | |
if (originalSize) | |
std::memcpy(newBuffer, originalPtr, originalSize); | |
return newBuffer; | |
} | |
else | |
return NULL; | |
} | |
//! Frees a memory block (concept Allocator) | |
static void Free(void *ptr) { (void)ptr; } // Do nothing | |
private: | |
//! Copy constructor is not permitted. | |
MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */; | |
//! Copy assignment operator is not permitted. | |
MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */; | |
//! Creates a new chunk. | |
/*! \param capacity Capacity of the chunk in bytes. | |
\return true if success. | |
*/ | |
bool AddChunk(size_t capacity) { | |
if (!baseAllocator_) | |
ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)(); | |
if (ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) { | |
chunk->capacity = capacity; | |
chunk->size = 0; | |
chunk->next = chunkHead_; | |
chunkHead_ = chunk; | |
return true; | |
} | |
else | |
return false; | |
} | |
static const int kDefaultChunkCapacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY; //!< Default chunk capacity. | |
//! Chunk header for perpending to each chunk. | |
/*! Chunks are stored as a singly linked list. | |
*/ | |
struct ChunkHeader { | |
size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). | |
size_t size; //!< Current size of allocated memory in bytes. | |
ChunkHeader *next; //!< Next chunk in the linked list. | |
}; | |
ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation. | |
size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. | |
void *userBuffer_; //!< User supplied buffer. | |
BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. | |
BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object. | |
}; | |
RAPIDJSON_NAMESPACE_END | |
#endif // RAPIDJSON_ENCODINGS_H_ | |
// End file:allocators.h | |
// Begin file: error/en.h | |
// Tencent is pleased to support the open source community by making RapidJSON available. | |
// | |
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. | |
// | |
// Licensed under the MIT License (the "License"); you may not use this file except | |
// in compliance with the License. You may obtain a copy of the License at | |
// | |
// http://opensource.org/licenses/MIT | |
// | |
// Unless required by applicable law or agreed to in writing, software distributed | |
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |
// CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
// specific language governing permissions and limitations under the License. | |
#ifndef RAPIDJSON_ERROR_EN_H_ | |
#define RAPIDJSON_ERROR_EN_H_ | |
// Begin file: error.h | |
// Tencent is pleased to support the open source community by making RapidJSON available. | |
// | |
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. | |
// | |
// Licensed under the MIT License (the "License"); you may not use this file except | |
// in compliance with the License. You may obtain a copy of the License at | |
// | |
// http://opensource.org/licenses/MIT | |
// | |
// Unless required by applicable law or agreed to in writing, software distributed | |
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |
// CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
// specific language governing permissions and limitations under the License. | |
#ifndef RAPIDJSON_ERROR_ERROR_H_ | |
#define RAPIDJSON_ERROR_ERROR_H_ | |
// Begin file: ../rapidjson.h | |
// already included | |
// End file:../rapidjson.h | |
#ifdef __clang__ | |
RAPIDJSON_DIAG_PUSH | |
RAPIDJSON_DIAG_OFF(padded) | |
#endif | |
/*! \file error.h */ | |
/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_ERROR_CHARTYPE | |
//! Character type of error messages. | |
/*! \ingroup RAPIDJSON_ERRORS | |
The default character type is \c char. | |
On Windows, user can define this macro as \c TCHAR for supporting both | |
unicode/non-unicode settings. | |
*/ | |
#ifndef RAPIDJSON_ERROR_CHARTYPE | |
#define RAPIDJSON_ERROR_CHARTYPE char | |
#endif | |
/////////////////////////////////////////////////////////////////////////////// | |
// RAPIDJSON_ERROR_STRING | |
//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[]. | |
/*! \ingroup RAPIDJSON_ERRORS | |
By default this conversion macro does nothing. | |
On Windows, user can define this macro as \c _T(x) for supporting both | |
unicode/non-unicode settings. | |
*/ | |
#ifndef RAPIDJSON_ERROR_STRING | |
#define RAPIDJSON_ERROR_STRING(x) x | |
#endif | |
RAPIDJSON_NAMESPACE_BEGIN | |
/////////////////////////////////////////////////////////////////////////////// | |
// ParseErrorCode | |
//! Error code of parsing. | |
/*! \ingroup RAPIDJSON_ERRORS | |
\see GenericReader::Parse, GenericReader::GetParseErrorCode | |
*/ | |
enum ParseErrorCode { | |
kParseErrorNone = 0, //!< No error. | |
kParseErrorDocumentEmpty, //!< The document is empty. | |
kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. | |
kParseErrorValueInvalid, //!< Invalid value. | |
kParseErrorObjectMissName, //!< Missing a name for object member. | |
kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. | |
kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. | |
kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. | |
kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. | |
kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. | |
kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. | |
kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. | |
kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. | |
kParseErrorNumberTooBig, //!< Number too big to be stored in double. | |
kParseErrorNumberMissFraction, //!< Miss fraction part in number. | |
kParseErrorNumberMissExponent, //!< Miss exponent in number. | |
kParseErrorTermination, //!< Parsing was terminated. | |
kParseErrorUnspecificSyntaxError //!< Unspecific syntax error. | |
}; | |
//! Result of parsing (wraps ParseErrorCode) | |
/*! | |
\ingroup RAPIDJSON_ERRORS | |
\code | |
Document doc; | |
ParseResult ok = doc.Parse("[42]"); | |
if (!ok) { | |
fprintf(stderr, "JSON parse error: %s (%u)", | |
GetParseError_En(ok.Code()), ok.Offset()); | |
exit(EXIT_FAILURE); | |
} | |
\endcode | |
\see GenericReader::Parse, GenericDocument::Parse | |
*/ | |
struct ParseResult { | |
//!! Unspecified boolean type | |
typedef bool (ParseResult::*BooleanType)() const; | |
public: | |
//! Default constructor, no error. | |
ParseResult() : code_(kParseErrorNone), offset_(0) {} | |
//! Constructor to set an error. | |
ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} | |
//! Get the error code. | |
ParseErrorCode Code() const { return code_; } | |
//! Get the error offset, if \ref IsError(), 0 otherwise. | |
size_t Offset() const { return offset_; } | |
//! Explicit conversion to \c bool, returns \c true, iff !\ref IsError(). | |
operator BooleanType() const { return !IsError() ? &ParseResult::IsError : NULL; } | |
//! Whether the result is an error. | |
bool IsError() const { return code_ != kParseErrorNone; } | |
bool operator==(const ParseResult& that) const { return code_ == that.code_; } | |
bool operator==(ParseErrorCode code) const { return code_ == code; } | |
friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } | |
bool operator!=(const ParseResult& that) const { return !(*this == that); } | |
bool operator!=(ParseErrorCode code) const { return !(*this == code); } | |
friend bool operator!=(ParseErrorCode code, const ParseResult & err) { return err != code; } | |
//! Reset error code. | |
void Clear() { Set(kParseErrorNone); } | |
//! Update error code and offset. | |
void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } | |
private: | |
ParseErrorCode code_; | |
size_t offset_; | |
}; | |
//! Function pointer type of GetParseError(). | |
/*! \ingroup RAPIDJSON_ERRORS | |
This is the prototype for \c GetParseError_X(), where \c X is a locale. | |
User can dynamically change locale in runtime, e.g.: | |
\code | |
GetParseErrorFunc GetParseError = GetParseError_En; // or whatever | |
const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); | |
\endcode | |
*/ | |
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode); | |
RAPIDJSON_NAMESPACE_END | |
#ifdef __clang__ | |
RAPIDJSON_DIAG_POP | |
#endif | |
#endif // RAPIDJSON_ERROR_ERROR_H_ | |
// End file:error.h | |
#ifdef __clang__ | |
RAPIDJSON_DIAG_PUSH | |
RAPIDJSON_DIAG_OFF(switch-enum) | |
RAPIDJSON_DIAG_OFF(covered-switch-default) | |
#endif | |
RAPIDJSON_NAMESPACE_BEGIN | |
//! Maps error code of parsing into error message. | |
/*! | |
\ingroup RAPIDJSON_ERRORS | |
\param parseErrorCode Error code obtained in parsing. | |
\return the error message. | |
\note User can make a copy of this function for localization. | |
Using switch-case is safer for future modification of error codes. | |
*/ | |
inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { | |
switch (parseErrorCode) { | |
case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); | |
case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); | |
case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values."); | |
case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); | |
case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); | |
case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); | |
case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); | |
case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); | |
case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); | |
case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); | |
case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); | |
case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); | |
case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); | |
case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); | |
case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); | |
case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); | |
case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); | |
case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); | |
default: return RAPIDJSON_ERROR_STRING("Unknown error."); | |
} | |
} | |
RAPIDJSON_NAMESPACE_END | |
#ifdef __clang__ | |
RAPIDJSON_DIAG_POP | |
#endif | |
#endif // RAPIDJSON_ERROR_EN_H_ | |
// End file:error/en.h | |
// Begin file: cursorstreamwrapper.h | |
// Tencent is pleased to support the open source community by making RapidJSON available. | |
// | |
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. | |
// | |
// Licensed under the MIT License (the "License"); you may not use this file except | |
// in compliance with the License. You may obtain a copy of the License at | |
// | |
// http://opensource.org/licenses/MIT | |
// | |
// Unless required by applicable law or agreed to in writing, software distributed | |
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |
// CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
// specific language governing permissions and limitations under the License. | |
#ifndef RAPIDJSON_CURSORSTREAMWRAPPER_H_ | |
#define RAPIDJSON_CURSORSTREAMWRAPPER_H_ | |
// Begin file: stream.h | |
// Tencent is pleased to support the open source community by making RapidJSON available. | |
// | |
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. | |
// | |
// Licensed under the MIT License (the "License"); you may not use this file except | |
// in compliance with the License. You may obtain a copy of the License at | |
// | |
// http://opensource.org/licenses/MIT | |
// | |
// Unless required by applicable law or agreed to in writing, software distributed | |
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |
// CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
// specific language governing permissions and limitations under the License. | |
// Begin file: rapidjson.h | |
// already included | |
// End file:rapidjson.h | |
#ifndef RAPIDJSON_STREAM_H_ | |
#define RAPIDJSON_STREAM_H_ | |
// Begin file: encodings.h | |
// Tencent is pleased to support the open source community by making RapidJSON available. | |
// | |
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. | |
// | |
// Licensed under the MIT License (the "License"); you may not use this file except | |
// in compliance with the License. You may obtain a copy of the License at | |
// | |
// http://opensource.org/licenses/MIT | |
// | |
// Unless required by applicable law or agreed to in writing, software distributed | |
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |
// CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
// specific language governing permissions and limitations under the License. | |
#ifndef RAPIDJSON_ENCODINGS_H_ | |
#define RAPIDJSON_ENCODINGS_H_ | |
// Begin file: rapidjson.h | |
// already included | |
// End file:rapidjson.h | |
#if defined(_MSC_VER) && !defined(__clang__) | |
RAPIDJSON_DIAG_PUSH | |
RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data | |
RAPIDJSON_DIAG_OFF(4702) // unreachable code | |
#elif defined(__GNUC__) | |
RAPIDJSON_DIAG_PUSH | |
RAPIDJSON_DIAG_OFF(effc++) | |
RAPIDJSON_DIAG_OFF(overflow) | |
#endif | |
RAPIDJSON_NAMESPACE_BEGIN | |
/////////////////////////////////////////////////////////////////////////////// | |
// Encoding | |
/*! \class rapidjson::Encoding | |
\brief Concept for encoding of Unicode characters. | |
\code | |
concept Encoding { | |
typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition. | |
enum { supportUnicode = 1 }; // or 0 if not supporting unicode | |
//! \brief Encode a Unicode codepoint to an output stream. | |
//! \param os Output stream. | |
//! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. | |
template<typename OutputStream> | |
static void Encode(OutputStream& os, unsigned codepoint); | |
//! \brief Decode a Unicode codepoint from an input stream. | |
//! \param is Input stream. | |
//! \param codepoint Output of the unicode codepoint. | |
//! \return true if a valid codepoint can be decoded from the stream. | |
template <typename InputStream> | |
static bool Decode(InputStream& is, unsigned* codepoint); | |
//! \brief Validate one Unicode codepoint from an encoded stream. | |
//! \param is Input stream to obtain codepoint. | |
//! \param os Output for copying one codepoint. | |
//! \return true if it is valid. | |
//! \note This function just validating and copying the codepoint without actually decode it. | |
template <typename InputStream, typename OutputStream> | |
static bool Validate(InputStream& is, OutputStream& os); | |
// The following functions are deal with byte streams. | |
//! Take a character from input byte stream, skip BOM if exist. | |
template <typename InputByteStream> | |
static CharType TakeBOM(InputByteStream& is); | |
//! Take a character from input byte stream. | |
template <typename InputByteStream> | |
static Ch Take(InputByteStream& is); | |
//! Put BOM to output byte stream. | |
template <typename OutputByteStream> | |
static void PutBOM(OutputByteStream& os); | |
//! Put a character to output byte stream. | |
template <typename OutputByteStream> | |
static void Put(OutputByteStream& os, Ch c); | |
}; | |
\endcode | |
*/ | |
/////////////////////////////////////////////////////////////////////////////// | |
// UTF8 | |
//! UTF-8 encoding. | |
/*! http://en.wikipedia.org/wiki/UTF-8 | |
http://tools.ietf.org/html/rfc3629 | |
\tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char. | |
\note implements Encoding concept | |
*/ | |
template<typename CharType = char> | |
struct UTF8 { | |
typedef CharType Ch; | |
enum { supportUnicode = 1 }; | |
template<typename OutputStream> | |
static void Encode(OutputStream& os, unsigned codepoint) { | |
if (codepoint <= 0x7F) | |
os.Put(static_cast<Ch>(codepoint & 0xFF)); | |
else if (codepoint <= 0x7FF) { | |
os.Put(static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF))); | |
os.Put(static_cast<Ch>(0x80 | ((codepoint & 0x3F)))); | |
} | |
else if (codepoint <= 0xFFFF) { | |
os.Put(static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF))); | |
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); | |
os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F))); | |
} | |
else { | |
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); | |
os.Put(static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF))); | |
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F))); | |
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); | |
os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F))); | |
} | |
} | |
template<typename OutputStream> | |
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { | |
if (codepoint <= 0x7F) | |
PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF)); | |
else if (codepoint <= 0x7FF) { | |
PutUnsafe(os, static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF))); | |
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint & 0x3F)))); | |
} | |
else if (codepoint <= 0xFFFF) { | |
PutUnsafe(os, static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF))); | |
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); | |
PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F))); | |
} | |
else { | |
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); | |
PutUnsafe(os, static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF))); | |
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F))); | |
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F))); | |
PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F))); | |
} | |
} | |
template <typename InputStream> | |
static bool Decode(InputStream& is, unsigned* codepoint) { | |
#define RAPIDJSON_COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu) | |
#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0) | |
#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70) | |
typename InputStream::Ch c = is.Take(); | |
if (!(c & 0x80)) { | |
*codepoint = static_cast<unsigned char>(c); | |
return true; | |
} | |
unsigned char type = GetRange(static_cast<unsigned char>(c)); | |
if (type >= 32) { | |
*codepoint = 0; | |
} else { | |
*codepoint = (0xFFu >> type) & static_cast<unsigned char>(c); | |
} | |
bool result = true; | |
switch (type) { | |
case 2: RAPIDJSON_TAIL(); return result; | |
case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; | |
case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result; | |
case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; | |
case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; | |
case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result; | |
case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; | |
default: return false; | |
} | |
#undef RAPIDJSON_COPY | |
#undef RAPIDJSON_TRANS | |
#undef RAPIDJSON_TAIL | |
} | |
template <typename InputStream, typename OutputStream> | |
static bool Validate(InputStream& is, OutputStream& os) { | |
#define RAPIDJSON_COPY() os.Put(c = is.Take()) | |
#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0) | |
#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70) | |
Ch c; | |
RAPIDJSON_COPY(); | |
if (!(c & 0x80)) | |
return true; | |
bool result = true; | |
switch (GetRange(static_cast<unsigned char>(c))) { | |
case 2: RAPIDJSON_TAIL(); return result; | |
case 3: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; | |
case 4: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x50); RAPIDJSON_TAIL(); return result; | |
case 5: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x10); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; | |
case 6: RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; | |
case 10: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x20); RAPIDJSON_TAIL(); return result; | |
case 11: RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x60); RAPIDJSON_TAIL(); RAPIDJSON_TAIL(); return result; | |
default: return false; | |
} | |
#undef RAPIDJSON_COPY | |
#undef RAPIDJSON_TRANS | |
#undef RAPIDJSON_TAIL | |
} | |
static unsigned char GetRange(unsigned char c) { | |
// Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ | |
// With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types. | |
static const unsigned char type[] = { | |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, | |
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, | |
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, | |
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, | |
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, | |
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, | |
}; | |
return type[c]; | |
} | |
template <typename InputByteStream> | |
static CharType TakeBOM(InputByteStream& is) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | |
typename InputByteStream::Ch c = Take(is); | |
if (static_cast<unsigned char>(c) != 0xEFu) return c; | |
c = is.Take(); | |
if (static_cast<unsigned char>(c) != 0xBBu) return c; | |
c = is.Take(); | |
if (static_cast<unsigned char>(c) != 0xBFu) return c; | |
c = is.Take(); | |
return c; | |
} | |
template <typename InputByteStream> | |
static Ch Take(InputByteStream& is) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | |
return static_cast<Ch>(is.Take()); | |
} | |
template <typename OutputByteStream> | |
static void PutBOM(OutputByteStream& os) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0xEFu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0xBBu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0xBFu)); | |
} | |
template <typename OutputByteStream> | |
static void Put(OutputByteStream& os, Ch c) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |
os.Put(static_cast<typename OutputByteStream::Ch>(c)); | |
} | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// UTF16 | |
//! UTF-16 encoding. | |
/*! http://en.wikipedia.org/wiki/UTF-16 | |
http://tools.ietf.org/html/rfc2781 | |
\tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. | |
\note implements Encoding concept | |
\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. | |
For streaming, use UTF16LE and UTF16BE, which handle endianness. | |
*/ | |
template<typename CharType = wchar_t> | |
struct UTF16 { | |
typedef CharType Ch; | |
RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2); | |
enum { supportUnicode = 1 }; | |
template<typename OutputStream> | |
static void Encode(OutputStream& os, unsigned codepoint) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); | |
if (codepoint <= 0xFFFF) { | |
RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair | |
os.Put(static_cast<typename OutputStream::Ch>(codepoint)); | |
} | |
else { | |
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); | |
unsigned v = codepoint - 0x10000; | |
os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800)); | |
os.Put(static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00)); | |
} | |
} | |
template<typename OutputStream> | |
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); | |
if (codepoint <= 0xFFFF) { | |
RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair | |
PutUnsafe(os, static_cast<typename OutputStream::Ch>(codepoint)); | |
} | |
else { | |
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); | |
unsigned v = codepoint - 0x10000; | |
PutUnsafe(os, static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800)); | |
PutUnsafe(os, static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00)); | |
} | |
} | |
template <typename InputStream> | |
static bool Decode(InputStream& is, unsigned* codepoint) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); | |
typename InputStream::Ch c = is.Take(); | |
if (c < 0xD800 || c > 0xDFFF) { | |
*codepoint = static_cast<unsigned>(c); | |
return true; | |
} | |
else if (c <= 0xDBFF) { | |
*codepoint = (static_cast<unsigned>(c) & 0x3FF) << 10; | |
c = is.Take(); | |
*codepoint |= (static_cast<unsigned>(c) & 0x3FF); | |
*codepoint += 0x10000; | |
return c >= 0xDC00 && c <= 0xDFFF; | |
} | |
return false; | |
} | |
template <typename InputStream, typename OutputStream> | |
static bool Validate(InputStream& is, OutputStream& os) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); | |
typename InputStream::Ch c; | |
os.Put(static_cast<typename OutputStream::Ch>(c = is.Take())); | |
if (c < 0xD800 || c > 0xDFFF) | |
return true; | |
else if (c <= 0xDBFF) { | |
os.Put(c = is.Take()); | |
return c >= 0xDC00 && c <= 0xDFFF; | |
} | |
return false; | |
} | |
}; | |
//! UTF-16 little endian encoding. | |
template<typename CharType = wchar_t> | |
struct UTF16LE : UTF16<CharType> { | |
template <typename InputByteStream> | |
static CharType TakeBOM(InputByteStream& is) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | |
CharType c = Take(is); | |
return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c; | |
} | |
template <typename InputByteStream> | |
static CharType Take(InputByteStream& is) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | |
unsigned c = static_cast<uint8_t>(is.Take()); | |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8; | |
return static_cast<CharType>(c); | |
} | |
template <typename OutputByteStream> | |
static void PutBOM(OutputByteStream& os) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu)); | |
} | |
template <typename OutputByteStream> | |
static void Put(OutputByteStream& os, CharType c) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |
os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu)); | |
} | |
}; | |
//! UTF-16 big endian encoding. | |
template<typename CharType = wchar_t> | |
struct UTF16BE : UTF16<CharType> { | |
template <typename InputByteStream> | |
static CharType TakeBOM(InputByteStream& is) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | |
CharType c = Take(is); | |
return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c; | |
} | |
template <typename InputByteStream> | |
static CharType Take(InputByteStream& is) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | |
unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8; | |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())); | |
return static_cast<CharType>(c); | |
} | |
template <typename OutputByteStream> | |
static void PutBOM(OutputByteStream& os) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu)); | |
} | |
template <typename OutputByteStream> | |
static void Put(OutputByteStream& os, CharType c) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |
os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu)); | |
} | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// UTF32 | |
//! UTF-32 encoding. | |
/*! http://en.wikipedia.org/wiki/UTF-32 | |
\tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. | |
\note implements Encoding concept | |
\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. | |
For streaming, use UTF32LE and UTF32BE, which handle endianness. | |
*/ | |
template<typename CharType = unsigned> | |
struct UTF32 { | |
typedef CharType Ch; | |
RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4); | |
enum { supportUnicode = 1 }; | |
template<typename OutputStream> | |
static void Encode(OutputStream& os, unsigned codepoint) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); | |
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); | |
os.Put(codepoint); | |
} | |
template<typename OutputStream> | |
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); | |
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); | |
PutUnsafe(os, codepoint); | |
} | |
template <typename InputStream> | |
static bool Decode(InputStream& is, unsigned* codepoint) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); | |
Ch c = is.Take(); | |
*codepoint = c; | |
return c <= 0x10FFFF; | |
} | |
template <typename InputStream, typename OutputStream> | |
static bool Validate(InputStream& is, OutputStream& os) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); | |
Ch c; | |
os.Put(c = is.Take()); | |
return c <= 0x10FFFF; | |
} | |
}; | |
//! UTF-32 little endian enocoding. | |
template<typename CharType = unsigned> | |
struct UTF32LE : UTF32<CharType> { | |
template <typename InputByteStream> | |
static CharType TakeBOM(InputByteStream& is) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | |
CharType c = Take(is); | |
return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c; | |
} | |
template <typename InputByteStream> | |
static CharType Take(InputByteStream& is) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | |
unsigned c = static_cast<uint8_t>(is.Take()); | |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8; | |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16; | |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24; | |
return static_cast<CharType>(c); | |
} | |
template <typename OutputByteStream> | |
static void PutBOM(OutputByteStream& os) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u)); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u)); | |
} | |
template <typename OutputByteStream> | |
static void Put(OutputByteStream& os, CharType c) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |
os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu)); | |
} | |
}; | |
//! UTF-32 big endian encoding. | |
template<typename CharType = unsigned> | |
struct UTF32BE : UTF32<CharType> { | |
template <typename InputByteStream> | |
static CharType TakeBOM(InputByteStream& is) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | |
CharType c = Take(is); | |
return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c; | |
} | |
template <typename InputByteStream> | |
static CharType Take(InputByteStream& is) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | |
unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24; | |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16; | |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8; | |
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())); | |
return static_cast<CharType>(c); | |
} | |
template <typename OutputByteStream> | |
static void PutBOM(OutputByteStream& os) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u)); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u)); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu)); | |
} | |
template <typename OutputByteStream> | |
static void Put(OutputByteStream& os, CharType c) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu)); | |
os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu)); | |
} | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// ASCII | |
//! ASCII encoding. | |
/*! http://en.wikipedia.org/wiki/ASCII | |
\tparam CharType Code unit for storing 7-bit ASCII data. Default is char. | |
\note implements Encoding concept | |
*/ | |
template<typename CharType = char> | |
struct ASCII { | |
typedef CharType Ch; | |
enum { supportUnicode = 0 }; | |
template<typename OutputStream> | |
static void Encode(OutputStream& os, unsigned codepoint) { | |
RAPIDJSON_ASSERT(codepoint <= 0x7F); | |
os.Put(static_cast<Ch>(codepoint & 0xFF)); | |
} | |
template<typename OutputStream> | |
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { | |
RAPIDJSON_ASSERT(codepoint <= 0x7F); | |
PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF)); | |
} | |
template <typename InputStream> | |
static bool Decode(InputStream& is, unsigned* codepoint) { | |
uint8_t c = static_cast<uint8_t>(is.Take()); | |
*codepoint = c; | |
return c <= 0X7F; | |
} | |
template <typename InputStream, typename OutputStream> | |
static bool Validate(InputStream& is, OutputStream& os) { | |
uint8_t c = static_cast<uint8_t>(is.Take()); | |
os.Put(static_cast<typename OutputStream::Ch>(c)); | |
return c <= 0x7F; | |
} | |
template <typename InputByteStream> | |
static CharType TakeBOM(InputByteStream& is) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | |
uint8_t c = static_cast<uint8_t>(Take(is)); | |
return static_cast<Ch>(c); | |
} | |
template <typename InputByteStream> | |
static Ch Take(InputByteStream& is) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); | |
return static_cast<Ch>(is.Take()); | |
} | |
template <typename OutputByteStream> | |
static void PutBOM(OutputByteStream& os) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |
(void)os; | |
} | |
template <typename OutputByteStream> | |
static void Put(OutputByteStream& os, Ch c) { | |
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); | |
os.Put(static_cast<typename OutputByteStream::Ch>(c)); | |
} | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// AutoUTF | |
//! Runtime-specified UTF encoding type of a stream. | |
enum UTFType { | |
kUTF8 = 0, //!< UTF-8. | |
kUTF16LE = 1, //!< UTF-16 little endian. | |
kUTF16BE = 2, //!< UTF-16 big endian. | |
kUTF32LE = 3, //!< UTF-32 little endian. | |
kUTF32BE = 4 //!< UTF-32 big endian. | |
}; | |
//! Dynamically select encoding according to stream's runtime-specified UTF encoding type. | |
/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType(). | |
*/ | |
template<typename CharType> | |
struct AutoUTF { | |
typedef CharType Ch; | |
enum { supportUnicode = 1 }; | |
#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x | |
template<typename OutputStream> | |
static RAPIDJSON_FORCEINLINE void Encode(OutputStream& os, unsigned codepoint) { | |
typedef void (*EncodeFunc)(OutputStream&, unsigned); | |
static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) }; | |
(*f[os.GetType()])(os, codepoint); | |
} | |
template<typename OutputStream> | |
static RAPIDJSON_FORCEINLINE void EncodeUnsafe(OutputStream& os, unsigned codepoint) { | |
typedef void (*EncodeFunc)(OutputStream&, unsigned); | |
static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) }; | |
(*f[os.GetType()])(os, codepoint); | |
} | |
template <typename InputStream> | |
static RAPIDJSON_FORCEINLINE bool Decode(InputStream& is, unsigned* codepoint) { | |
typedef bool (*DecodeFunc)(InputStream&, unsigned*); | |
static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) }; | |
return (*f[is.GetType()])(is, codepoint); | |
} | |
template <typename InputStream, typename OutputStream> | |
static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) { | |
typedef bool (*ValidateFunc)(InputStream&, OutputStream&); | |
static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) }; | |
return (*f[is.GetType()])(is, os); | |
} | |
#undef RAPIDJSON_ENCODINGS_FUNC | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
// Transcoder | |
//! Encoding conversion. | |
template<typename SourceEncoding, typename TargetEncoding> | |
struct Transcoder { | |
//! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream. | |
template<typename InputStream, typename OutputStream> | |
static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) { | |
unsigned codepoint; | |
if (!SourceEncoding::Decode(is, &codepoint)) | |
return false; | |
TargetEncoding::Encode(os, codepoint); | |
return true; | |
} | |
template<typename InputStream, typename OutputStream> | |
static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) { | |
unsigned codepoint; | |
if (!SourceEncoding::Decode(is, &codepoint)) | |
return false; | |
TargetEncoding::EncodeUnsafe(os, codepoint); | |
return true; | |
} | |
//! Validate one Unicode codepoint from an encoded stream. | |
template<typename InputStream, typename OutputStream> | |
static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) { | |
return Transcode(is, os); // Since source/target encoding is different, must transcode. | |
} | |
}; | |
// Forward declaration. | |
template<typename Stream> | |
inline void PutUnsafe(Stream& stream, typename Stream::Ch c); | |
//! Specialization of Transcoder with same source and target encoding. | |
template<typename Encoding> | |
struct Transcoder<Encoding, Encoding> { | |
template<typename InputStream, typename OutputStream> | |
static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) { | |
os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class. | |
return true; | |
} | |
template<typename InputStream, typename OutputStream> | |
static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) { | |
PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class. | |
return true; | |
} | |
template<typename InputStream, typename OutputStream> | |
static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) { | |
return Encoding::Validate(is, os); // source/target encoding are the same | |
} | |
}; | |
RAPIDJSON_NAMESPACE_END | |
#if defined(__GNUC__) || (defined(_MSC_VER) && !defined(__clang__)) | |
RAPIDJSON_DIAG_POP | |
#endif | |
#endif // RAPIDJSON_ENCODINGS_H_ | |
// End file:encodings.h | |
RAPIDJSON_NAMESPACE_BEGIN | |
/////////////////////////////////////////////////////////////////////////////// | |
// 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 | |
*/ | |
//! Provides additional information for stream. | |
/*! | |
By using traits pattern, this type provides a default configuration for stream. | |
For custom stream, this type can be specialized for other configuration. | |
See TEST(Reader, CustomStringStream) in readertest.cpp for example. | |
*/ | |
template<typename Stream> | |
struct StreamTraits { | |
//! Whether to make local copy of stream for optimization during parsing. | |
/*! | |
By default, for safety, streams do not use local copy optimization. | |
Stream that can be copied fast should specialize this, like StreamTraits<StringStream>. | |
*/ | |
enum { copyOptimization = 0 }; | |
}; | |
//! Reserve n characters for writing to a stream. | |
template<typename Stream> | |
inline void PutReserve(Stream& stream, size_t count) { | |
(void)stream; | |
(void)count; | |
} | |
//! Write character to a stream, presuming buffer is reserved. | |
template<typename Stream> | |
inline void PutUnsafe(Stream& stream, typename Stream::Ch c) { | |
stream.Put(c); | |
} | |
//! Put N copies of a character to a stream. | |
template<typename Stream, typename Ch> | |
inline void PutN(Stream& stream, Ch c, size_t n) { | |
PutReserve(stream, n); | |
for (size_t i = 0; i < n; i++) | |
PutUnsafe(stream, c); | |
} | |
/////////////////////////////////////////////////////////////////////////////// | |
// GenericStreamWrapper | |
//! A Stream Wrapper | |
/*! \tThis string stream is a wrapper for any stream by just forwarding any | |
\treceived message to the origin stream. | |
\note implements Stream concept | |
*/ | |
#if defined(_MSC_VER) && _MSC_VER <= 1800 | |
RAPIDJSON_DIAG_PUSH | |
RAPIDJSON_DIAG_OFF(4702) // unreachable code | |
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated | |
#endif | |
template <typename InputStream, typename Encoding = UTF8<> > | |
class GenericStreamWrapper { | |
public: | |
typedef typename Encoding::Ch Ch; | |
GenericStreamWrapper(InputStream& is): is_(is) {} | |
Ch Peek() const { return is_.Peek(); } | |
Ch Take() { return is_.Take(); } | |
size_t Tell() { return is_.Tell(); } | |
Ch* PutBegin() { return is_.PutBegin(); } | |
void Put(Ch ch) { is_.Put(ch); } | |
void Flush() { is_.Flush(); } | |
size_t PutEnd(Ch* ch) { return is_.PutEnd(ch); } | |
// wrapper for MemoryStream | |
const Ch* Peek4() const { return is_.Peek4(); } | |
// wrapper for AutoUTFInputStream | |
UTFType GetType() const { return is_.GetType(); } | |
bool HasBOM() const { return is_.HasBOM(); } | |
protected: | |
InputStream& is_; | |
}; | |
#if defined(_MSC_VER) && _MSC_VER <= 1800 | |
RAPIDJSON_DIAG_POP | |
#endif | |
/////////////////////////////////////////////////////////////////////////////// | |
// StringStream | |
//! Read-only string stream. | |
/*! \note implements Stream concept | |
*/ | |
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 static_cast<size_t>(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. | |
}; | |
template <typename Encoding> | |
struct StreamTraits<GenericStringStream<Encoding> > { | |
enum { copyOptimization = 1 }; | |
}; | |
//! String stream with UTF8 encoding. | |
typedef GenericStringStream<UTF8<> > StringStream; | |
/////////////////////////////////////////////////////////////////////////////// | |
// InsituStringStream | |
//! A read-write string stream. | |
/*! This string stream is particularly designed for in-situ parsing. | |
\note implements Stream concept | |
*/ | |
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 static_cast<size_t>(src_ - head_); } | |
// Write | |
void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } | |
Ch* PutBegin() { return dst_ = src_; } | |
size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); } | |
void Flush() {} | |
Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } | |
void Pop(size_t count) { dst_ -= count; } | |
Ch* src_; | |
Ch* dst_; | |
Ch* head_; | |
}; | |
template <typename Encoding> | |
struct StreamTraits<GenericInsituStringStream<Encoding> > { | |
enum { copyOptimization = 1 }; | |
}; | |
//! Insitu string stream with UTF8 encoding. | |
typedef GenericInsituStringStream<UTF8<> > InsituStringStream; | |
RAPIDJSON_NAMESPACE_END | |
#endif // RAPIDJSON_STREAM_H_ | |
// End file:stream.h | |
#if defined(__GNUC__) | |
RAPIDJSON_DIAG_PUSH | |
RAPIDJSON_DIAG_OFF(effc++) | |
#endif | |
#if defined(_MSC_VER) && _MSC_VER <= 1800 | |
RAPIDJSON_DIAG_PUSH | |
RAPIDJSON_DIAG_OFF(4702) // unreachable code | |
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated | |
#endif | |
RAPIDJSON_NAMESPACE_BEGIN | |
//! Cursor stream wrapper for counting line and column number if error exists. | |
/*! | |
\tparam InputStream Any stream that implements Stream Concept | |
*/ | |
template <typename InputStream, typename Encoding = UTF8<> > | |
class CursorStreamWrapper : public GenericStreamWrapper<InputStream, Encoding> { | |
public: | |
typedef typename Encoding::Ch Ch; | |
CursorStreamWrapper(InputStream& is): | |
GenericStreamWrapper<InputStream, Encoding>(is), line_(1), col_(0) {} | |
// counting line and column number | |
Ch Take() { | |
Ch ch = this->is_.Take(); | |
if(ch == '\n') { | |
line_ ++; | |
col_ = 0; | |
} else { | |
col_ ++; | |
} | |
return ch; | |
} | |
//! Get the error line number, if error exists. | |
size_t GetLine() const { return line_; } | |
//! Get the error column number, if error exists. | |
size_t GetColumn() const { return col_; } | |
private: | |
size_t line_; //!< Current Line | |
size_t col_; //!< Current Column | |
}; | |
#if defined(_MSC_VER) && _MSC_VER <= 1800 | |
RAPIDJSON_DIAG_POP | |
#endif | |
#if defined(__GNUC__) | |
RAPIDJSON_DIAG_POP | |
#endif | |
RAPIDJSON_NAMESPACE_END | |
#endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_ | |
// End file:cursorstreamwrapper.h | |
// Begin file: document.h | |
// Tencent is pleased to support the open source community by making RapidJSON available. | |
// | |
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. | |
// | |
// Licensed under the MIT License (the "License"); you may not use this file except | |
// in compliance with the License. You may obtain a copy of the License at | |
// | |
// http://opensource.org/licenses/MIT | |
// | |
// Unless required by applicable law or agreed to in writing, software distributed | |
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |
// CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
// specific language governing permissions and limitations under the License. | |
#ifndef RAPIDJSON_DOCUMENT_H_ | |
#define RAPIDJSON_DOCUMENT_H_ | |
/*! \file document.h */ | |
// Begin file: reader.h | |
// Tencent is pleased to support the open source community by making RapidJSON available. | |
// | |
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. | |
// | |
// Licensed under the MIT License (the "License"); you may not use this file except | |
// in compliance with the License. You may obtain a copy of the License at | |
// | |
// http://opensource.org/licenses/MIT | |
// | |
// Unless required by applicable law or agreed to in writing, software distributed | |
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |
// CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
// specific language governing permissions and limitations under the License. | |
#ifndef RAPIDJSON_READER_H_ | |
#define RAPIDJSON_READER_H_ | |
/*! \file reader.h */ | |
// Begin file: allocators.h | |
// already included | |
// End file:allocators.h | |
// Begin file: stream.h | |
// already included | |
// End file:stream.h | |
// Begin file: encodedstream.h | |
// Tencent is pleased to support the open source community by making RapidJSON available. | |
// | |
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. | |
// | |
// Licensed under the MIT License (the "License"); you may not use this file except | |
// in compliance with the License. You may obtain a copy of the License at | |
// | |
// http://opensource.org/licenses/MIT | |
// | |
// Unless required by applicable law or agreed to in writing, software distributed | |
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |
// CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
// specific language governing permissions and limitations under the License. | |
#ifndef RAPIDJSON_ENCODEDSTREAM_H_ | |
#define RAPIDJSON_ENCODEDSTREAM_H_ | |
// Begin file: stream.h | |
// already included | |
// End file:stream.h | |
// Begin file: memorystream.h | |
// Tencent is pleased to support the open source community by making RapidJSON available. | |
// | |
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. | |
// | |
// Licensed under the MIT License (the "License"); you may not use this file except | |
// in compliance with the License. You may obtain a copy of the License at | |
// | |
// http://opensource.org/licenses/MIT | |
// | |
// Unless required by applicable law or agreed to in writing, software distributed | |
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | |
// CONDITIONS OF ANY KIND, either express or implied. See the License for the | |
// specific language governing permissions and limitations under the License. | |
#ifndef RAPIDJSON_MEMORYSTREAM_H_ | |
#define RAPIDJSON_MEMORYSTREAM_H_ | |
// Begin file: stream.h | |
// already included | |
// End file:stream.h | |
#ifdef __clang__ | |
RAPIDJSON_DIAG_PUSH | |
RAPIDJSON_DIAG_OFF(unreachable-code) | |
RAPIDJSON_DIAG_OFF(missing-noreturn) | |
#endif | |
RAPIDJSON_NAMESPACE_BEGIN | |
//! Represents an in-memory input byte stream. | |
/*! | |
This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. | |