Commit 36434b66 authored by thebusytypist's avatar thebusytypist

Merge remote-tracking branch 'upstream/master' into TransitionTable

parents 70d01cc5 e440b695
......@@ -5,5 +5,6 @@
/build/*.exe
/build/gmake
/build/vs*/
/doc/html
/thirdparty/lib
/intermediate
......@@ -5,8 +5,11 @@ compiler:
- gcc
env:
- config=debug64 config_suffix=debug_x64_gmake
- config=release64 config_suffix=release_x64_gmake
matrix:
- config=debug64 config_suffix=debug_x64_gmake
- config=release64 config_suffix=release_x64_gmake
global:
secure: "CR3yKliFhwQLX+Zs1PCRcGej6jr4DIZsCqs9x6J2NN+U9Aow0gd/uiPBho/utgm+/TmSBji5n8FO/J3ORo34q4gC6EebTEaN4gCHNXVlIBJFw9x+Gs/lML5i8F2AoweFJY334OVaOf9qC8ZVJ8Z1nEwxj77fq3gcSLzRU3pIaS8="
before_install:
- sudo add-apt-repository -y ppa:codegear/release
......@@ -16,14 +19,14 @@ before_install:
install: true
before_script:
- cd build
- premake4 'gmake'
- cd "${TRAVIS_BUILD_DIR}"
- pushd build && premake4 'gmake' && popd
script:
- make -C build/gmake -f test.make
- make -C build/gmake -f example.make
- cd bin
- make -C build/gmake -f example.make
- pushd bin
- ./unittest_${config_suffix}
- valgrind --leak-check=full --error-exitcode=1 ./unittest_${config_suffix}
- ./perftest_${config_suffix}
- if [ "$config" = "release64" ]; then ./perftest_${config_suffix}; fi
- popd
- ./build/travis-doxygen.sh;
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -64,7 +64,7 @@ solution "test"
defines { "_CRT_SECURE_NO_WARNINGS" }
configuration "gmake"
buildoptions "-msse4.2 -Werror -Wall -Wextra -Wswitch-default"
buildoptions "-msse4.2 -Werror -Wall -Wextra"
project "gtest"
kind "StaticLib"
......@@ -87,7 +87,7 @@ solution "test"
kind "ConsoleApp"
if _ACTION == "gmake" then
buildoptions "-Weffc++"
buildoptions "-Weffc++ -Wswitch-default"
end
files {
......
#!/bin/bash
# Update Doxygen documentation after push to 'master'.
# Author: @pah
set -e
SUDO=sudo
DOXYGEN_VER=doxygen-1.8.7
DOXYGEN_TAR=${DOXYGEN_VER}.linux.bin.tar.gz
DOXYGEN_URL="http://ftp.stack.nl/pub/users/dimitri/${DOXYGEN_TAR}"
DOXYGEN_BIN="/usr/local/bin/doxygen"
GHPAGES_REPO="miloyip/rapidjson"
GHPAGES_URL="https://github.com/${GHPAGES_REPO}"
skip() {
echo "$@" 1>&2
echo "Exiting..." 1>&2
exit 0
}
abort() {
echo "Error: $@" 1>&2
echo "Exiting..." 1>&2
exit 1
}
# TRAVIS_BUILD_DIR not set, exiting
[ -d "${TRAVIS_BUILD_DIR-/nonexistent}" ] || \
abort '${TRAVIS_BUILD_DIR} not set or nonexistent.'
# check for pull-requests
[ "${TRAVIS_PULL_REQUEST}" = "false" ] || \
skip "Not running Doxygen for pull-requests."
# check for branch name
[ "${TRAVIS_BRANCH}" = "master" ] || \
skip "Running Doxygen only for updates on 'master' branch (current: ${TRAVIS_BRANCH})."
# check for job number
[ "${TRAVIS_JOB_NUMBER}" = "${TRAVIS_BUILD_NUMBER}.1" ] || \
skip "Running Doxygen only on first job of build ${TRAVIS_BUILD_NUMBER} (current: ${TRAVIS_JOB_NUMBER})."
# install doxygen binary distribution
doxygen_install()
{
wget -O - "${DOXYGEN_URL}" | \
tar xz -C ${TMPDIR-/tmp} ${DOXYGEN_VER}/bin/doxygen
$SUDO install -m 755 ${TMPDIR-/tmp}/${DOXYGEN_VER}/bin/doxygen \
${DOXYGEN_BIN};
}
doxygen_run()
{
cd "${TRAVIS_BUILD_DIR}";
doxygen build/Doxyfile;
}
gh_pages_prepare()
{
cd "${TRAVIS_BUILD_DIR}/doc";
[ ! -d "html" ] || \
abort "Doxygen target directory already exists."
git clone --single-branch -b gh-pages ${GHPAGES_URL} html
cd html
# setup git config (with defaults)
git config user.name "${GIT_NAME-travis}"
git config user.email "${GIT_EMAIL-"travis@localhost"}"
# clean working dir
rm -f .git/index
git clean -df
}
gh_pages_commit() {
cd "${TRAVIS_BUILD_DIR}/doc/html";
git add --all;
git diff-index --quiet HEAD || git commit -m "Automatic doxygen build";
}
gh_pages_push() {
# check for secure variables
[ "${TRAVIS_SECURE_ENV_VARS}" = "true" ] || \
skip "Secure variables not available, not updating GitHub pages."
[ "${GH_TOKEN+set}" = set ] || \
skip "GitHub access token not available, not updating GitHub pages."
cd "${TRAVIS_BUILD_DIR}/doc/html";
# setup credentials (hide in "set -x" mode)
git config core.askpass /bin/true
( set +x ; git config credential.${GHPAGES_URL}.username "${GH_TOKEN}" )
# push to GitHub
git push origin gh-pages
}
doxygen_install
gh_pages_prepare
doxygen_run
gh_pages_commit
gh_pages_push
digraph {
compound=true
fontname="Inconsolata, Consolas"
fontsize=10
margin="0,0"
ranksep=0.2
penwidth=0.5
node [fontname="Inconsolata, Consolas", fontsize=10, penwidth=0.5]
edge [fontname="Inconsolata, Consolas", fontsize=10, arrowhead=normal]
{
node [shape=record, fontsize="8", margin="0.04", height=0.2, color=gray]
oldjson [label="\{|\"|m|s|g|\"|:|\"|H|e|l|l|o|\\|n|W|o|r|l|d|!|\"|,|\"|\\|u|0|0|7|3|t|a|r|s|\"|:|1|0|\}", xlabel="Before Parsing"]
//newjson [label="\{|\"|<a>m|s|g|\\0|:|\"|<b>H|e|l|l|o|\\n|W|o|r|l|d|!|\\0|\"|,|\"|<c>s|t|a|r|s|\\0|t|a|r|s|:|1|0|\}", xlabel="After Parsing"]
newjson [shape=plaintext, label=<
<table BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="2"><tr>
<td>{</td>
<td>"</td><td port="a">m</td><td>s</td><td>g</td><td bgcolor="yellow">\\0</td>
<td>:</td>
<td>"</td><td port="b">H</td><td>e</td><td>l</td><td>l</td><td>o</td><td bgcolor="yellow">\\n</td><td bgcolor="yellow">W</td><td bgcolor="yellow">o</td><td bgcolor="yellow">r</td><td bgcolor="yellow">l</td><td bgcolor="yellow">d</td><td bgcolor="yellow">!</td><td bgcolor="yellow">\\0</td><td>"</td>
<td>,</td>
<td>"</td><td port="c" bgcolor="yellow">s</td><td bgcolor="yellow">t</td><td bgcolor="yellow">a</td><td bgcolor="yellow">r</td><td bgcolor="yellow">s</td><td bgcolor="yellow">\\0</td><td>t</td><td>a</td><td>r</td><td>s</td>
<td>:</td>
<td>1</td><td>0</td>
<td>}</td>
</tr></table>
>, xlabel="After Parsing"]
}
subgraph cluster1 {
margin="10,10"
labeljust="left"
label = "Document by In situ Parsing"
style=filled
fillcolor=gray95
node [shape=Mrecord, style=filled, colorscheme=spectral7]
root [label="{object|}", fillcolor=3]
{
msg [label="{string|<a>}", fillcolor=5]
helloworld [label="{string|<a>}", fillcolor=5]
stars [label="{string|<a>}", fillcolor=5]
ten [label="{number|10}", fillcolor=6]
}
}
oldjson -> root [label=" ParseInsitu()" lhead="cluster1"]
edge [arrowhead=vee]
root -> { msg; stars }
edge [arrowhead="none"]
msg -> helloworld
stars -> ten
{
edge [arrowhead=vee, arrowtail=dot, arrowsize=0.5, dir=both, tailclip=false]
msg:a:c -> newjson:a
helloworld:a:c -> newjson:b
stars:a:c -> newjson:c
}
//oldjson -> newjson [style=invis]
}
\ No newline at end of file
digraph {
compound=true
fontname="Inconsolata, Consolas"
fontsize=10
margin="0,0"
ranksep=0.2
penwidth=0.5
node [fontname="Inconsolata, Consolas", fontsize=10, penwidth=0.5]
edge [fontname="Inconsolata, Consolas", fontsize=10, arrowhead=normal]
{
node [shape=record, fontsize="8", margin="0.04", height=0.2, color=gray]
normaljson [label="\{|\"|m|s|g|\"|:|\"|H|e|l|l|o|\\|n|W|o|r|l|d|!|\"|,|\"|\\|u|0|0|7|3|t|a|r|s\"|:|1|0|\}"]
{
rank = same
msgstring [label="m|s|g|\\0"]
helloworldstring [label="H|e|l|l|o|\\n|W|o|r|l|d|!|\\0"]
starsstring [label="s|t|a|r|s\\0"]
}
}
subgraph cluster1 {
margin="10,10"
labeljust="left"
label = "Document by Normal Parsing"
style=filled
fillcolor=gray95
node [shape=Mrecord, style=filled, colorscheme=spectral7]
root [label="{object|}", fillcolor=3]
{
msg [label="{string|<a>}", fillcolor=5]
helloworld [label="{string|<a>}", fillcolor=5]
stars [label="{string|<a>}", fillcolor=5]
ten [label="{number|10}", fillcolor=6]
}
}
normaljson -> root [label=" Parse()" lhead="cluster1"]
edge [arrowhead=vee]
root -> { msg; stars }
edge [arrowhead="none"]
msg -> helloworld
stars -> ten
edge [arrowhead=vee, arrowtail=dot, arrowsize=0.5, dir=both, tailclip=false]
msg:a:c -> msgstring:w
helloworld:a:c -> helloworldstring:w
stars:a:c -> starsstring:w
msgstring -> helloworldstring -> starsstring [style=invis]
}
\ No newline at end of file
This diff is collapsed.
# RapidJSON Encoding
# Encoding
## Unicode
......
# RapidJSON FAQ
# FAQ
## General
......
# RapidJSON Features
# Features
## General
......@@ -39,10 +39,10 @@
## API styles
* SAX (Simple API for XML) style API
* Similar to [SAX](http://en.wikipedia.org/wiki/Simple_API_for_XML), RapidJSON provides a event sequential access parser API (`GenericReader`). It also provides a generator API (`GenericWriter`) which consumes the same set of events.
* Similar to [SAX](http://en.wikipedia.org/wiki/Simple_API_for_XML), RapidJSON provides a event sequential access parser API (`rapidjson::GenericReader`). It also provides a generator API (`rapidjson::Writer`) which consumes the same set of events.
* DOM (Document Object Model) style API
* Similar to [DOM](http://en.wikipedia.org/wiki/Document_Object_Model) for HTML/XML, RapidJSON can parse JSON into a DOM representation (`GenericDocument`), for easy manipulation, and finally stringify back to JSON if needed.
* The DOM style API (`GenericDocument`) is actually implemented with SAX style API (`GenericReader`). SAX is faster but sometimes DOM is easier. Users can pick their choices according to scenarios.
* Similar to [DOM](http://en.wikipedia.org/wiki/Document_Object_Model) for HTML/XML, RapidJSON can parse JSON into a DOM representation (`rapidjson::GenericDocument`), for easy manipulation, and finally stringify back to JSON if needed.
* The DOM style API (`rapidjson::GenericDocument`) is actually implemented with SAX style API (`rapidjson::GenericReader`). SAX is faster but sometimes DOM is easier. Users can pick their choices according to scenarios.
## DOM (Document)
......@@ -59,13 +59,13 @@
## SAX (Writer)
* Support PrettyWriter for adding newlines and indentations.
* Support `rapidjson::PrettyWriter` for adding newlines and indentations.
* Support custom precision for floating point values.
## Stream
* Support `GenericStringBuffer` for storing the output JSON as string.
* Support `FileReadStream`/`FileWriteStream` for input/output `FILE` object.
* Support `rapidjson::GenericStringBuffer` for storing the output JSON as string.
* Support `rapidjson::FileReadStream` and `rapidjson::FileWriteStream` for input/output `FILE` object.
* Support custom streams.
## Memory
......
# RapidJSON Internals
# Internals
This section records some design and implementation details.
......
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.8.7 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="yes" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="yes" title="">
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>
body code {
margin: 0;
border: 1px solid #ddd;
background-color: #f8f8f8;
border-radius: 3px;
padding: 0;
}
a {
color: #4183c4;
}
a.el {
font-weight: normal;
}
body, table, div, p, dl {
color: #333333;
font-family: Helvetica, arial, freesans, clean, sans-serif, 'Segoe UI Emoji', 'Segoe UI Symbol';
font-size: 15px;
font-style: normal;
font-variant: normal;
font-weight: normal;
line-height: 25.5px;
}
body {
background-color: #eee;
}
div.header {
background-image: none;
background-color: white;
margin: 0px;
border: 0px;
}
div.headertitle {
width: 858px;
margin: 30px;
padding: 0px;
}
div.toc {
background-color: #f8f8f8;
border-color: #ddd;
margin-right: 10px;
margin-left: 20px;
}
div.toc h3 {
color: #333333;
font-family: Helvetica, arial, freesans, clean, sans-serif, 'Segoe UI Emoji', 'Segoe UI Symbol';
font-size: 18px;
font-style: normal;
font-variant: normal;
font-weight: normal;
}
div.toc li {
color: #333333;
font-family: Helvetica, arial, freesans, clean, sans-serif, 'Segoe UI Emoji', 'Segoe UI Symbol';
font-size: 12px;
font-style: normal;
font-variant: normal;
font-weight: normal;
}
.title {
font-size: 2.5em;
line-height: 63.75px;
border-bottom: 1px solid #ddd;
margin-bottom: 15px;
margin-left: 0px;
margin-right: 0px;
margin-top: 0px;
}
body h1 {
font-size: 2em;
line-height: 1.7;
border-bottom: 1px solid #eee;
margin: 1em 0 15px;
padding: 0;
overflow: hidden;
}
body h2 {
font-size: 1.5em;
line-height: 1.7;
margin: 1em 0 15px;
padding: 0;
}
pre.fragment {
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
font-size: 13px;
font-style: normal;
font-variant: normal;
font-weight: normal;
line-height: 19px;
}
table.doxtable th {
background-color: #f8f8f8;
color: #333333;
font-size: 15px;
}
table.doxtable td, table.doxtable th {
border: 1px solid #ddd;
}
#doc-content {
background-color: #fff;
width: 918px;
height: auto !important;
}
div.contents {
width: 858px;
margin: 30px;
}
div.line {
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
font-size: 13px;
font-style: normal;
font-variant: normal;
font-weight: normal;
line-height: 19px;
}
tt, code, pre {
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 12px;
}
div.fragment {
background-color: #f8f8f8;
border: 1px solid #ddd;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px;
}
#topbanner {
position: fixed;
margin: 15px;
z-index: 101;
}
#projectname
{
font-family: Helvetica, arial, freesans, clean, sans-serif, 'Segoe UI Emoji', 'Segoe UI Symbol';
font-size: 38px;
font-weight: bold;
line-height: 63.75px;
margin: 0px;
padding: 2px 0px;
}
#projectbrief
{
font-family: Helvetica, arial, freesans, clean, sans-serif, 'Segoe UI Emoji', 'Segoe UI Symbol';
font-size: 16px;
line-height: 22.4px;
margin: 0px 0px 13px 0px;
padding: 2px;
}
/* side bar and search */
#side-nav
{
padding: 10px 0px 20px 20px;
border-top: 60px solid #2980b9;
background-color: #343131;
width: 250px !important;
position: fixed
}
#nav-tree
{
background-color: transparent;
background-image: none;
height: 100% !important;
}
#nav-tree .label
{
font-family: Helvetica, arial, freesans, clean, sans-serif, 'Segoe UI Emoji', 'Segoe UI Symbol';
line-height: 25.5px;
font-size: 15px;
}
#nav-tree
{
color: #b3b3b3;
}
#nav-tree .selected {
background-image: none;
}
#nav-tree a
{
color: #b3b3b3;
}
#github
{
position: fixed;
left: auto;
right: auto;
width: 250px;
}
#MSearchBox
{
margin: 20px;
left: 40px;
right: auto;
position: fixed;
width: 180px;
}
#MSearchField
{
width: 121px;
}
#MSearchResultsWindow
{
left: 45px !important;
}
#nav-sync
{
display: none;
}
.ui-resizable .ui-resizable-handle
{
width: 0px;
}
#nav-path
{
display: none;
}
/* external link icon */
div.contents a[href ^= "http"]:after {
content: " " url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAVklEQVR4Xn3PgQkAMQhDUXfqTu7kTtkpd5RA8AInfArtQ2iRXFWT2QedAfttj2FsPIOE1eCOlEuoWWjgzYaB/IkeGOrxXhqB+uA9Bfcm0lAZuh+YIeAD+cAqSz4kCMUAAAAASUVORK5CYII=);
}
.githublogo {
content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RERCMUIwOUY4NkNFMTFFM0FBNTJFRTMzNTJEMUJDNDYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RERCMUIwOUU4NkNFMTFFM0FBNTJFRTMzNTJEMUJDNDYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkU1MTc4QTJBOTlBMDExRTI5QTE1QkMxMDQ2QTg5MDREIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkU1MTc4QTJCOTlBMDExRTI5QTE1QkMxMDQ2QTg5MDREIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+jUqS1wAAApVJREFUeNq0l89rE1EQx3e3gVJoSPzZeNEWPKgHoa0HBak0iHiy/4C3WvDmoZ56qJ7txVsPQu8qlqqHIhRKJZceesmhioQEfxTEtsoSpdJg1u/ABJ7Pmc1m8zLwgWTmzcw3L+/te+tHUeQltONgCkyCi2AEDHLsJ6iBMlgHL8FeoqokoA2j4CloRMmtwTmj7erHBXPgCWhG6a3JNXKdCiDl1cidVbXZkJoXQRi5t5BrxwoY71FzU8S4JuAIqFkJ2+BFSlEh525b/hr3+k/AklDkNsf6wTT4yv46KIMNpsy+iMdMc47HNWxbsgVcUn7FmLAzzoFAWDsBx+wVP6bUpp5ewI+DOeUx0Wd9D8F70BTGNjkWtqnhmT1JQAHcUgZd8Lo3rQb1LAT8eJVUfgGvHQigGp+V2Z0iAUUl8QH47kAA1XioxIo+bRN8OG8F/oBjwv+Z1nJgX5jpdzQDw0LCjsPmrcW7I/iHScCAEDj03FtD8A0EyuChHgg4KTlJQF3wZ7WELppnBX+dBFSVpJsOBWi1qiRgSwnOgoyD5hmuJdkWCVhTgnTvW3AgYIFrSbZGh0UW/Io5Vp+DQoK7o80pztWMemZbgxeNwCNwDbw1fIfgGZjhU6xPaJgBV8BdsMw5cbZoHsenwYFxkZzl83xTSKTiviCAfCsJLysH3POfC8m8NegyGAGfLP/VmGmfSChgXroR0RSWjEFv2J/nG84cuKFMf4sTCZqXuJd4KaXFVjEG3+tw4eXbNK/YC9oXXs3O8NY8y99L4BXY5cvLY/Bb2VZ58EOJVcB18DHJq9lRsKr8inyKGVjlmh29mtHs3AHfuhCwy1vXT/Nu2GKQt+UHsGdctyX6eQyNvc+5sfX9Dl7Pe2J/BRgAl2CpwmrsHR0AAAAASUVORK5CYII=);
}
\ No newline at end of file
<!-- HTML footer for doxygen 1.8.7-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!-- HTML header for doxygen 1.8.7-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search
$mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="topbanner"><a href="https://github.com/miloyip/rapidjson" title="RapidJSON GitHub"><i class="githublogo"></i></a></div>
$searchbox
<!--END TITLEAREA-->
<!-- end header part -->
# RapidJSON Performance
# Performance
The old performance article for RapidJSON 0.1 is provided [here](https://code.google.com/p/rapidjson/wiki/Performance).
......
# RapidJSON SAX
# SAX
## Reader
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -4,8 +4,8 @@
#include "rapidjson.h"
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
#endif
namespace rapidjson {
......@@ -264,7 +264,7 @@ private:
} // namespace rapidjson
#ifdef __GNUC__
#pragma GCC diagnostic pop
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_FILESTREAM_H_
......@@ -3,9 +3,12 @@
#include "rapidjson.h"
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#ifdef _MSC_VER
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data
#elif defined(__GNUC__)
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
#endif
namespace rapidjson {
......@@ -529,8 +532,8 @@ struct Transcoder<Encoding, Encoding> {
} // namespace rapidjson
#ifdef __GNUC__
#pragma GCC diagnostic pop
#if defined(__GNUC__) || defined(_MSV_VER)
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_ENCODINGS_H_
......@@ -24,11 +24,14 @@ struct SelectIf : SelectIfCond<Condition::Value,T1,T2> {};
template <bool Constify, typename T>
struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
template <typename T, typename U> struct IsSame { enum { Value = false }; };
template <typename T> struct IsSame<T,T> { enum { Value = true }; };
template <typename T, typename U> struct IsSame : FalseType {};
template <typename T> struct IsSame<T,T> : TrueType {};
template <typename T> struct IsConst { enum { Value = false }; };
template <typename T> struct IsConst<const T> { enum { Value = true }; };
template <typename T> struct IsConst : FalseType {};
template <typename T> struct IsConst<const T> : TrueType {};
template <typename T> struct IsPointer : FalseType {};
template <typename T> struct IsPointer<T*> : TrueType {};
template <typename CT, typename T>
struct IsMoreConst {
......@@ -64,6 +67,9 @@ template <typename T> struct RemoveSfinaeFptr<SfinaeResultTag&(*)(T)> { typedef
typename ::rapidjson::internal::EnableIf \
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
typename ::rapidjson::internal::DisableIf<cond,returntype>::Type
} // namespace internal
} // namespace rapidjson
//@endcond
......
......@@ -13,8 +13,7 @@ namespace internal {
template <typename Ch>
inline SizeType StrLen(const Ch* s) {
const Ch* p = s;
while (*p != '\0')
++p;
while (*p) ++p;
return SizeType(p - s);
}
......
......@@ -4,8 +4,8 @@
#include "writer.h"
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
#endif
namespace rapidjson {
......@@ -24,9 +24,9 @@ public:
typedef typename Base::Ch Ch;
//! Constructor
/*! \param os Output os.
/*! \param os Output stream.
\param allocator User supplied allocator. If it is null, it will create a private one.
\param levelDepth Initial capacity of
\param levelDepth Initial capacity of stack.
*/
PrettyWriter(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
......@@ -46,7 +46,9 @@ public:
return *this;
}
//@name Implementation of Handler.
/*! @name Implementation of Handler
\see Handler
*/
//@{
PrettyWriter& Null() { PrettyPrefix(kNullType); Base::WriteNull(); return *this; }
......@@ -56,11 +58,6 @@ public:
PrettyWriter& Int64(int64_t i64) { PrettyPrefix(kNumberType); Base::WriteInt64(i64); return *this; }
PrettyWriter& Uint64(uint64_t u64) { PrettyPrefix(kNumberType); Base::WriteUint64(u64); return *this; }
PrettyWriter& Double(double d) { PrettyPrefix(kNumberType); Base::WriteDouble(d); return *this; }
//! Overridden for fluent API, see \ref Writer::Double()
PrettyWriter& Double(double d, int precision) {
int oldPrecision = Base::GetDoublePrecision();
return SetDoublePrecision(precision).Double(d).SetDoublePrecision(oldPrecision);
}
PrettyWriter& String(const Ch* str, SizeType length, bool copy = false) {
(void)copy;
......@@ -117,9 +114,19 @@ public:
//@}
/*! @name Convenience extensions */
//@{
//! Simpler but slower overload.
PrettyWriter& String(const Ch* str) { return String(str, internal::StrLen(str)); }
//! Overridden for fluent API, see \ref Writer::Double()
PrettyWriter& Double(double d, int precision) {
int oldPrecision = Base::GetDoublePrecision();
return SetDoublePrecision(precision).Double(d).SetDoublePrecision(oldPrecision);
}
//@}
protected:
void PrettyPrefix(Type type) {
(void)type;
......@@ -177,7 +184,7 @@ private:
} // namespace rapidjson
#ifdef __GNUC__
#pragma GCC diagnostic pop
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_RAPIDJSON_H_
......@@ -4,6 +4,12 @@
// Copyright (c) 2011 Milo Yip (miloyip@gmail.com)
// Version 0.1
/*!\file rapidjson.h
\brief common definitions and configuration
\todo Complete Doxygen documentation for configure macros.
*/
#include <cstdlib> // malloc(), realloc(), free()
#include <cstring> // memcpy()
......@@ -14,6 +20,7 @@
// (U)INT64_C constant macros.
// If user have their own definition, can define RAPIDJSON_NO_INT64DEFINE to disable this.
#ifndef RAPIDJSON_NO_INT64DEFINE
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#ifndef __STDC_CONSTANT_MACROS
# define __STDC_CONSTANT_MACROS 1 // required by C++ standard
#endif
......@@ -25,6 +32,7 @@
#include <stdint.h>
#include <inttypes.h>
#endif
//!@endcond
#endif // RAPIDJSON_NO_INT64TYPEDEF
///////////////////////////////////////////////////////////////////////////////
......@@ -46,7 +54,7 @@
//! Endianness of the machine.
/*! GCC provided macro for detecting endianness of the target machine. But other
compilers may not have this. User can define RAPIDJSON_ENDIAN to either
RAPIDJSON_LITTLEENDIAN or RAPIDJSON_BIGENDIAN.
\ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN.
*/
#ifndef RAPIDJSON_ENDIAN
#ifdef __BYTE_ORDER__
......@@ -115,7 +123,9 @@ typedef unsigned SizeType;
// Adopt from boost
#ifndef RAPIDJSON_STATIC_ASSERT
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
namespace rapidjson {
template <bool x> struct STATIC_ASSERTION_FAILURE;
template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
template<int x> struct StaticAssertTest {};
......@@ -130,7 +140,13 @@ template<int x> struct StaticAssertTest {};
#else
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
#endif
//!@endcond
/*! \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::StaticAssertTest<\
sizeof(::rapidjson::STATIC_ASSERTION_FAILURE<bool(x) >)>\
RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
......@@ -139,16 +155,66 @@ template<int x> struct StaticAssertTest {};
///////////////////////////////////////////////////////////////////////////////
// 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))
// token stringification
#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x)
#define RAPIDJSON_DO_STRINGIFY(x) #x
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
#if defined(__clang__) || (defined(__GNUC__) && RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) >= 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(__GNUC__) && RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) >= 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_*
//!@endcond
///////////////////////////////////////////////////////////////////////////////
// Allocators and Encodings
#include "allocators.h"
#include "encodings.h"
//! main RapidJSON namespace
namespace rapidjson {
///////////////////////////////////////////////////////////////////////////////
......@@ -246,6 +312,7 @@ struct StreamTraits<GenericStringStream<Encoding> > {
enum { copyOptimization = 1 };
};
//! String stream with UTF8 encoding.
typedef GenericStringStream<UTF8<> > StringStream;
///////////////////////////////////////////////////////////////////////////////
......@@ -282,6 +349,7 @@ struct StreamTraits<GenericInsituStringStream<Encoding> > {
enum { copyOptimization = 1 };
};
//! Insitu string stream with UTF8 encoding.
typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
///////////////////////////////////////////////////////////////////////////////
......
......@@ -9,6 +9,10 @@
#include "internal/pow10.h"
#include "internal/stack.h"
#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
#include <intrin.h>
#pragma intrinsic(_BitScanForward)
#endif
#ifdef RAPIDJSON_SSE42
#include <nmmintrin.h>
#elif defined(RAPIDJSON_SSE2)
......@@ -16,8 +20,8 @@
#endif
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4127) // conditional expression is constant
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
#endif
#ifndef RAPIDJSON_PARSE_ERROR_NORETURN
......@@ -43,6 +47,8 @@ namespace rapidjson {
// ParseFlag
//! Combination of parseFlags
/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream
*/
enum ParseFlag {
kParseDefaultFlags = 0, //!< Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer.
kParseInsituFlag = 1, //!< In-situ(destructive) parsing.
......@@ -260,7 +266,7 @@ template<> inline void SkipWhitespace(StringStream& is) {
///////////////////////////////////////////////////////////////////////////////
// GenericReader
//! SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator.
/*! GenericReader parses JSON text from a stream, and send events synchronously to an
object implementing Handler concept.
......@@ -279,7 +285,7 @@ template<> inline void SkipWhitespace(StringStream& is) {
template <typename SourceEncoding, typename TargetEncoding, typename Allocator = MemoryPoolAllocator<> >
class GenericReader {
public:
typedef typename SourceEncoding::Ch Ch;
typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type
//! Constructor.
/*! \param allocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
......@@ -288,12 +294,12 @@ public:
GenericReader(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseErrorCode_(kParseErrorNone), errorOffset_(0) {}
//! Parse JSON text.
/*! \tparam parseFlags Combination of ParseFlag.
\tparam InputStream Type of input stream.
\tparam Handler Type of handler which must implement Handler concept.
\param is Input stream to be parsed.
\param handler The handler to receive events.
\return Whether the parsing is successful.
/*! \tparam parseFlags Combination of \ref ParseFlag.
\tparam InputStream Type of input stream, implementing Stream concept.
\tparam Handler Type of handler, implementing Handler concept.
\param is Input stream to be parsed.
\param handler The handler to receive events.
\return Whether the parsing is successful.
*/
template <unsigned parseFlags, typename InputStream, typename Handler>
bool Parse(InputStream& is, Handler& handler) {
......@@ -327,6 +333,13 @@ public:
return !HasParseError();
}
//! Parse JSON text (with \ref kParseDefaultFlags)
/*! \tparam InputStream Type of input stream, implementing Stream concept
\tparam Handler Type of handler, implementing Handler concept.
\param is Input stream to be parsed.
\param handler The handler to receive events.
\return Whether the parsing is successful.
*/
template <typename InputStream, typename Handler>
bool Parse(InputStream& is, Handler& handler) {
return Parse<kParseDefaultFlags>(is, handler);
......@@ -1160,7 +1173,7 @@ typedef GenericReader<UTF8<>, UTF8<> > Reader;
} // namespace rapidjson
#ifdef _MSC_VER
#pragma warning(pop)
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_READER_H_
......@@ -37,6 +37,7 @@ struct GenericStringBuffer {
mutable internal::Stack<Allocator> stack_;
};
//! String buffer with UTF8 encoding
typedef GenericStringBuffer<UTF8<> > StringBuffer;
//! Implement specialized version of PutN() with memset() for better performance.
......
......@@ -8,8 +8,8 @@
#include <new> // placement new
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4127) // conditional expression is constant
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
#endif
namespace rapidjson {
......@@ -25,8 +25,9 @@ namespace rapidjson {
for example Reader::Parse() and Document::Accept().
\tparam OutputStream Type of output stream.
\tparam SourceEncoding Encoding of both source strings.
\tparam TargetEncoding Encoding of and output stream.
\tparam SourceEncoding Encoding of source string.
\tparam TargetEncoding Encoding of output stream.
\tparam Allocator Type of allocator for allocating memory of stack.
\note implements Handler concept
*/
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >
......@@ -34,6 +35,11 @@ class Writer {
public:
typedef typename SourceEncoding::Ch Ch;
//! Constructor
/*! \param os Output stream.
\param allocator User supplied allocator. If it is null, it will create a private one.
\param levelDepth Initial capacity of stack.
*/
Writer(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
os_(os), level_stack_(allocator, levelDepth * sizeof(Level)),
doublePrecision_(kDefaultDoublePrecision) {}
......@@ -53,8 +59,11 @@ public:
//! \see SetDoublePrecision()
int GetDoublePrecision() const { return doublePrecision_; }
//@name Implementation of Handler
/*!@name Implementation of Handler
\see Handler
*/
//@{
Writer& Null() { Prefix(kNullType); WriteNull(); return *this; }
Writer& Bool(bool b) { Prefix(b ? kTrueType : kFalseType); WriteBool(b); return *this; }
Writer& Int(int i) { Prefix(kNumberType); WriteInt(i); return *this; }
......@@ -75,20 +84,6 @@ public:
*/
Writer& Double(double d) { Prefix(kNumberType); WriteDouble(d); return *this; }
//! Writes the given \c double value to the stream (explicit precision)
/*!
The currently set double precision is ignored in favor of the explicitly
given precision for this value.
\see Double(), SetDoublePrecision(), GetDoublePrecision()
\param d The value to be written
\param precision The number of significant digits for this value
\return The Writer itself for fluent API.
*/
Writer& Double(double d, int precision) {
int oldPrecision = GetDoublePrecision();
return SetDoublePrecision(precision).Double(d).SetDoublePrecision(oldPrecision);
}
Writer& String(const Ch* str, SizeType length, bool copy = false) {
(void)copy;
Prefix(kStringType);
......@@ -133,9 +128,28 @@ public:
}
//@}
/*! @name Convenience extensions */
//@{
//! Writes the given \c double value to the stream (explicit precision)
/*!
The currently set double precision is ignored in favor of the explicitly
given precision for this value.
\see Double(), SetDoublePrecision(), GetDoublePrecision()
\param d The value to be written
\param precision The number of significant digits for this value
\return The Writer itself for fluent API.
*/
Writer& Double(double d, int precision) {
int oldPrecision = GetDoublePrecision();
return SetDoublePrecision(precision).Double(d).SetDoublePrecision(oldPrecision);
}
//! Simpler but slower overload.
Writer& String(const Ch* str) { return String(str, internal::StrLen(str)); }
//@}
protected:
//! Information for each nested level
struct Level {
......@@ -171,7 +185,7 @@ protected:
char buffer[10];
char *p = buffer;
do {
*p++ = (u % 10) + '0';
*p++ = char(u % 10) + '0';
u /= 10;
} while (u > 0);
......@@ -292,7 +306,7 @@ private:
} // namespace rapidjson
#ifdef _MSC_VER
#pragma warning(pop)
RAPIDJSON_DIAG_POP
#endif
#endif // RAPIDJSON_RAPIDJSON_H_
......@@ -2,7 +2,9 @@
Copyright (c) 2011-2014 Milo Yip (miloyip@gmail.com)
https://github.com/miloyip/rapidjson/
[RapidJSON GitHub](https://github.com/miloyip/rapidjson/)
[RapidJSON Documentation](http://miloyip.github.io/rapidjson/)
## Introduction
......@@ -37,23 +39,29 @@ Users can build and run the unit tests on their platform/compiler.
## Installation
RapidJSON is a header-only C++ library. Just copy the `rapidjson/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.
To build the tests and examples:
1. Obtain [premake4](http://industriousone.com/premake/download).
2. Copy premake4 executable to RapidJSON/build (or system path)
3. Run `rapidjson/build/premake.bat` on Windows, `RapidJSON/build/premake.sh` on Linux or other platforms
4. On Windows, build the solution at `rapidjson/build/vs2008/` or `/vs2010/`
5. On other platforms, run GNU make at `rapidjson/build/gmake/` (e.g., `make -f test.make config=release32`, `make -f example.make config=debug32`)
6. On success, the executable are generated at `rapidjson/bin`
2. Copy premake4 executable to RapidJSON/build (or system path).
3. Run `rapidjson/build/premake.bat` on Windows, `RapidJSON/build/premake.sh` on Linux or other platforms.
4. On Windows, build the solution at `rapidjson/build/vs2008/` or `/vs2010/`.
5. On other platforms, run GNU make at `rapidjson/build/gmake/` (e.g., `make -f test.make config=release32`; `make -f example.make config=debug32`).
6. On success, the executable are generated at `rapidjson/bin`.
To build the [Doxygen](http://doxygen.org) documentation:
1. Obtain and install [Doxygen](http://doxygen.org/download.html).
2. In the top-level directory, run `doxygen build/Doxyfile`.
3. Browse the generated documentation in `doc/html`.
## Usage at a glance
This simple example parses a JSON string into a document (DOM), make a simple modification of the DOM, and finally stringify the DOM to a JSON string.
[simpledom.cpp](example/simpledom/simpledom.cpp)
```cpp
~~~~~~~~~~cpp
// rapidjson/example/simpledom/simpledom.cpp`
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
......@@ -80,12 +88,12 @@ int main() {
std::cout << buffer.GetString() << std::endl;
return 0;
}
```
~~~~~~~~~~
Note that this example did not handle potential errors.
The following diagram shows the process.
![simpledom](doc/diagram/simpledom.png?raw=true)
![simpledom](doc/diagram/simpledom.png)
More [examples](example/) are available.
......@@ -29,14 +29,16 @@
# define __STDC_CONSTANT_MACROS 1 // required by C++ standard
#endif
#ifdef __GNUC__
#if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
#if defined(__clang__) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Weffc++"
#endif
#include "gtest/gtest.h"
#ifdef __GNUC__
#if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
#pragma GCC diagnostic pop
#endif
......
......@@ -190,8 +190,8 @@ TEST_F(RapidJson, DocumentTraverse) {
}
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
#endif
struct ValueCounter : public BaseReaderHandler<> {
......@@ -204,7 +204,7 @@ struct ValueCounter : public BaseReaderHandler<> {
};
#ifdef __GNUC__
#pragma GCC diagnostic pop
RAPIDJSON_DIAG_POP
#endif
TEST_F(RapidJson, DocumentAccept) {
......@@ -260,7 +260,7 @@ TEST_F(RapidJson, PrettyWriter_StringBuffer) {
TEST_F(RapidJson, internal_Pow10) {
double sum = 0;
for (size_t i = 0; i < kTrialCount * kTrialCount; i++)
sum += internal::Pow10(i & 255);
sum += internal::Pow10(int(i & 255));
EXPECT_GT(sum, 0.0);
}
......
......@@ -6,8 +6,8 @@
using namespace rapidjson;
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
#endif
template<bool expect>
......@@ -1176,5 +1176,5 @@ TEST(Reader, IterativeParsing_StateTransition_ElementDelimiter) {
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
RAPIDJSON_DIAG_POP
#endif
......@@ -13,22 +13,24 @@
#pragma warning(disable : 4996) // 'function': was declared deprecated
#endif
#ifdef __GNUC__
#if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
#if defined(__clang__) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Weffc++"
#endif
#include "gtest/gtest.h"
#ifdef __GNUC__
#if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
#pragma GCC diagnostic pop
#endif
template <typename Ch>
inline size_t StrLen(const Ch* s) {
inline unsigned StrLen(const Ch* s) {
const Ch* p = s;
while (*p) p++;
return p - s;
return unsigned(p - s);
}
template<typename Ch>
......
......@@ -23,6 +23,25 @@ TEST(Value, assignment_operator) {
y = x;
EXPECT_TRUE(x.IsNull()); // move semantic
EXPECT_EQ(1234, y.GetInt());
y = 5678;
EXPECT_TRUE(y.IsInt());
EXPECT_EQ(5678, y.GetInt());
x = "Hello";
EXPECT_TRUE(x.IsString());
EXPECT_STREQ(x.GetString(),"Hello");
y = StringRef(x.GetString(),x.GetStringLength());
EXPECT_TRUE(y.IsString());
EXPECT_EQ(y.GetString(),x.GetString());
EXPECT_EQ(y.GetStringLength(),x.GetStringLength());
static char mstr[] = "mutable";
// y = mstr; // should not compile
y = StringRef(mstr);
EXPECT_TRUE(y.IsString());
EXPECT_EQ(y.GetString(),mstr);
}
template <typename Value>
......@@ -350,8 +369,8 @@ TEST(Value, Double) {
}
TEST(Value, String) {
// Constructor with const string
Value x("Hello", 5);
// Construction with const string
Value x("Hello", 5); // literal
EXPECT_EQ(kStringType, x.GetType());
EXPECT_TRUE(x.IsString());
EXPECT_STREQ("Hello", x.GetString());
......@@ -365,9 +384,41 @@ TEST(Value, String) {
EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray());
static const char cstr[] = "World"; // const array
Value(cstr).Swap(x);
EXPECT_TRUE(x.IsString());
EXPECT_EQ(x.GetString(), cstr);
EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1);
static char mstr[] = "Howdy"; // non-const array
// Value(mstr).Swap(x); // should not compile
Value(StringRef(mstr)).Swap(x);
EXPECT_TRUE(x.IsString());
EXPECT_EQ(x.GetString(), mstr);
EXPECT_EQ(x.GetStringLength(), sizeof(mstr)-1);
strncpy(mstr,"Hello", sizeof(mstr));
EXPECT_STREQ(x.GetString(), "Hello");
const char* pstr = cstr;
//Value(pstr).Swap(x); // should not compile
Value(StringRef(pstr)).Swap(x);
EXPECT_TRUE(x.IsString());
EXPECT_EQ(x.GetString(), cstr);
EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1);
char* mpstr = mstr;
Value(StringRef(mpstr,sizeof(mstr)-1)).Swap(x);
EXPECT_TRUE(x.IsString());
EXPECT_EQ(x.GetString(), mstr);
EXPECT_EQ(x.GetStringLength(), 5u);
EXPECT_STREQ(x.GetString(), "Hello");
// Constructor with copy string
MemoryPoolAllocator<> allocator;
Value c(x.GetString(), x.GetStringLength(), allocator);
EXPECT_NE(x.GetString(), c.GetString());
EXPECT_EQ(x.GetStringLength(), c.GetStringLength());
EXPECT_STREQ(x.GetString(), c.GetString());
//x.SetString("World");
x.SetString("World", 5);
EXPECT_STREQ("Hello", c.GetString());
......@@ -381,11 +432,31 @@ TEST(Value, String) {
// SetConsttring()
Value z;
//z.SetString("Hello");
z.SetString("Hello");
EXPECT_TRUE(x.IsString());
z.SetString("Hello", 5);
EXPECT_STREQ("Hello", z.GetString());
EXPECT_STREQ("Hello", z.GetString());
EXPECT_EQ(5u, z.GetStringLength());
z.SetString("Hello");
EXPECT_TRUE(z.IsString());
EXPECT_STREQ("Hello", z.GetString());
//z.SetString(mstr); // should not compile
//z.SetString(pstr); // should not compile
z.SetString(StringRef(mstr));
EXPECT_TRUE(z.IsString());
EXPECT_STREQ(z.GetString(), mstr);
z.SetString(cstr);
EXPECT_TRUE(z.IsString());
EXPECT_EQ(cstr, z.GetString());
z = cstr;
EXPECT_TRUE(z.IsString());
EXPECT_EQ(cstr, z.GetString());
// SetString()
char s[] = "World";
Value w;
......@@ -424,11 +495,13 @@ TEST(Value, Array) {
x.PushBack(v, allocator);
v.SetInt(123);
x.PushBack(v, allocator);
//x.PushBack((const char*)"foo", allocator); // should not compile
x.PushBack("foo", allocator);
EXPECT_FALSE(x.Empty());
EXPECT_EQ(4u, x.Size());
EXPECT_EQ(5u, x.Size());
EXPECT_FALSE(y.Empty());
EXPECT_EQ(4u, y.Size());
EXPECT_EQ(5u, y.Size());
EXPECT_TRUE(x[SizeType(0)].IsNull());
EXPECT_TRUE(x[1u].IsTrue());
EXPECT_TRUE(x[2u].IsFalse());
......@@ -439,6 +512,8 @@ TEST(Value, Array) {
EXPECT_TRUE(y[2u].IsFalse());
EXPECT_TRUE(y[3u].IsInt());
EXPECT_EQ(123, y[3u].GetInt());
EXPECT_TRUE(y[4u].IsString());
EXPECT_STREQ("foo", y[4u].GetString());
// iterator
Value::ValueIterator itr = x.Begin();
......@@ -454,6 +529,10 @@ TEST(Value, Array) {
EXPECT_TRUE(itr != x.End());
EXPECT_TRUE(itr->IsInt());
EXPECT_EQ(123, itr->GetInt());
++itr;
EXPECT_TRUE(itr != x.End());
EXPECT_TRUE(itr->IsString());
EXPECT_STREQ("foo", itr->GetString());
// const iterator
Value::ConstValueIterator citr = y.Begin();
......@@ -469,13 +548,18 @@ TEST(Value, Array) {
EXPECT_TRUE(citr != y.End());
EXPECT_TRUE(citr->IsInt());
EXPECT_EQ(123, citr->GetInt());
++citr;
EXPECT_TRUE(citr != y.End());
EXPECT_TRUE(citr->IsString());
EXPECT_STREQ("foo", citr->GetString());
// PopBack()
x.PopBack();
EXPECT_EQ(3u, x.Size());
EXPECT_EQ(4u, x.Size());
EXPECT_TRUE(y[SizeType(0)].IsNull());
EXPECT_TRUE(y[1].IsTrue());
EXPECT_TRUE(y[2].IsFalse());
EXPECT_TRUE(y[1u].IsTrue());
EXPECT_TRUE(y[2u].IsFalse());
EXPECT_TRUE(y[3u].IsInt());
// Clear()
x.Clear();
......@@ -502,16 +586,34 @@ TEST(Value, Object) {
EXPECT_TRUE(y.IsObject());
// AddMember()
Value name("A", 1);
Value value("Apple", 5);
x.AddMember(name, value, allocator);
//name.SetString("B");
name.SetString("B", 1);
//value.SetString("Banana");
value.SetString("Banana", 6);
x.AddMember(name, value, allocator);
x.AddMember("A", "Apple", allocator);
Value value("Banana", 6);
x.AddMember("B", "Banana", allocator);
// AddMember<T>(StringRefType, T, Allocator)
{
Value o(kObjectType);
o.AddMember("true", true, allocator);
o.AddMember("false", false, allocator);
o.AddMember("int", -1, allocator);
o.AddMember("uint", 1u, allocator);
o.AddMember("int64", INT64_C(-4294967296), allocator);
o.AddMember("uint64", UINT64_C(4294967296), allocator);
o.AddMember("double", 3.14, allocator);
o.AddMember("string", "Jelly", allocator);
EXPECT_TRUE(o["true"].GetBool());
EXPECT_FALSE(o["false"].GetBool());
EXPECT_EQ(-1, o["int"].GetInt());
EXPECT_EQ(1u, o["uint"].GetUint());
EXPECT_EQ(INT64_C(-4294967296), o["int64"].GetInt64());
EXPECT_EQ(UINT64_C(4294967296), o["uint64"].GetUint64());
EXPECT_STREQ("Jelly",o["string"].GetString());
}
// Tests a member with null character
Value name;
const Value C0D("C\0D", 3);
name.SetString(C0D.GetString(), 3);
value.SetString("CherryD", 7);
......@@ -523,7 +625,7 @@ TEST(Value, Object) {
EXPECT_TRUE(y.HasMember("A"));
EXPECT_TRUE(y.HasMember("B"));
name.SetString("C\0D", 3);
name.SetString("C\0D");
EXPECT_TRUE(x.HasMember(name));
EXPECT_TRUE(y.HasMember(name));
......@@ -617,6 +719,7 @@ TEST(Value, BigNestedObject) {
char name1[10];
sprintf(name1, "%d", i);
// Value name(name1); // should not compile
Value name(name1, (SizeType)strlen(name1), allocator);
Value object(kObjectType);
......@@ -629,6 +732,7 @@ TEST(Value, BigNestedObject) {
object.AddMember(name, number, allocator);
}
// x.AddMember(name1, object, allocator); // should not compile
x.AddMember(name, object, allocator);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment