Merge branch 'master' into custom_malloc
This commit is contained in:
commit
004e8e61a0
61
.travis.yml
61
.travis.yml
@ -1,11 +1,18 @@
|
|||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: xenial
|
||||||
group: edge
|
|
||||||
|
|
||||||
language: cpp
|
language: cpp
|
||||||
cache:
|
cache:
|
||||||
- ccache
|
- ccache
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
packages:
|
||||||
|
- cmake
|
||||||
|
- valgrind
|
||||||
|
- clang-8
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- USE_CCACHE=1
|
- USE_CCACHE=1
|
||||||
@ -14,41 +21,60 @@ env:
|
|||||||
- CCACHE_MAXSIZE=100M
|
- CCACHE_MAXSIZE=100M
|
||||||
- ARCH_FLAGS_x86='-m32' # #266: don't use SSE on 32-bit
|
- ARCH_FLAGS_x86='-m32' # #266: don't use SSE on 32-bit
|
||||||
- ARCH_FLAGS_x86_64='-msse4.2' # use SSE4.2 on 64-bit
|
- ARCH_FLAGS_x86_64='-msse4.2' # use SSE4.2 on 64-bit
|
||||||
|
- ARCH_FLAGS_aarch64='-march=armv8-a'
|
||||||
- GITHUB_REPO='Tencent/rapidjson'
|
- GITHUB_REPO='Tencent/rapidjson'
|
||||||
- secure: "HrsaCb+N66EG1HR+LWH1u51SjaJyRwJEDzqJGYMB7LJ/bfqb9mWKF1fLvZGk46W5t7TVaXRDD5KHFx9DPWvKn4gRUVkwTHEy262ah5ORh8M6n/6VVVajeV/AYt2C0sswdkDBDO4Xq+xy5gdw3G8s1A4Inbm73pUh+6vx+7ltBbk="
|
- secure: "HrsaCb+N66EG1HR+LWH1u51SjaJyRwJEDzqJGYMB7LJ/bfqb9mWKF1fLvZGk46W5t7TVaXRDD5KHFx9DPWvKn4gRUVkwTHEy262ah5ORh8M6n/6VVVajeV/AYt2C0sswdkDBDO4Xq+xy5gdw3G8s1A4Inbm73pUh+6vx+7ltBbk="
|
||||||
|
|
||||||
before_install:
|
|
||||||
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
|
|
||||||
- sudo apt-get update -qq
|
|
||||||
- sudo apt-get install -y cmake valgrind g++-multilib libc6-dbg:i386
|
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
# gcc
|
# gcc
|
||||||
- env: CONF=release ARCH=x86 CXX11=ON
|
- env: CONF=release ARCH=x86 CXX11=ON
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
|
arch: amd64
|
||||||
- env: CONF=release ARCH=x86_64 CXX11=ON
|
- env: CONF=release ARCH=x86_64 CXX11=ON
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
|
arch: amd64
|
||||||
- env: CONF=debug ARCH=x86 CXX11=OFF
|
- env: CONF=debug ARCH=x86 CXX11=OFF
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
|
arch: amd64
|
||||||
- env: CONF=debug ARCH=x86_64 CXX11=OFF
|
- env: CONF=debug ARCH=x86_64 CXX11=OFF
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
|
arch: amd64
|
||||||
|
- env: CONF=release ARCH=aarch64 CXX11=ON
|
||||||
|
compiler: gcc
|
||||||
|
arch: arm64
|
||||||
|
- env: CONF=debug ARCH=aarch64 CXX11=OFF
|
||||||
|
compiler: gcc
|
||||||
|
arch: arm64
|
||||||
# clang
|
# clang
|
||||||
- env: CONF=debug ARCH=x86 CXX11=ON CCACHE_CPP2=yes
|
- env: CONF=debug ARCH=x86 CXX11=ON CCACHE_CPP2=yes
|
||||||
compiler: clang
|
compiler: clang
|
||||||
|
arch: amd64
|
||||||
- env: CONF=debug ARCH=x86_64 CXX11=ON CCACHE_CPP2=yes
|
- env: CONF=debug ARCH=x86_64 CXX11=ON CCACHE_CPP2=yes
|
||||||
compiler: clang
|
compiler: clang
|
||||||
|
arch: amd64
|
||||||
- env: CONF=debug ARCH=x86 CXX11=OFF CCACHE_CPP2=yes
|
- env: CONF=debug ARCH=x86 CXX11=OFF CCACHE_CPP2=yes
|
||||||
compiler: clang
|
compiler: clang
|
||||||
|
arch: amd64
|
||||||
- env: CONF=debug ARCH=x86_64 CXX11=OFF CCACHE_CPP2=yes
|
- env: CONF=debug ARCH=x86_64 CXX11=OFF CCACHE_CPP2=yes
|
||||||
compiler: clang
|
compiler: clang
|
||||||
|
arch: amd64
|
||||||
- env: CONF=release ARCH=x86 CXX11=ON CCACHE_CPP2=yes
|
- env: CONF=release ARCH=x86 CXX11=ON CCACHE_CPP2=yes
|
||||||
compiler: clang
|
compiler: clang
|
||||||
|
arch: amd64
|
||||||
- env: CONF=release ARCH=x86_64 CXX11=ON CCACHE_CPP2=yes
|
- env: CONF=release ARCH=x86_64 CXX11=ON CCACHE_CPP2=yes
|
||||||
compiler: clang
|
compiler: clang
|
||||||
|
arch: amd64
|
||||||
|
- env: CONF=debug ARCH=aarch64 CXX11=ON CCACHE_CPP2=yes
|
||||||
|
compiler: clang
|
||||||
|
arch: arm64
|
||||||
|
- env: CONF=debug ARCH=aarch64 CXX11=OFF CCACHE_CPP2=yes
|
||||||
|
compiler: clang
|
||||||
|
arch: arm64
|
||||||
# coverage report
|
# coverage report
|
||||||
- env: CONF=debug ARCH=x86 CXX11=ON GCOV_FLAGS='--coverage'
|
- env: CONF=debug ARCH=x86 CXX11=ON GCOV_FLAGS='--coverage'
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
|
arch: amd64
|
||||||
cache:
|
cache:
|
||||||
- ccache
|
- ccache
|
||||||
- pip
|
- pip
|
||||||
@ -57,6 +83,16 @@ matrix:
|
|||||||
- coveralls -r .. --gcov-options '\-lp' -e thirdparty -e example -e test -e build/CMakeFiles -e include/rapidjson/msinttypes -e include/rapidjson/internal/meta.h -e include/rapidjson/error/en.h
|
- coveralls -r .. --gcov-options '\-lp' -e thirdparty -e example -e test -e build/CMakeFiles -e include/rapidjson/msinttypes -e include/rapidjson/internal/meta.h -e include/rapidjson/error/en.h
|
||||||
- env: CONF=debug ARCH=x86_64 GCOV_FLAGS='--coverage'
|
- env: CONF=debug ARCH=x86_64 GCOV_FLAGS='--coverage'
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
|
arch: amd64
|
||||||
|
cache:
|
||||||
|
- ccache
|
||||||
|
- pip
|
||||||
|
after_success:
|
||||||
|
- pip install --user cpp-coveralls
|
||||||
|
- coveralls -r .. --gcov-options '\-lp' -e thirdparty -e example -e test -e build/CMakeFiles -e include/rapidjson/msinttypes -e include/rapidjson/internal/meta.h -e include/rapidjson/error/en.h
|
||||||
|
- env: CONF=debug ARCH=aarch64 GCOV_FLAGS='--coverage'
|
||||||
|
compiler: gcc
|
||||||
|
arch: arm64
|
||||||
cache:
|
cache:
|
||||||
- ccache
|
- ccache
|
||||||
- pip
|
- pip
|
||||||
@ -73,7 +109,18 @@ matrix:
|
|||||||
packages:
|
packages:
|
||||||
- doxygen
|
- doxygen
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- if [ "x86_64" = "$(arch)" ]; then sudo apt-get install -y g++-multilib libc6-dbg:i386 --allow-unauthenticated; fi
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
|
# travis provides clang-7 for amd64 and clang-3.8 for arm64
|
||||||
|
# here use clang-8 to all architectures as clang-7 is not available for arm64
|
||||||
|
- if [ -f /usr/bin/clang++-8 ]; then
|
||||||
|
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-8 1000;
|
||||||
|
sudo update-alternatives --config clang++;
|
||||||
|
export PATH=/usr/bin:$PATH;
|
||||||
|
fi
|
||||||
|
- if [ "$CXX" = "clang++" ]; then export CCACHE_CPP2=yes; fi
|
||||||
- ccache -s
|
- ccache -s
|
||||||
# hack to avoid Valgrind bug (https://bugs.kde.org/show_bug.cgi?id=326469),
|
# hack to avoid Valgrind bug (https://bugs.kde.org/show_bug.cgi?id=326469),
|
||||||
# exposed by merging PR#163 (using -march=native)
|
# exposed by merging PR#163 (using -march=native)
|
||||||
|
@ -9,13 +9,18 @@ endif()
|
|||||||
|
|
||||||
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules)
|
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules)
|
||||||
|
|
||||||
PROJECT(RapidJSON CXX)
|
|
||||||
|
|
||||||
set(LIB_MAJOR_VERSION "1")
|
set(LIB_MAJOR_VERSION "1")
|
||||||
set(LIB_MINOR_VERSION "1")
|
set(LIB_MINOR_VERSION "1")
|
||||||
set(LIB_PATCH_VERSION "0")
|
set(LIB_PATCH_VERSION "0")
|
||||||
set(LIB_VERSION_STRING "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_PATCH_VERSION}")
|
set(LIB_VERSION_STRING "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_PATCH_VERSION}")
|
||||||
|
|
||||||
|
if (CMAKE_VERSION VERSION_LESS 3.0)
|
||||||
|
PROJECT(RapidJSON CXX)
|
||||||
|
else()
|
||||||
|
cmake_policy(SET CMP0048 NEW)
|
||||||
|
PROJECT(RapidJSON VERSION "${LIB_VERSION_STRING}" LANGUAGES CXX)
|
||||||
|
endif()
|
||||||
|
|
||||||
# compile in release with debug info mode by default
|
# compile in release with debug info mode by default
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
################################################################################
|
||||||
|
# CMake minimum version required
|
||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# RapidJSON source dir
|
# RapidJSON source dir
|
||||||
set( RapidJSON_SOURCE_DIR "@CONFIG_SOURCE_DIR@")
|
set( RapidJSON_SOURCE_DIR "@CONFIG_SOURCE_DIR@")
|
||||||
@ -13,3 +17,9 @@ get_filename_component(RapidJSON_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
|||||||
set( RapidJSON_INCLUDE_DIR "@RapidJSON_INCLUDE_DIR@" )
|
set( RapidJSON_INCLUDE_DIR "@RapidJSON_INCLUDE_DIR@" )
|
||||||
set( RapidJSON_INCLUDE_DIRS "@RapidJSON_INCLUDE_DIR@" )
|
set( RapidJSON_INCLUDE_DIRS "@RapidJSON_INCLUDE_DIR@" )
|
||||||
message(STATUS "RapidJSON found. Headers: ${RapidJSON_INCLUDE_DIRS}")
|
message(STATUS "RapidJSON found. Headers: ${RapidJSON_INCLUDE_DIRS}")
|
||||||
|
|
||||||
|
if(NOT TARGET rapidjson)
|
||||||
|
add_library(rapidjson INTERFACE IMPORTED)
|
||||||
|
set_property(TARGET rapidjson PROPERTY
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES ${RapidJSON_INCLUDE_DIRS})
|
||||||
|
endif()
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
<DisplayString Condition="(data_.f.flags & kTypeMask) == kNullType">null</DisplayString>
|
<DisplayString Condition="(data_.f.flags & kTypeMask) == kNullType">null</DisplayString>
|
||||||
<DisplayString Condition="data_.f.flags == kTrueFlag">true</DisplayString>
|
<DisplayString Condition="data_.f.flags == kTrueFlag">true</DisplayString>
|
||||||
<DisplayString Condition="data_.f.flags == kFalseFlag">false</DisplayString>
|
<DisplayString Condition="data_.f.flags == kFalseFlag">false</DisplayString>
|
||||||
<DisplayString Condition="data_.f.flags == kShortStringFlag">{data_.ss.str}</DisplayString>
|
<DisplayString Condition="data_.f.flags == kShortStringFlag">{(const Ch*)data_.ss.str,na}</DisplayString>
|
||||||
<DisplayString Condition="(data_.f.flags & kTypeMask) == kStringType">{(const char*)((size_t)data_.s.str & 0x0000FFFFFFFFFFFF)}</DisplayString>
|
<DisplayString Condition="(data_.f.flags & kTypeMask) == kStringType">{(const Ch*)((size_t)data_.s.str & 0x0000FFFFFFFFFFFF),na}</DisplayString>
|
||||||
<DisplayString Condition="(data_.f.flags & kNumberIntFlag) == kNumberIntFlag">{data_.n.i.i}</DisplayString>
|
<DisplayString Condition="(data_.f.flags & kNumberIntFlag) == kNumberIntFlag">{data_.n.i.i}</DisplayString>
|
||||||
<DisplayString Condition="(data_.f.flags & kNumberUintFlag) == kNumberUintFlag">{data_.n.u.u}</DisplayString>
|
<DisplayString Condition="(data_.f.flags & kNumberUintFlag) == kNumberUintFlag">{data_.n.u.u}</DisplayString>
|
||||||
<DisplayString Condition="(data_.f.flags & kNumberInt64Flag) == kNumberInt64Flag">{data_.n.i64}</DisplayString>
|
<DisplayString Condition="(data_.f.flags & kNumberInt64Flag) == kNumberInt64Flag">{data_.n.i64}</DisplayString>
|
||||||
|
@ -119,6 +119,7 @@ Parse flags | Meaning
|
|||||||
`kParseNumbersAsStringsFlag` | Parse numerical type values as strings.
|
`kParseNumbersAsStringsFlag` | Parse numerical type values as strings.
|
||||||
`kParseTrailingCommasFlag` | Allow trailing commas at the end of objects and arrays (relaxed JSON syntax).
|
`kParseTrailingCommasFlag` | Allow trailing commas at the end of objects and arrays (relaxed JSON syntax).
|
||||||
`kParseNanAndInfFlag` | Allow parsing `NaN`, `Inf`, `Infinity`, `-Inf` and `-Infinity` as `double` values (relaxed JSON syntax).
|
`kParseNanAndInfFlag` | Allow parsing `NaN`, `Inf`, `Infinity`, `-Inf` and `-Infinity` as `double` values (relaxed JSON syntax).
|
||||||
|
`kParseEscapedApostropheFlag` | Allow escaped apostrophe `\'` in strings (relaxed JSON syntax).
|
||||||
|
|
||||||
By using a non-type template parameter, instead of a function parameter, C++ compiler can generate code which is optimized for specified combinations, improving speed, and reducing code size (if only using a single specialization). The downside is the flags needed to be determined in compile-time.
|
By using a non-type template parameter, instead of a function parameter, C++ compiler can generate code which is optimized for specified combinations, improving speed, and reducing code size (if only using a single specialization). The downside is the flags needed to be determined in compile-time.
|
||||||
|
|
||||||
|
@ -119,6 +119,7 @@ GenericDocument& GenericDocument::Parse(const Ch* str);
|
|||||||
`kParseNumbersAsStringsFlag` | 把数字类型解析成字符串。
|
`kParseNumbersAsStringsFlag` | 把数字类型解析成字符串。
|
||||||
`kParseTrailingCommasFlag` | 容许在对象和数组结束前含有逗号(放宽的 JSON 语法)。
|
`kParseTrailingCommasFlag` | 容许在对象和数组结束前含有逗号(放宽的 JSON 语法)。
|
||||||
`kParseNanAndInfFlag` | 容许 `NaN`、`Inf`、`Infinity`、`-Inf` 及 `-Infinity` 作为 `double` 值(放宽的 JSON 语法)。
|
`kParseNanAndInfFlag` | 容许 `NaN`、`Inf`、`Infinity`、`-Inf` 及 `-Infinity` 作为 `double` 值(放宽的 JSON 语法)。
|
||||||
|
`kParseEscapedApostropheFlag` | 容许字符串中转义单引号 `\'` (放宽的 JSON 语法)。
|
||||||
|
|
||||||
由于使用了非类型模板参数,而不是函数参数,C++ 编译器能为个别组合生成代码,以改善性能及减少代码尺寸(当只用单种特化)。缺点是需要在编译期决定标志。
|
由于使用了非类型模板参数,而不是函数参数,C++ 编译器能为个别组合生成代码,以改善性能及减少代码尺寸(当只用单种特化)。缺点是需要在编译期决定标志。
|
||||||
|
|
||||||
|
@ -64,11 +64,11 @@
|
|||||||
|
|
||||||
JSON are commonly used in web applications for transferring structured data. It is also used as a file format for data persistence.
|
JSON are commonly used in web applications for transferring structured data. It is also used as a file format for data persistence.
|
||||||
|
|
||||||
2. Does RapidJSON conform to the JSON standard?
|
3. Does RapidJSON conform to the JSON standard?
|
||||||
|
|
||||||
Yes. RapidJSON is fully compliance with [RFC7159](http://www.ietf.org/rfc/rfc7159.txt) and [ECMA-404](http://www.ecma-international.org/publications/standards/Ecma-404.htm). It can handle corner cases, such as supporting null character and surrogate pairs in JSON strings.
|
Yes. RapidJSON is fully compliance with [RFC7159](http://www.ietf.org/rfc/rfc7159.txt) and [ECMA-404](http://www.ecma-international.org/publications/standards/Ecma-404.htm). It can handle corner cases, such as supporting null character and surrogate pairs in JSON strings.
|
||||||
|
|
||||||
3. Does RapidJSON support relaxed syntax?
|
4. Does RapidJSON support relaxed syntax?
|
||||||
|
|
||||||
Currently no. RapidJSON only support the strict standardized format. Support on related syntax is under discussion in this [issue](https://github.com/Tencent/rapidjson/issues/36).
|
Currently no. RapidJSON only support the strict standardized format. Support on related syntax is under discussion in this [issue](https://github.com/Tencent/rapidjson/issues/36).
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
4. RapidJSON 是免费的么?
|
4. RapidJSON 是免费的么?
|
||||||
|
|
||||||
是的,它在 MIT 特許條款下免费。它可用于商业软件。详情请参看 [license.txt](https://github.com/Tencent/rapidjson/blob/master/license.txt)。
|
是的,它在 MIT 协议下免费。它可用于商业软件。详情请参看 [license.txt](https://github.com/Tencent/rapidjson/blob/master/license.txt)。
|
||||||
|
|
||||||
5. RapidJSON 很小么?它有何依赖?
|
5. RapidJSON 很小么?它有何依赖?
|
||||||
|
|
||||||
@ -64,13 +64,13 @@
|
|||||||
|
|
||||||
JSON 常用于网页应用程序,以传送结构化数据。它也可作为文件格式用于数据持久化。
|
JSON 常用于网页应用程序,以传送结构化数据。它也可作为文件格式用于数据持久化。
|
||||||
|
|
||||||
2. RapidJSON 是否符合 JSON 标准?
|
3. RapidJSON 是否符合 JSON 标准?
|
||||||
|
|
||||||
是。RapidJSON 完全符合 [RFC7159](http://www.ietf.org/rfc/rfc7159.txt) 及 [ECMA-404](http://www.ecma-international.org/publications/standards/Ecma-404.htm)。它能处理一些特殊情况,例如支持 JSON 字符串中含有空字符及代理对(surrogate pair)。
|
是。RapidJSON 完全符合 [RFC7159](http://www.ietf.org/rfc/rfc7159.txt) 及 [ECMA-404](http://www.ecma-international.org/publications/standards/Ecma-404.htm)。它能处理一些特殊情况,例如支持 JSON 字符串中含有空字符及代理对(surrogate pair)。
|
||||||
|
|
||||||
3. RapidJSON 是否支持宽松的语法?
|
4. RapidJSON 是否支持宽松的语法?
|
||||||
|
|
||||||
现时不支持。RapidJSON 只支持严格的标准格式。宽松语法现时在这 [issue](https://github.com/Tencent/rapidjson/issues/36) 中进行讨论。
|
目前不支持。RapidJSON 只支持严格的标准格式。宽松语法可以在这个 [issue](https://github.com/Tencent/rapidjson/issues/36) 中进行讨论。
|
||||||
|
|
||||||
## DOM 与 SAX
|
## DOM 与 SAX
|
||||||
|
|
||||||
@ -271,7 +271,7 @@
|
|||||||
|
|
||||||
有些应用程序需要处理非常大的 JSON 文件。而有些后台应用程序需要处理大量的 JSON。达到高性能同时改善延时及吞吐量。更广义来说,这也可以节省能源。
|
有些应用程序需要处理非常大的 JSON 文件。而有些后台应用程序需要处理大量的 JSON。达到高性能同时改善延时及吞吐量。更广义来说,这也可以节省能源。
|
||||||
|
|
||||||
## 八挂
|
## 八卦
|
||||||
|
|
||||||
1. 谁是 RapidJSON 的开发者?
|
1. 谁是 RapidJSON 的开发者?
|
||||||
|
|
||||||
@ -279,11 +279,11 @@
|
|||||||
|
|
||||||
2. 为何你要开发 RapidJSON?
|
2. 为何你要开发 RapidJSON?
|
||||||
|
|
||||||
在 2011 年开始这项目是,它仅一个兴趣项目。Milo Yip 是一个游戏程序员,他在那时候认识到 JSON 并希望在未来的项目中使用。由于 JSON 好像很简单,他希望写一个仅有头文件并且快速的程序库。
|
在 2011 年开始这项目时,它只是一个兴趣项目。Milo Yip 是一个游戏程序员,他在那时候认识到 JSON 并希望在未来的项目中使用。由于 JSON 好像很简单,他希望写一个快速的仅有头文件的程序库。
|
||||||
|
|
||||||
3. 为什么开发中段有一段长期空档?
|
3. 为什么开发中段有一段长期空档?
|
||||||
|
|
||||||
主要是个人因素,例如加入新家庭成员。另外,Milo Yip 也花了许多业馀时间去翻译 Jason Gregory 的《Game Engine Architecture》至中文版《游戏引擎架构》。
|
主要是个人因素,例如加入新家庭成员。另外,Milo Yip 也花了许多业余时间去翻译 Jason Gregory 的《Game Engine Architecture》至中文版《游戏引擎架构》。
|
||||||
|
|
||||||
4. 为什么这个项目从 Google Code 搬到 GitHub?
|
4. 为什么这个项目从 Google Code 搬到 GitHub?
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ The following tables show the data layout of each type. The 32-bit/64-bit column
|
|||||||
| `unsigned u` | 32-bit unsigned integer |4 |4 |
|
| `unsigned u` | 32-bit unsigned integer |4 |4 |
|
||||||
| (zero padding) | 0 |4 |4 |
|
| (zero padding) | 0 |4 |4 |
|
||||||
| (unused) | |4 |8 |
|
| (unused) | |4 |8 |
|
||||||
| `unsigned flags_` | `kNumberType kNumberFlag kUIntFlag kUInt64Flag ...` |4 |4 |
|
| `unsigned flags_` | `kNumberType kNumberFlag kUintFlag kUint64Flag ...` |4 |4 |
|
||||||
|
|
||||||
| Number (Int64) | |32-bit|64-bit|
|
| Number (Int64) | |32-bit|64-bit|
|
||||||
|---------------------|-------------------------------------|:----:|:----:|
|
|---------------------|-------------------------------------|:----:|:----:|
|
||||||
|
@ -79,7 +79,7 @@ SAX 和 DOM API 都依赖于3个额外的概念:`Allocator`、`Encoding` 和 `
|
|||||||
| `unsigned u` | 32位无符号整数 |4 |4 |
|
| `unsigned u` | 32位无符号整数 |4 |4 |
|
||||||
| (零填充) | 0 |4 |4 |
|
| (零填充) | 0 |4 |4 |
|
||||||
| (未使用) | |4 |8 |
|
| (未使用) | |4 |8 |
|
||||||
| `unsigned flags_` | `kNumberType kNumberFlag kUIntFlag kUInt64Flag ...` |4 |4 |
|
| `unsigned flags_` | `kNumberType kNumberFlag kUintFlag kUint64Flag ...` |4 |4 |
|
||||||
|
|
||||||
| Number (Int64) | | 32位 | 64位 |
|
| Number (Int64) | | 32位 | 64位 |
|
||||||
|---------------------|-------------------------------------|:----:|:----:|
|
|---------------------|-------------------------------------|:----:|:----:|
|
||||||
@ -248,7 +248,7 @@ void SkipWhitespace(InputStream& is) {
|
|||||||
|
|
||||||
## 整数到字符串的转换 {#itoa}
|
## 整数到字符串的转换 {#itoa}
|
||||||
|
|
||||||
整数到字符串转换的朴素算法需要对每一个十进制位进行一次处罚。我们实现了若干版本并在 [itoa-benchmark](https://github.com/miloyip/itoa-benchmark) 中对它们进行了评估。
|
整数到字符串转换的朴素算法需要对每一个十进制位进行一次除法。我们实现了若干版本并在 [itoa-benchmark](https://github.com/miloyip/itoa-benchmark) 中对它们进行了评估。
|
||||||
|
|
||||||
虽然 SSE2 版本是最快的,但它和第二快的 `branchlut` 差距不大。而且 `branchlut` 是纯C++实现,所以我们在 RapidJSON 中使用了 `branchlut`。
|
虽然 SSE2 版本是最快的,但它和第二快的 `branchlut` 差距不大。而且 `branchlut` 是纯C++实现,所以我们在 RapidJSON 中使用了 `branchlut`。
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ private:
|
|||||||
|
|
||||||
`Pointer` 在其建构函数里会解译源字符串。若有解析错误,`Pointer::IsValid()` 返回 `false`。你可使用 `Pointer::GetParseErrorCode()` 和 `GetParseErrorOffset()` 去获取错信息。
|
`Pointer` 在其建构函数里会解译源字符串。若有解析错误,`Pointer::IsValid()` 返回 `false`。你可使用 `Pointer::GetParseErrorCode()` 和 `GetParseErrorOffset()` 去获取错信息。
|
||||||
|
|
||||||
要注意的是,所有解析函数都假设 pointer 是合法的。对一个非法 pointer 解析会做成断言失败。
|
要注意的是,所有解析函数都假设 pointer 是合法的。对一个非法 pointer 解析会造成断言失败。
|
||||||
|
|
||||||
# URI 片段表示方式 {#URIFragment}
|
# URI 片段表示方式 {#URIFragment}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ Bool(false)
|
|||||||
Key("n", 1, true)
|
Key("n", 1, true)
|
||||||
Null()
|
Null()
|
||||||
Key("i")
|
Key("i")
|
||||||
UInt(123)
|
Uint(123)
|
||||||
Key("pi")
|
Key("pi")
|
||||||
Double(3.1416)
|
Double(3.1416)
|
||||||
Key("a")
|
Key("a")
|
||||||
|
@ -37,7 +37,7 @@ Bool(false)
|
|||||||
Key("n", 1, true)
|
Key("n", 1, true)
|
||||||
Null()
|
Null()
|
||||||
Key("i")
|
Key("i")
|
||||||
UInt(123)
|
Uint(123)
|
||||||
Key("pi")
|
Key("pi")
|
||||||
Double(3.1416)
|
Double(3.1416)
|
||||||
Key("a")
|
Key("a")
|
||||||
@ -91,7 +91,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
注意 RapidJSON 使用模板去静态挷定 `Reader` 类型及处理器的类形,而不是使用含虚函数的类。这个范式可以通过把函数内联而改善性能。
|
注意 RapidJSON 使用模板去静态挷定 `Reader` 类型及处理器的类型,而不是使用含虚函数的类。这个范式可以通过把函数内联而改善性能。
|
||||||
|
|
||||||
## 处理器 {#Handler}
|
## 处理器 {#Handler}
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ Due to users' requests, RapidJSON provided official wrappers for `std::basic_ist
|
|||||||
|
|
||||||
## IStreamWrapper {#IStreamWrapper}
|
## IStreamWrapper {#IStreamWrapper}
|
||||||
|
|
||||||
`IStreamWrapper` wraps any class drived from `std::istream`, such as `std::istringstream`, `std::stringstream`, `std::ifstream`, `std::fstream`, into RapidJSON's input stream.
|
`IStreamWrapper` wraps any class derived from `std::istream`, such as `std::istringstream`, `std::stringstream`, `std::ifstream`, `std::fstream`, into RapidJSON's input stream.
|
||||||
|
|
||||||
~~~cpp
|
~~~cpp
|
||||||
#include <rapidjson/document.h>
|
#include <rapidjson/document.h>
|
||||||
|
@ -82,7 +82,7 @@ JSON number type represents all numeric values. However, C++ needs more specific
|
|||||||
~~~~~~~~~~cpp
|
~~~~~~~~~~cpp
|
||||||
assert(document["i"].IsNumber());
|
assert(document["i"].IsNumber());
|
||||||
|
|
||||||
// In this case, IsUint()/IsInt64()/IsUInt64() also return true.
|
// In this case, IsUint()/IsInt64()/IsUint64() also return true.
|
||||||
assert(document["i"].IsInt());
|
assert(document["i"].IsInt());
|
||||||
printf("i = %d\n", document["i"].GetInt());
|
printf("i = %d\n", document["i"].GetInt());
|
||||||
// Alternative (int)document["i"]
|
// Alternative (int)document["i"]
|
||||||
|
@ -82,7 +82,7 @@ JSON Number 类型表示所有数值。然而,C++ 需要使用更专门的类
|
|||||||
~~~~~~~~~~cpp
|
~~~~~~~~~~cpp
|
||||||
assert(document["i"].IsNumber());
|
assert(document["i"].IsNumber());
|
||||||
|
|
||||||
// 在此情况下,IsUint()/IsInt64()/IsUInt64() 也会返回 true
|
// 在此情况下,IsUint()/IsInt64()/IsUint64() 也会返回 true
|
||||||
assert(document["i"].IsInt());
|
assert(document["i"].IsInt());
|
||||||
printf("i = %d\n", document["i"].GetInt());
|
printf("i = %d\n", document["i"].GetInt());
|
||||||
// 另一种用法: (int)document["i"]
|
// 另一种用法: (int)document["i"]
|
||||||
@ -250,7 +250,7 @@ string(const char* s, size_t count);
|
|||||||
|
|
||||||
~~~~~~~~~~cpp
|
~~~~~~~~~~cpp
|
||||||
if (document["hello"] == document["n"]) /*...*/; // 比较两个值
|
if (document["hello"] == document["n"]) /*...*/; // 比较两个值
|
||||||
if (document["hello"] == "world") /*...*/; // 与字符串家面量作比较
|
if (document["hello"] == "world") /*...*/; // 与字符串字面量作比较
|
||||||
if (document["i"] != 123) /*...*/; // 与整数作比较
|
if (document["i"] != 123) /*...*/; // 与整数作比较
|
||||||
if (document["pi"] != 3.14) /*...*/; // 与 double 作比较
|
if (document["pi"] != 3.14) /*...*/; // 与 double 作比较
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
@ -388,7 +388,7 @@ allocator 参数。对于字符串字面量(或字符数组常量),只需
|
|||||||
|
|
||||||
~~~~~~~~~~cpp
|
~~~~~~~~~~cpp
|
||||||
Value s;
|
Value s;
|
||||||
s.SetString("rapidjson"); // 可包含空字符,长度在编译萁推导
|
s.SetString("rapidjson"); // 可包含空字符,长度在编译期推导
|
||||||
s = "rapidjson"; // 上行的缩写
|
s = "rapidjson"; // 上行的缩写
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
@ -447,7 +447,7 @@ contact.PushBack(val, document.GetAllocator());
|
|||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
## 修改 Object {#ModifyObject}
|
## 修改 Object {#ModifyObject}
|
||||||
Object 是键值对的集合。每个键必须为 String。要修改 Object,方法是增加或移除成员。以下的 API 用来增加城员:
|
Object 是键值对的集合。每个键必须为 String。要修改 Object,方法是增加或移除成员。以下的 API 用来增加成员:
|
||||||
|
|
||||||
* `Value& AddMember(Value&, Value&, Allocator& allocator)`
|
* `Value& AddMember(Value&, Value&, Allocator& allocator)`
|
||||||
* `Value& AddMember(StringRefType, Value&, Allocator&)`
|
* `Value& AddMember(StringRefType, Value&, Allocator&)`
|
||||||
|
@ -42,7 +42,12 @@ int main() {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// C++11 supports std::move() of Value so it always have no problem for std::sort().
|
||||||
|
// Some C++03 implementations of std::sort() requires copy constructor which causes compilation error.
|
||||||
|
// Needs a sorting function only depends on std::swap() instead.
|
||||||
|
#if __cplusplus >= 201103L || (!defined(__GLIBCXX__) && (!defined(_MSC_VER) || _MSC_VER >= 1900))
|
||||||
std::sort(d.MemberBegin(), d.MemberEnd(), NameComparator());
|
std::sort(d.MemberBegin(), d.MemberEnd(), NameComparator());
|
||||||
|
|
||||||
printIt(d);
|
printIt(d);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -53,4 +58,5 @@ int main() {
|
|||||||
"zeta": false
|
"zeta": false
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ int main(int, char*[]) {
|
|||||||
printf("n = %s\n", document["n"].IsNull() ? "null" : "?");
|
printf("n = %s\n", document["n"].IsNull() ? "null" : "?");
|
||||||
|
|
||||||
assert(document["i"].IsNumber()); // Number is a JSON type, but C++ needs more specific type.
|
assert(document["i"].IsNumber()); // Number is a JSON type, but C++ needs more specific type.
|
||||||
assert(document["i"].IsInt()); // In this case, IsUint()/IsInt64()/IsUInt64() also return true.
|
assert(document["i"].IsInt()); // In this case, IsUint()/IsInt64()/IsUint64() also return true.
|
||||||
printf("i = %d\n", document["i"].GetInt()); // Alternative (int)document["i"]
|
printf("i = %d\n", document["i"].GetInt()); // Alternative (int)document["i"]
|
||||||
|
|
||||||
assert(document["pi"].IsNumber());
|
assert(document["pi"].IsNumber());
|
||||||
|
@ -53,7 +53,7 @@ concept Allocator {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*! \def RAPIDJSON_ALLOCATOR_DEFUALT_CHUNK_CAPACITY
|
/*! \def RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
|
||||||
\ingroup RAPIDJSON_CONFIG
|
\ingroup RAPIDJSON_CONFIG
|
||||||
\brief User-defined kDefaultChunkCapacity definition.
|
\brief User-defined kDefaultChunkCapacity definition.
|
||||||
|
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
#include "encodedstream.h"
|
#include "encodedstream.h"
|
||||||
#include <new> // placement new
|
#include <new> // placement new
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#ifdef __cpp_lib_three_way_comparison
|
||||||
|
#include <compare>
|
||||||
|
#endif
|
||||||
|
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
@ -56,6 +59,48 @@ class GenericValue;
|
|||||||
template <typename Encoding, typename Allocator, typename StackAllocator>
|
template <typename Encoding, typename Allocator, typename StackAllocator>
|
||||||
class GenericDocument;
|
class GenericDocument;
|
||||||
|
|
||||||
|
/*! \def RAPIDJSON_DEFAULT_ALLOCATOR
|
||||||
|
\ingroup RAPIDJSON_CONFIG
|
||||||
|
\brief Allows to choose default allocator.
|
||||||
|
|
||||||
|
User can define this to use CrtAllocator or MemoryPoolAllocator.
|
||||||
|
*/
|
||||||
|
#ifndef RAPIDJSON_DEFAULT_ALLOCATOR
|
||||||
|
#define RAPIDJSON_DEFAULT_ALLOCATOR MemoryPoolAllocator<CrtAllocator>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! \def RAPIDJSON_DEFAULT_STACK_ALLOCATOR
|
||||||
|
\ingroup RAPIDJSON_CONFIG
|
||||||
|
\brief Allows to choose default stack allocator for Document.
|
||||||
|
|
||||||
|
User can define this to use CrtAllocator or MemoryPoolAllocator.
|
||||||
|
*/
|
||||||
|
#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
|
||||||
|
#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR CrtAllocator
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! \def RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
|
||||||
|
\ingroup RAPIDJSON_CONFIG
|
||||||
|
\brief User defined kDefaultObjectCapacity value.
|
||||||
|
|
||||||
|
User can define this as any natural number.
|
||||||
|
*/
|
||||||
|
#ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
|
||||||
|
// number of objects that rapidjson::Value allocates memory for by default
|
||||||
|
#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! \def RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
|
||||||
|
\ingroup RAPIDJSON_CONFIG
|
||||||
|
\brief User defined kDefaultArrayCapacity value.
|
||||||
|
|
||||||
|
User can define this as any natural number.
|
||||||
|
*/
|
||||||
|
#ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
|
||||||
|
// number of array elements that rapidjson::Value allocates memory for by default
|
||||||
|
#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16
|
||||||
|
#endif
|
||||||
|
|
||||||
//! Name-value pair in a JSON object value.
|
//! Name-value pair in a JSON object value.
|
||||||
/*!
|
/*!
|
||||||
This class was internal to GenericValue. It used to be a inner struct.
|
This class was internal to GenericValue. It used to be a inner struct.
|
||||||
@ -63,15 +108,45 @@ class GenericDocument;
|
|||||||
https://code.google.com/p/rapidjson/issues/detail?id=64
|
https://code.google.com/p/rapidjson/issues/detail?id=64
|
||||||
*/
|
*/
|
||||||
template <typename Encoding, typename Allocator>
|
template <typename Encoding, typename Allocator>
|
||||||
struct GenericMember {
|
class GenericMember {
|
||||||
|
public:
|
||||||
GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
|
GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
|
||||||
GenericValue<Encoding, Allocator> value; //!< value of member.
|
GenericValue<Encoding, Allocator> value; //!< value of member.
|
||||||
|
|
||||||
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
|
//! Move constructor in C++11
|
||||||
|
GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
|
||||||
|
: name(std::move(rhs.name)),
|
||||||
|
value(std::move(rhs.value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Move assignment in C++11
|
||||||
|
GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT {
|
||||||
|
return *this = static_cast<GenericMember&>(rhs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! Assignment with move semantics.
|
||||||
|
/*! \param rhs Source of the assignment. Its name and value will become a null value after assignment.
|
||||||
|
*/
|
||||||
|
GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT {
|
||||||
|
if (RAPIDJSON_LIKELY(this != &rhs)) {
|
||||||
|
name = rhs.name;
|
||||||
|
value = rhs.value;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// swap() for std::sort() and other potential use in STL.
|
// swap() for std::sort() and other potential use in STL.
|
||||||
friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
|
friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
|
||||||
a.name.Swap(b.name);
|
a.name.Swap(b.name);
|
||||||
a.value.Swap(b.value);
|
a.value.Swap(b.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Copy constructor is not permitted.
|
||||||
|
GenericMember(const GenericMember& rhs);
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -175,12 +250,16 @@ public:
|
|||||||
|
|
||||||
//! @name relations
|
//! @name relations
|
||||||
//@{
|
//@{
|
||||||
bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
|
template <bool Const_> bool operator==(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ == that.ptr_; }
|
||||||
bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
|
template <bool Const_> bool operator!=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ != that.ptr_; }
|
||||||
bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
|
template <bool Const_> bool operator<=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <= that.ptr_; }
|
||||||
bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }
|
template <bool Const_> bool operator>=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ >= that.ptr_; }
|
||||||
bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }
|
template <bool Const_> bool operator< (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ < that.ptr_; }
|
||||||
bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }
|
template <bool Const_> bool operator> (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ > that.ptr_; }
|
||||||
|
|
||||||
|
#ifdef __cpp_lib_three_way_comparison
|
||||||
|
template <bool Const_> std::strong_ordering operator<=>(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <=> that.ptr_; }
|
||||||
|
#endif
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//! @name dereference
|
//! @name dereference
|
||||||
@ -205,17 +284,17 @@ private:
|
|||||||
// class-based member iterator implementation disabled, use plain pointers
|
// class-based member iterator implementation disabled, use plain pointers
|
||||||
|
|
||||||
template <bool Const, typename Encoding, typename Allocator>
|
template <bool Const, typename Encoding, typename Allocator>
|
||||||
struct GenericMemberIterator;
|
class GenericMemberIterator;
|
||||||
|
|
||||||
//! non-const GenericMemberIterator
|
//! non-const GenericMemberIterator
|
||||||
template <typename Encoding, typename Allocator>
|
template <typename Encoding, typename Allocator>
|
||||||
struct GenericMemberIterator<false,Encoding,Allocator> {
|
class GenericMemberIterator<false,Encoding,Allocator> {
|
||||||
//! use plain pointer as iterator type
|
//! use plain pointer as iterator type
|
||||||
typedef GenericMember<Encoding,Allocator>* Iterator;
|
typedef GenericMember<Encoding,Allocator>* Iterator;
|
||||||
};
|
};
|
||||||
//! const GenericMemberIterator
|
//! const GenericMemberIterator
|
||||||
template <typename Encoding, typename Allocator>
|
template <typename Encoding, typename Allocator>
|
||||||
struct GenericMemberIterator<true,Encoding,Allocator> {
|
class GenericMemberIterator<true,Encoding,Allocator> {
|
||||||
//! use plain const pointer as iterator type
|
//! use plain const pointer as iterator type
|
||||||
typedef const GenericMember<Encoding,Allocator>* Iterator;
|
typedef const GenericMember<Encoding,Allocator>* Iterator;
|
||||||
};
|
};
|
||||||
@ -574,7 +653,7 @@ template <bool, typename> class GenericObject;
|
|||||||
\tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
|
\tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
|
||||||
\tparam Allocator Allocator type for allocating memory of object, array and string.
|
\tparam Allocator Allocator type for allocating memory of object, array and string.
|
||||||
*/
|
*/
|
||||||
template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
|
template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
|
||||||
class GenericValue {
|
class GenericValue {
|
||||||
public:
|
public:
|
||||||
//! Name-value pair in an object.
|
//! Name-value pair in an object.
|
||||||
@ -1939,8 +2018,8 @@ private:
|
|||||||
kTypeMask = 0x07
|
kTypeMask = 0x07
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SizeType kDefaultArrayCapacity = 16;
|
static const SizeType kDefaultArrayCapacity = RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY;
|
||||||
static const SizeType kDefaultObjectCapacity = 16;
|
static const SizeType kDefaultObjectCapacity = RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY;
|
||||||
|
|
||||||
struct Flag {
|
struct Flag {
|
||||||
#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
|
#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
|
||||||
@ -2120,7 +2199,7 @@ typedef GenericValue<UTF8<> > Value;
|
|||||||
\tparam StackAllocator Allocator for allocating memory for stack during parsing.
|
\tparam StackAllocator Allocator for allocating memory for stack during parsing.
|
||||||
\warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue.
|
\warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue.
|
||||||
*/
|
*/
|
||||||
template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
|
template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR, typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
|
||||||
class GenericDocument : public GenericValue<Encoding, Allocator> {
|
class GenericDocument : public GenericValue<Encoding, Allocator> {
|
||||||
public:
|
public:
|
||||||
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
|
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
|
||||||
@ -2505,6 +2584,7 @@ private:
|
|||||||
//! GenericDocument with UTF8 encoding
|
//! GenericDocument with UTF8 encoding
|
||||||
typedef GenericDocument<UTF8<> > Document;
|
typedef GenericDocument<UTF8<> > Document;
|
||||||
|
|
||||||
|
|
||||||
//! Helper class for accessing Value of array type.
|
//! Helper class for accessing Value of array type.
|
||||||
/*!
|
/*!
|
||||||
Instance of this helper class is obtained by \c GenericValue::GetArray().
|
Instance of this helper class is obtained by \c GenericValue::GetArray().
|
||||||
|
@ -102,7 +102,7 @@ class PrettyWriter;
|
|||||||
// document.h
|
// document.h
|
||||||
|
|
||||||
template <typename Encoding, typename Allocator>
|
template <typename Encoding, typename Allocator>
|
||||||
struct GenericMember;
|
class GenericMember;
|
||||||
|
|
||||||
template <bool Const, typename Encoding, typename Allocator>
|
template <bool Const, typename Encoding, typename Allocator>
|
||||||
class GenericMemberIterator;
|
class GenericMemberIterator;
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include "../rapidjson.h"
|
#include "../rapidjson.h"
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !__INTEL_COMPILER && defined(_M_AMD64)
|
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_M_AMD64)
|
||||||
#include <intrin.h> // for _umul128
|
#include <intrin.h> // for _umul128
|
||||||
#pragma intrinsic(_umul128)
|
#pragma intrinsic(_umul128)
|
||||||
#endif
|
#endif
|
||||||
|
71
include/rapidjson/internal/clzll.h
Normal file
71
include/rapidjson/internal/clzll.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// 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_CLZLL_H_
|
||||||
|
#define RAPIDJSON_CLZLL_H_
|
||||||
|
|
||||||
|
#include "../rapidjson.h"
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#include <intrin.h>
|
||||||
|
#if defined(_WIN64)
|
||||||
|
#pragma intrinsic(_BitScanReverse64)
|
||||||
|
#else
|
||||||
|
#pragma intrinsic(_BitScanReverse)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
inline uint32_t clzll(uint64_t x) {
|
||||||
|
// Passing 0 to __builtin_clzll is UB in GCC and results in an
|
||||||
|
// infinite loop in the software implementation.
|
||||||
|
RAPIDJSON_ASSERT(x != 0);
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
unsigned long r = 0;
|
||||||
|
#if defined(_WIN64)
|
||||||
|
_BitScanReverse64(&r, x);
|
||||||
|
#else
|
||||||
|
// Scan the high 32 bits.
|
||||||
|
if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
|
||||||
|
return 63 - (r + 32);
|
||||||
|
|
||||||
|
// Scan the low 32 bits.
|
||||||
|
_BitScanReverse(&r, static_cast<uint32_t>(x & 0xFFFFFFFF));
|
||||||
|
#endif // _WIN64
|
||||||
|
|
||||||
|
return 63 - r;
|
||||||
|
#elif (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll)
|
||||||
|
// __builtin_clzll wrapper
|
||||||
|
return static_cast<uint32_t>(__builtin_clzll(x));
|
||||||
|
#else
|
||||||
|
// naive version
|
||||||
|
uint32_t r;
|
||||||
|
while (!(x & (static_cast<uint64_t>(1) << 63))) {
|
||||||
|
x <<= 1;
|
||||||
|
++r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
#endif // _MSC_VER
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RAPIDJSON_CLZLL RAPIDJSON_NAMESPACE::internal::clzll
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // RAPIDJSON_CLZLL_H_
|
@ -20,11 +20,11 @@
|
|||||||
#define RAPIDJSON_DIYFP_H_
|
#define RAPIDJSON_DIYFP_H_
|
||||||
|
|
||||||
#include "../rapidjson.h"
|
#include "../rapidjson.h"
|
||||||
|
#include "clzll.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
|
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#pragma intrinsic(_BitScanReverse64)
|
|
||||||
#pragma intrinsic(_umul128)
|
#pragma intrinsic(_umul128)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -100,22 +100,8 @@ struct DiyFp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DiyFp Normalize() const {
|
DiyFp Normalize() const {
|
||||||
RAPIDJSON_ASSERT(f != 0); // https://stackoverflow.com/a/26809183/291737
|
int s = static_cast<int>(clzll(f));
|
||||||
#if defined(_MSC_VER) && defined(_M_AMD64)
|
|
||||||
unsigned long index;
|
|
||||||
_BitScanReverse64(&index, f);
|
|
||||||
return DiyFp(f << (63 - index), e - (63 - index));
|
|
||||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
|
||||||
int s = __builtin_clzll(f);
|
|
||||||
return DiyFp(f << s, e - s);
|
return DiyFp(f << s, e - s);
|
||||||
#else
|
|
||||||
DiyFp res = *this;
|
|
||||||
while (!(res.f & (static_cast<uint64_t>(1) << 63))) {
|
|
||||||
res.f <<= 1;
|
|
||||||
res.e--;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DiyFp NormalizeBoundary() const {
|
DiyFp NormalizeBoundary() const {
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(padded)
|
RAPIDJSON_DIAG_OFF(padded)
|
||||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||||
RAPIDJSON_DIAG_OFF(implicit-fallthrough)
|
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
||||||
@ -32,9 +31,6 @@ RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
|
|||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
RAPIDJSON_DIAG_OFF(effc++)
|
RAPIDJSON_DIAG_OFF(effc++)
|
||||||
#if __GNUC__ >= 7
|
|
||||||
RAPIDJSON_DIAG_OFF(implicit-fallthrough)
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RAPIDJSON_REGEX_VERBOSE
|
#ifndef RAPIDJSON_REGEX_VERBOSE
|
||||||
@ -291,6 +287,7 @@ private:
|
|||||||
if (!CharacterEscape(ds, &codepoint))
|
if (!CharacterEscape(ds, &codepoint))
|
||||||
return; // Unsupported escape character
|
return; // Unsupported escape character
|
||||||
// fall through to default
|
// fall through to default
|
||||||
|
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
||||||
|
|
||||||
default: // Pattern character
|
default: // Pattern character
|
||||||
PushOperand(operandStack, codepoint);
|
PushOperand(operandStack, codepoint);
|
||||||
@ -520,6 +517,7 @@ private:
|
|||||||
else if (!CharacterEscape(ds, &codepoint))
|
else if (!CharacterEscape(ds, &codepoint))
|
||||||
return false;
|
return false;
|
||||||
// fall through to default
|
// fall through to default
|
||||||
|
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
switch (step) {
|
switch (step) {
|
||||||
@ -529,6 +527,7 @@ private:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// fall through to step 0 for other characters
|
// fall through to step 0 for other characters
|
||||||
|
RAPIDJSON_DELIBERATE_FALLTHROUGH;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "../allocators.h"
|
#include "../allocators.h"
|
||||||
#include "swap.h"
|
#include "swap.h"
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
@ -114,7 +115,7 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
|
RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
|
||||||
// Expand the stack if needed
|
// Expand the stack if needed
|
||||||
if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_))
|
if (RAPIDJSON_UNLIKELY(static_cast<std::ptrdiff_t>(sizeof(T) * count) > (stackEnd_ - stackTop_)))
|
||||||
Expand<T>(count);
|
Expand<T>(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +128,7 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
|
RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
|
||||||
RAPIDJSON_ASSERT(stackTop_);
|
RAPIDJSON_ASSERT(stackTop_);
|
||||||
RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_);
|
RAPIDJSON_ASSERT(static_cast<std::ptrdiff_t>(sizeof(T) * count) <= (stackEnd_ - stackTop_));
|
||||||
T* ret = reinterpret_cast<T*>(stackTop_);
|
T* ret = reinterpret_cast<T*>(stackTop_);
|
||||||
stackTop_ += sizeof(T) * count;
|
stackTop_ += sizeof(T) * count;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
#include <ios>
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
@ -488,10 +488,11 @@ public:
|
|||||||
v = &((*v)[t->index]);
|
v = &((*v)[t->index]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
|
typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
|
||||||
if (m == v->MemberEnd()) {
|
if (m == v->MemberEnd()) {
|
||||||
v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
|
v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
|
||||||
v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end
|
m = v->MemberEnd();
|
||||||
|
v = &(--m)->value; // Assumes AddMember() appends at the end
|
||||||
exist = false;
|
exist = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -543,7 +544,7 @@ public:
|
|||||||
switch (v->GetType()) {
|
switch (v->GetType()) {
|
||||||
case kObjectType:
|
case kObjectType:
|
||||||
{
|
{
|
||||||
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
|
typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
|
||||||
if (m == v->MemberEnd())
|
if (m == v->MemberEnd())
|
||||||
break;
|
break;
|
||||||
v = &m->value;
|
v = &m->value;
|
||||||
@ -779,7 +780,7 @@ public:
|
|||||||
switch (v->GetType()) {
|
switch (v->GetType()) {
|
||||||
case kObjectType:
|
case kObjectType:
|
||||||
{
|
{
|
||||||
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
|
typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
|
||||||
if (m == v->MemberEnd())
|
if (m == v->MemberEnd())
|
||||||
return false;
|
return false;
|
||||||
v = &m->value;
|
v = &m->value;
|
||||||
|
@ -60,7 +60,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
||||||
Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
|
Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||||
PrettyWriter(PrettyWriter&& rhs) :
|
PrettyWriter(PrettyWriter&& rhs) :
|
||||||
|
@ -490,6 +490,12 @@ RAPIDJSON_NAMESPACE_END
|
|||||||
#define RAPIDJSON_VERSION_CODE(x,y,z) \
|
#define RAPIDJSON_VERSION_CODE(x,y,z) \
|
||||||
(((x)*100000) + ((y)*100) + (z))
|
(((x)*100000) + ((y)*100) + (z))
|
||||||
|
|
||||||
|
#if defined(__has_builtin)
|
||||||
|
#define RAPIDJSON_HAS_BUILTIN(x) __has_builtin(x)
|
||||||
|
#else
|
||||||
|
#define RAPIDJSON_HAS_BUILTIN(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
|
// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
|
||||||
|
|
||||||
@ -591,6 +597,19 @@ RAPIDJSON_NAMESPACE_END
|
|||||||
#endif
|
#endif
|
||||||
#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR
|
#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// C++17 features
|
||||||
|
|
||||||
|
#if defined(__has_cpp_attribute)
|
||||||
|
# if __has_cpp_attribute(fallthrough)
|
||||||
|
# define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]]
|
||||||
|
# else
|
||||||
|
# define RAPIDJSON_DELIBERATE_FALLTHROUGH
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define RAPIDJSON_DELIBERATE_FALLTHROUGH
|
||||||
|
#endif
|
||||||
|
|
||||||
//!@endcond
|
//!@endcond
|
||||||
|
|
||||||
//! Assertion (in non-throwing contexts).
|
//! Assertion (in non-throwing contexts).
|
||||||
@ -607,15 +626,18 @@ RAPIDJSON_NAMESPACE_END
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// RAPIDJSON_NOEXCEPT_ASSERT
|
// RAPIDJSON_NOEXCEPT_ASSERT
|
||||||
|
|
||||||
|
#ifndef RAPIDJSON_NOEXCEPT_ASSERT
|
||||||
#ifdef RAPIDJSON_ASSERT_THROWS
|
#ifdef RAPIDJSON_ASSERT_THROWS
|
||||||
#if RAPIDJSON_HAS_CXX11_NOEXCEPT
|
#if RAPIDJSON_HAS_CXX11_NOEXCEPT
|
||||||
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
|
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
|
||||||
#else
|
#else
|
||||||
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
|
#include <cassert>
|
||||||
|
#define RAPIDJSON_NOEXCEPT_ASSERT(x) assert(x)
|
||||||
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
|
#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
|
||||||
#else
|
#else
|
||||||
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
|
#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
|
||||||
#endif // RAPIDJSON_ASSERT_THROWS
|
#endif // RAPIDJSON_ASSERT_THROWS
|
||||||
|
#endif // RAPIDJSON_NOEXCEPT_ASSERT
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// malloc/realloc/free
|
// malloc/realloc/free
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "allocators.h"
|
#include "allocators.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "encodedstream.h"
|
#include "encodedstream.h"
|
||||||
|
#include "internal/clzll.h"
|
||||||
#include "internal/meta.h"
|
#include "internal/meta.h"
|
||||||
#include "internal/stack.h"
|
#include "internal/stack.h"
|
||||||
#include "internal/strtod.h"
|
#include "internal/strtod.h"
|
||||||
@ -153,6 +154,7 @@ enum ParseFlag {
|
|||||||
kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings.
|
kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings.
|
||||||
kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays.
|
kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays.
|
||||||
kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
|
kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
|
||||||
|
kParseEscapedApostropheFlag = 512, //!< Allow escaped apostrophe in strings.
|
||||||
kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
|
kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -443,16 +445,16 @@ inline const char *SkipWhitespace_SIMD(const char* p) {
|
|||||||
|
|
||||||
x = vmvnq_u8(x); // Negate
|
x = vmvnq_u8(x); // Negate
|
||||||
x = vrev64q_u8(x); // Rev in 64
|
x = vrev64q_u8(x); // Rev in 64
|
||||||
uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
|
uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
|
uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract
|
||||||
|
|
||||||
if (low == 0) {
|
if (low == 0) {
|
||||||
if (high != 0) {
|
if (high != 0) {
|
||||||
int lz =__builtin_clzll(high);;
|
uint32_t lz = internal::clzll(high);
|
||||||
return p + 8 + (lz >> 3);
|
return p + 8 + (lz >> 3);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int lz = __builtin_clzll(low);;
|
uint32_t lz = internal::clzll(low);
|
||||||
return p + (lz >> 3);
|
return p + (lz >> 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -479,16 +481,16 @@ inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
|
|||||||
|
|
||||||
x = vmvnq_u8(x); // Negate
|
x = vmvnq_u8(x); // Negate
|
||||||
x = vrev64q_u8(x); // Rev in 64
|
x = vrev64q_u8(x); // Rev in 64
|
||||||
uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
|
uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
|
uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract
|
||||||
|
|
||||||
if (low == 0) {
|
if (low == 0) {
|
||||||
if (high != 0) {
|
if (high != 0) {
|
||||||
int lz = __builtin_clzll(high);
|
uint32_t lz = internal::clzll(high);
|
||||||
return p + 8 + (lz >> 3);
|
return p + 8 + (lz >> 3);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int lz = __builtin_clzll(low);
|
uint32_t lz = internal::clzll(low);
|
||||||
return p + (lz >> 3);
|
return p + (lz >> 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1013,6 +1015,10 @@ private:
|
|||||||
is.Take();
|
is.Take();
|
||||||
os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
|
os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
|
||||||
}
|
}
|
||||||
|
else if ((parseFlags & kParseEscapedApostropheFlag) && RAPIDJSON_LIKELY(e == '\'')) { // Allow escaped apostrophe
|
||||||
|
is.Take();
|
||||||
|
os.Put('\'');
|
||||||
|
}
|
||||||
else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode
|
else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode
|
||||||
is.Take();
|
is.Take();
|
||||||
unsigned codepoint = ParseHex4(is, escapeOffset);
|
unsigned codepoint = ParseHex4(is, escapeOffset);
|
||||||
@ -1244,19 +1250,19 @@ private:
|
|||||||
x = vorrq_u8(x, vcltq_u8(s, s3));
|
x = vorrq_u8(x, vcltq_u8(s, s3));
|
||||||
|
|
||||||
x = vrev64q_u8(x); // Rev in 64
|
x = vrev64q_u8(x); // Rev in 64
|
||||||
uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
|
uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
|
uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract
|
||||||
|
|
||||||
SizeType length = 0;
|
SizeType length = 0;
|
||||||
bool escaped = false;
|
bool escaped = false;
|
||||||
if (low == 0) {
|
if (low == 0) {
|
||||||
if (high != 0) {
|
if (high != 0) {
|
||||||
unsigned lz = (unsigned)__builtin_clzll(high);;
|
uint32_t lz = internal::clzll(high);
|
||||||
length = 8 + (lz >> 3);
|
length = 8 + (lz >> 3);
|
||||||
escaped = true;
|
escaped = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unsigned lz = (unsigned)__builtin_clzll(low);;
|
uint32_t lz = internal::clzll(low);
|
||||||
length = lz >> 3;
|
length = lz >> 3;
|
||||||
escaped = true;
|
escaped = true;
|
||||||
}
|
}
|
||||||
@ -1314,19 +1320,19 @@ private:
|
|||||||
x = vorrq_u8(x, vcltq_u8(s, s3));
|
x = vorrq_u8(x, vcltq_u8(s, s3));
|
||||||
|
|
||||||
x = vrev64q_u8(x); // Rev in 64
|
x = vrev64q_u8(x); // Rev in 64
|
||||||
uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
|
uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
|
uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract
|
||||||
|
|
||||||
SizeType length = 0;
|
SizeType length = 0;
|
||||||
bool escaped = false;
|
bool escaped = false;
|
||||||
if (low == 0) {
|
if (low == 0) {
|
||||||
if (high != 0) {
|
if (high != 0) {
|
||||||
unsigned lz = (unsigned)__builtin_clzll(high);
|
uint32_t lz = internal::clzll(high);
|
||||||
length = 8 + (lz >> 3);
|
length = 8 + (lz >> 3);
|
||||||
escaped = true;
|
escaped = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unsigned lz = (unsigned)__builtin_clzll(low);
|
uint32_t lz = internal::clzll(low);
|
||||||
length = lz >> 3;
|
length = lz >> 3;
|
||||||
escaped = true;
|
escaped = true;
|
||||||
}
|
}
|
||||||
@ -1370,17 +1376,17 @@ private:
|
|||||||
x = vorrq_u8(x, vcltq_u8(s, s3));
|
x = vorrq_u8(x, vcltq_u8(s, s3));
|
||||||
|
|
||||||
x = vrev64q_u8(x); // Rev in 64
|
x = vrev64q_u8(x); // Rev in 64
|
||||||
uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
|
uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
|
uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract
|
||||||
|
|
||||||
if (low == 0) {
|
if (low == 0) {
|
||||||
if (high != 0) {
|
if (high != 0) {
|
||||||
int lz = __builtin_clzll(high);
|
uint32_t lz = internal::clzll(high);
|
||||||
p += 8 + (lz >> 3);
|
p += 8 + (lz >> 3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int lz = __builtin_clzll(low);
|
uint32_t lz = internal::clzll(low);
|
||||||
p += lz >> 3;
|
p += lz >> 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -443,7 +443,6 @@ public:
|
|||||||
exclusiveMaximum_(false),
|
exclusiveMaximum_(false),
|
||||||
defaultValueLength_(0)
|
defaultValueLength_(0)
|
||||||
{
|
{
|
||||||
typedef typename SchemaDocumentType::ValueType ValueType;
|
|
||||||
typedef typename ValueType::ConstValueIterator ConstValueIterator;
|
typedef typename ValueType::ConstValueIterator ConstValueIterator;
|
||||||
typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
|
typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
|
||||||
|
|
||||||
@ -899,7 +898,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SizeType index;
|
SizeType index = 0;
|
||||||
if (FindPropertyIndex(ValueType(str, len).Move(), &index)) {
|
if (FindPropertyIndex(ValueType(str, len).Move(), &index)) {
|
||||||
if (context.patternPropertiesSchemaCount > 0) {
|
if (context.patternPropertiesSchemaCount > 0) {
|
||||||
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema;
|
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema;
|
||||||
@ -1149,7 +1148,7 @@ private:
|
|||||||
#elif RAPIDJSON_SCHEMA_USE_STDREGEX
|
#elif RAPIDJSON_SCHEMA_USE_STDREGEX
|
||||||
template <typename ValueType>
|
template <typename ValueType>
|
||||||
RegexType* CreatePattern(const ValueType& value) {
|
RegexType* CreatePattern(const ValueType& value) {
|
||||||
if (value.IsString())
|
if (value.IsString()) {
|
||||||
RegexType *r = static_cast<RegexType*>(allocator_->Malloc(sizeof(RegexType)));
|
RegexType *r = static_cast<RegexType*>(allocator_->Malloc(sizeof(RegexType)));
|
||||||
try {
|
try {
|
||||||
return new (r) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript);
|
return new (r) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript);
|
||||||
@ -1157,6 +1156,7 @@ private:
|
|||||||
catch (const std::regex_error&) {
|
catch (const std::regex_error&) {
|
||||||
AllocatorType::Free(r);
|
AllocatorType::Free(r);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#define RAPIDJSON_WRITER_H_
|
#define RAPIDJSON_WRITER_H_
|
||||||
|
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
|
#include "internal/clzll.h"
|
||||||
#include "internal/meta.h"
|
#include "internal/meta.h"
|
||||||
#include "internal/stack.h"
|
#include "internal/stack.h"
|
||||||
#include "internal/strfunc.h"
|
#include "internal/strfunc.h"
|
||||||
@ -282,6 +283,8 @@ public:
|
|||||||
os_->Flush();
|
os_->Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const size_t kDefaultLevelDepth = 32;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! Information for each nested level
|
//! Information for each nested level
|
||||||
struct Level {
|
struct Level {
|
||||||
@ -290,8 +293,6 @@ protected:
|
|||||||
bool inArray; //!< true if in array, otherwise in object
|
bool inArray; //!< true if in array, otherwise in object
|
||||||
};
|
};
|
||||||
|
|
||||||
static const size_t kDefaultLevelDepth = 32;
|
|
||||||
|
|
||||||
bool WriteNull() {
|
bool WriteNull() {
|
||||||
PutReserve(*os_, 4);
|
PutReserve(*os_, 4);
|
||||||
PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true;
|
PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true;
|
||||||
@ -668,19 +669,19 @@ inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, siz
|
|||||||
x = vorrq_u8(x, vcltq_u8(s, s3));
|
x = vorrq_u8(x, vcltq_u8(s, s3));
|
||||||
|
|
||||||
x = vrev64q_u8(x); // Rev in 64
|
x = vrev64q_u8(x); // Rev in 64
|
||||||
uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
|
uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0); // extract
|
||||||
uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
|
uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1); // extract
|
||||||
|
|
||||||
SizeType len = 0;
|
SizeType len = 0;
|
||||||
bool escaped = false;
|
bool escaped = false;
|
||||||
if (low == 0) {
|
if (low == 0) {
|
||||||
if (high != 0) {
|
if (high != 0) {
|
||||||
unsigned lz = (unsigned)__builtin_clzll(high);
|
uint32_t lz = internal::clzll(high);
|
||||||
len = 8 + (lz >> 3);
|
len = 8 + (lz >> 3);
|
||||||
escaped = true;
|
escaped = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unsigned lz = (unsigned)__builtin_clzll(low);
|
uint32_t lz = internal::clzll(low);
|
||||||
len = lz >> 3;
|
len = lz >> 3;
|
||||||
escaped = true;
|
escaped = true;
|
||||||
}
|
}
|
||||||
|
50
readme.md
50
readme.md
@ -72,6 +72,9 @@ Users can build and run the unit tests on their platform/compiler.
|
|||||||
|
|
||||||
RapidJSON is a header-only C++ library. Just copy the `include/rapidjson` folder to system or project's include path.
|
RapidJSON is a header-only C++ library. Just copy the `include/rapidjson` folder to system or project's include path.
|
||||||
|
|
||||||
|
Alternatively, if you are using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager you can download and install rapidjson with CMake integration in a single command:
|
||||||
|
* vcpkg install rapidjson
|
||||||
|
|
||||||
RapidJSON uses following software as its dependencies:
|
RapidJSON uses following software as its dependencies:
|
||||||
* [CMake](https://cmake.org/) as a general build tool
|
* [CMake](https://cmake.org/) as a general build tool
|
||||||
* (optional) [Doxygen](http://www.doxygen.org) to build documentation
|
* (optional) [Doxygen](http://www.doxygen.org) to build documentation
|
||||||
@ -158,3 +161,50 @@ More [examples](https://github.com/Tencent/rapidjson/tree/master/example) are av
|
|||||||
* [parsebyparts](https://github.com/Tencent/rapidjson/blob/master/example/parsebyparts/parsebyparts.cpp): Implements an `AsyncDocumentParser` which can parse JSON in parts, using C++11 thread.
|
* [parsebyparts](https://github.com/Tencent/rapidjson/blob/master/example/parsebyparts/parsebyparts.cpp): Implements an `AsyncDocumentParser` which can parse JSON in parts, using C++11 thread.
|
||||||
* [filterkey](https://github.com/Tencent/rapidjson/blob/master/example/filterkey/filterkey.cpp): A command line tool to remove all values with user-specified key.
|
* [filterkey](https://github.com/Tencent/rapidjson/blob/master/example/filterkey/filterkey.cpp): A command line tool to remove all values with user-specified key.
|
||||||
* [filterkeydom](https://github.com/Tencent/rapidjson/blob/master/example/filterkeydom/filterkeydom.cpp): Same tool as above, but it demonstrates how to use a generator to populate a `Document`.
|
* [filterkeydom](https://github.com/Tencent/rapidjson/blob/master/example/filterkeydom/filterkeydom.cpp): Same tool as above, but it demonstrates how to use a generator to populate a `Document`.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
RapidJSON welcomes contributions. When contributing, please follow the code below.
|
||||||
|
|
||||||
|
### Issues
|
||||||
|
|
||||||
|
Feel free to submit issues and enhancement requests.
|
||||||
|
|
||||||
|
Please help us by providing **minimal reproducible examples**, because source code is easier to let other people understand what happens.
|
||||||
|
For crash problems on certain platforms, please bring stack dump content with the detail of the OS, compiler, etc.
|
||||||
|
|
||||||
|
Please try breakpoint debugging first, tell us what you found, see if we can start exploring based on more information been prepared.
|
||||||
|
|
||||||
|
### Workflow
|
||||||
|
|
||||||
|
In general, we follow the "fork-and-pull" Git workflow.
|
||||||
|
|
||||||
|
1. **Fork** the repo on GitHub
|
||||||
|
2. **Clone** the project to your own machine
|
||||||
|
3. **Checkout** a new branch on your fork, start developing on the branch
|
||||||
|
4. **Test** the change before commit, Make sure the changes pass all the tests, including `unittest` and `preftest`, please add test case for each new feature or bug-fix if needed.
|
||||||
|
5. **Commit** changes to your own branch
|
||||||
|
6. **Push** your work back up to your fork
|
||||||
|
7. Submit a **Pull request** so that we can review your changes
|
||||||
|
|
||||||
|
NOTE: Be sure to merge the latest from "upstream" before making a pull request!
|
||||||
|
|
||||||
|
### Copyright and Licensing
|
||||||
|
|
||||||
|
You can copy and paste the license summary from below.
|
||||||
|
|
||||||
|
```
|
||||||
|
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.
|
||||||
|
```
|
@ -674,6 +674,9 @@ TEST(Pointer, Get) {
|
|||||||
EXPECT_EQ(2u, unresolvedTokenIndex);
|
EXPECT_EQ(2u, unresolvedTokenIndex);
|
||||||
EXPECT_TRUE(Pointer("/foo/0/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
|
EXPECT_TRUE(Pointer("/foo/0/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
|
||||||
EXPECT_EQ(2u, unresolvedTokenIndex);
|
EXPECT_EQ(2u, unresolvedTokenIndex);
|
||||||
|
|
||||||
|
Pointer::Token tokens[] = { { "foo ...", 3, kPointerInvalidIndex } };
|
||||||
|
EXPECT_EQ(&d["foo"], Pointer(tokens, 1).Get(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Pointer, GetWithDefault) {
|
TEST(Pointer, GetWithDefault) {
|
||||||
|
@ -2198,4 +2198,28 @@ TEST(Reader, ParseNanAndInfinity) {
|
|||||||
#undef TEST_NAN_INF
|
#undef TEST_NAN_INF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Reader, EscapedApostrophe) {
|
||||||
|
const char json[] = " { \"foo\": \"bar\\'buzz\" } ";
|
||||||
|
|
||||||
|
BaseReaderHandler<> h;
|
||||||
|
|
||||||
|
{
|
||||||
|
StringStream s(json);
|
||||||
|
Reader reader;
|
||||||
|
ParseResult r = reader.Parse<kParseNoFlags>(s, h);
|
||||||
|
EXPECT_TRUE(reader.HasParseError());
|
||||||
|
EXPECT_EQ(kParseErrorStringEscapeInvalid, r.Code());
|
||||||
|
EXPECT_EQ(14u, r.Offset());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
StringStream s(json);
|
||||||
|
Reader reader;
|
||||||
|
ParseResult r = reader.Parse<kParseEscapedApostropheFlag>(s, h);
|
||||||
|
EXPECT_FALSE(reader.HasParseError());
|
||||||
|
EXPECT_EQ(kParseErrorNone, r.Code());
|
||||||
|
EXPECT_EQ(0u, r.Offset());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
|
@ -122,6 +122,9 @@ public:
|
|||||||
|
|
||||||
#ifndef RAPIDJSON_ASSERT
|
#ifndef RAPIDJSON_ASSERT
|
||||||
#define RAPIDJSON_ASSERT(x) (!(x) ? throw AssertException(RAPIDJSON_STRINGIFY(x)) : (void)0u)
|
#define RAPIDJSON_ASSERT(x) (!(x) ? throw AssertException(RAPIDJSON_STRINGIFY(x)) : (void)0u)
|
||||||
|
#ifndef RAPIDJSON_ASSERT_THROWS
|
||||||
|
#define RAPIDJSON_ASSERT_THROWS
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Random {
|
class Random {
|
||||||
|
@ -4,9 +4,8 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
DOXYGEN_VER=doxygen-1.8.13
|
DOXYGEN_VER=1_8_16
|
||||||
DOXYGEN_TAR=${DOXYGEN_VER}.linux.bin.tar.gz
|
DOXYGEN_URL="https://codeload.github.com/doxygen/doxygen/tar.gz/Release_${DOXYGEN_VER}"
|
||||||
DOXYGEN_URL="http://ftp.stack.nl/pub/users/dimitri/${DOXYGEN_TAR}"
|
|
||||||
|
|
||||||
: ${GITHUB_REPO:="Tencent/rapidjson"}
|
: ${GITHUB_REPO:="Tencent/rapidjson"}
|
||||||
GITHUB_HOST="github.com"
|
GITHUB_HOST="github.com"
|
||||||
@ -47,9 +46,17 @@ abort() {
|
|||||||
# install doxygen binary distribution
|
# install doxygen binary distribution
|
||||||
doxygen_install()
|
doxygen_install()
|
||||||
{
|
{
|
||||||
wget -O - "${DOXYGEN_URL}" | \
|
cd ${TMPDIR-/tmp}
|
||||||
tar xz -C ${TMPDIR-/tmp} ${DOXYGEN_VER}/bin/doxygen
|
curl ${DOXYGEN_URL} -o doxygen.tar.gz
|
||||||
export PATH="${TMPDIR-/tmp}/${DOXYGEN_VER}/bin:$PATH"
|
tar zxvf doxygen.tar.gz
|
||||||
|
mkdir doxygen_build
|
||||||
|
cd doxygen_build
|
||||||
|
cmake ../doxygen-Release_${DOXYGEN_VER}/
|
||||||
|
make
|
||||||
|
|
||||||
|
export PATH="${TMPDIR-/tmp}/doxygen_build/bin:$PATH"
|
||||||
|
|
||||||
|
cd ../../
|
||||||
}
|
}
|
||||||
|
|
||||||
doxygen_run()
|
doxygen_run()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user