mirror of
https://github.com/Tencent/rapidjson.git
synced 2025-10-28 11:31:57 +01:00
Merge branch 'master' into schema
# Conflicts: # .gitignore # include/rapidjson/internal/stack.h
This commit is contained in:
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1,3 +1,11 @@
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
/bin/*
|
||||
!/bin/data
|
||||
!/bin/encodings
|
||||
!/bin/jsonchecker
|
||||
!/bin/types
|
||||
>>>>>>> master
|
||||
/build
|
||||
/doc/html
|
||||
/doc/doxygen_*.db
|
||||
@@ -16,3 +24,4 @@ Testing
|
||||
install_manifest.txt
|
||||
Doxyfile
|
||||
DartConfiguration.tcl
|
||||
*.nupkg
|
||||
|
||||
11
.travis.yml
11
.travis.yml
@@ -6,10 +6,12 @@ compiler:
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- CONF=debug ARCH=x86_64
|
||||
- CONF=release ARCH=x86_64
|
||||
- CONF=debug ARCH=x86
|
||||
- CONF=release ARCH=x86
|
||||
- CONF=debug ARCH=x86_64 CXX11=ON
|
||||
- CONF=release ARCH=x86_64 CXX11=ON
|
||||
- CONF=debug ARCH=x86 CXX11=ON
|
||||
- CONF=release ARCH=x86 CXX11=ON
|
||||
- CONF=debug ARCH=x86_64 CXX11=OFF
|
||||
- CONF=debug ARCH=x86 CXX11=OFF
|
||||
global:
|
||||
- ARCH_FLAGS_x86='-m32' # #266: don't use SSE on 32-bit
|
||||
- ARCH_FLAGS_x86_64='-msse4.2' # use SSE4.2 on 64-bit
|
||||
@@ -34,6 +36,7 @@ before_script:
|
||||
eval "ARCH_FLAGS=\${ARCH_FLAGS_${ARCH}}" ;
|
||||
(cd build && cmake
|
||||
-DRAPIDJSON_HAS_STDSTRING=ON
|
||||
-DRAPIDJSON_BUILD_CXX11=$CXX11
|
||||
-DCMAKE_VERBOSE_MAKEFILE=ON
|
||||
-DCMAKE_BUILD_TYPE=$CONF
|
||||
-DCMAKE_CXX_FLAGS="$ARCH_FLAGS $GCOV_FLAGS"
|
||||
|
||||
@@ -20,6 +20,8 @@ option(RAPIDJSON_BUILD_TESTS "Build rapidjson perftests and unittests." ON)
|
||||
option(RAPIDJSON_BUILD_THIRDPARTY_GTEST
|
||||
"Use gtest installation in `thirdparty/gtest` by default if available" OFF)
|
||||
|
||||
option(RAPIDJSON_BUILD_CXX11 "Build rapidjson with C++11 (gcc/clang)" ON)
|
||||
|
||||
option(RAPIDJSON_HAS_STDSTRING "" OFF)
|
||||
if(RAPIDJSON_HAS_STDSTRING)
|
||||
add_definitions(-DRAPIDJSON_HAS_STDSTRING)
|
||||
@@ -27,8 +29,18 @@ endif()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -Wall -Wextra -Werror")
|
||||
if (RAPIDJSON_BUILD_CXX11)
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7.0")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
endif()
|
||||
endif()
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -Wall -Wextra -Werror -Wno-missing-field-initializers")
|
||||
if (RAPIDJSON_BUILD_CXX11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
endif()
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
|
||||
endif()
|
||||
|
||||
102
bin/types/booleans.json
Executable file
102
bin/types/booleans.json
Executable file
@@ -0,0 +1,102 @@
|
||||
[
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
]
|
||||
102
bin/types/floats.json
Executable file
102
bin/types/floats.json
Executable file
@@ -0,0 +1,102 @@
|
||||
[
|
||||
135.747111636,
|
||||
123.377054008,
|
||||
140.527504552,
|
||||
-72.299143906,
|
||||
-23.851678949,
|
||||
73.586193519,
|
||||
-158.299382442,
|
||||
177.477876032,
|
||||
32.268518982,
|
||||
-139.560009969,
|
||||
115.203105183,
|
||||
-106.025823607,
|
||||
167.224138231,
|
||||
103.378383732,
|
||||
-97.498486285,
|
||||
18.184723416,
|
||||
69.137075711,
|
||||
33.849002681,
|
||||
-120.185228215,
|
||||
-20.841408615,
|
||||
-172.659492727,
|
||||
-2.691464061,
|
||||
22.426164066,
|
||||
-98.416909437,
|
||||
-31.603082708,
|
||||
-85.072296561,
|
||||
108.620987395,
|
||||
-43.127078238,
|
||||
-126.473562057,
|
||||
-158.595489097,
|
||||
-57.890678254,
|
||||
-13.254016573,
|
||||
-85.024504709,
|
||||
171.663552644,
|
||||
-146.495558248,
|
||||
-10.606748276,
|
||||
-118.786969354,
|
||||
153.352057804,
|
||||
-45.215545083,
|
||||
37.038725288,
|
||||
106.344071897,
|
||||
-64.607402031,
|
||||
85.148030911,
|
||||
28.897784566,
|
||||
39.51082061,
|
||||
20.450382102,
|
||||
-113.174943618,
|
||||
71.60785784,
|
||||
-168.202648062,
|
||||
-157.338200017,
|
||||
10.879588527,
|
||||
-114.261694831,
|
||||
-5.622927072,
|
||||
-173.330830616,
|
||||
-29.47002003,
|
||||
-39.829034201,
|
||||
50.031545162,
|
||||
82.815735508,
|
||||
-119.188760828,
|
||||
-48.455928081,
|
||||
163.964263034,
|
||||
46.30378861,
|
||||
-26.248889762,
|
||||
-47.354615322,
|
||||
155.388677633,
|
||||
-166.710356904,
|
||||
42.987233558,
|
||||
144.275297374,
|
||||
37.394383186,
|
||||
-122.550388725,
|
||||
177.469945914,
|
||||
101.104677413,
|
||||
109.429869885,
|
||||
-104.919625624,
|
||||
147.522756541,
|
||||
-81.294703727,
|
||||
122.744731363,
|
||||
81.803603684,
|
||||
26.321556167,
|
||||
147.045441354,
|
||||
147.256895816,
|
||||
-174.211095908,
|
||||
52.518769316,
|
||||
-78.58250334,
|
||||
-173.356685435,
|
||||
-107.728209264,
|
||||
-69.982325771,
|
||||
-113.776095893,
|
||||
-35.785267074,
|
||||
-105.748545976,
|
||||
-30.206523864,
|
||||
-76.185311723,
|
||||
-126.400112781,
|
||||
-26.864958639,
|
||||
56.840053629,
|
||||
93.781553535,
|
||||
-116.002949803,
|
||||
-46.617140948,
|
||||
176.846840093,
|
||||
-144.24821335
|
||||
]
|
||||
102
bin/types/guids.json
Executable file
102
bin/types/guids.json
Executable file
@@ -0,0 +1,102 @@
|
||||
[
|
||||
"d35bf0d4-8d8f-4e17-a5c3-ad9bfd675266",
|
||||
"db402774-eeb6-463b-9986-c458c44d8b5a",
|
||||
"2a2e4101-b5f2-40b8-8750-e03f01661e60",
|
||||
"76787cfa-f4eb-4d62-aaad-e1d588d00ad5",
|
||||
"fd73894b-b500-4a7c-888c-06b5bd9cec65",
|
||||
"cce1862a-cf31-4ef2-9e23-f1d23b4e6163",
|
||||
"00a98bb0-2b6e-4368-8512-71c21aa87db7",
|
||||
"ab9a8d69-cec7-4550-bd35-3ed678e22782",
|
||||
"f18b48e1-5114-4fbe-9652-579e8d66950e",
|
||||
"4efe3baa-7ac5-4d6a-a839-6b9cfe825764",
|
||||
"b4aec119-5b0a-434c-b388-109816c482a5",
|
||||
"e0ef0cbb-127a-4a28-9831-5741b4295275",
|
||||
"d50286a5-cb7b-4c9e-be99-f214439bae8c",
|
||||
"a981094c-f1ac-42ed-a9fa-86404c7210ff",
|
||||
"2a34ee57-5815-4829-b77b-eeebaa8fe340",
|
||||
"a0530d44-48f8-4eff-b9ea-8810c4308351",
|
||||
"c6f91509-83e1-4ea1-9680-e667fbfd56ee",
|
||||
"cab11402-dcdd-4454-b190-6da124947395",
|
||||
"283d159c-2b18-4856-b4c7-5059252eaa15",
|
||||
"146157c6-72a8-4051-9991-cb6ea6743d81",
|
||||
"aef6f269-7306-4bd2-83f7-6d5605b5dc9a",
|
||||
"37fe6027-d638-4017-80a9-e7b0567b278e",
|
||||
"5003d731-33fb-4159-af61-d76348a44079",
|
||||
"e0e06979-5f80-4713-9fe0-8a4d60dc89f8",
|
||||
"7e85bdc3-0345-4cb6-9398-ccab06e79976",
|
||||
"f2ebf5af-6568-4ffe-a46d-403863fd4b66",
|
||||
"e0b5bb1c-b4dd-4535-9a9e-3c73f1167d46",
|
||||
"c852d20b-6bcb-4b12-bd57-308296c64c5a",
|
||||
"7ac3ae82-1818-49cd-a8a4-5ac77dfafd46",
|
||||
"138004a9-76e2-4ad7-bd42-e74dabdbb803",
|
||||
"ab25b5be-96be-45b0-b765-947b40ec36a6",
|
||||
"08404734-fd57-499e-a4cf-71e9ec782ede",
|
||||
"8dfdeb16-248b-4a21-bf89-2e22b11a4101",
|
||||
"a0e44ef0-3b09-41e8-ad5d-ed8e6a1a2a67",
|
||||
"a7981e49-188d-414a-9779-b1ad91e599d1",
|
||||
"329186c0-bf27-4208-baf7-c0a0a5a2d5b7",
|
||||
"cb5f3381-d33e-4b30-b1a9-f482623cad33",
|
||||
"15031262-ca73-4e3c-bd0a-fcf89bdf0caf",
|
||||
"6d7333d1-2e8c-4d78-bfde-5be47e70eb13",
|
||||
"acaa160c-670a-4e8f-ac45-49416e77d5f9",
|
||||
"228f87eb-cde4-4106-808b-2dbf3c7b6d2e",
|
||||
"2ff830a3-5445-4d8e-b161-bddd30666697",
|
||||
"f488bedd-ff6e-4108-b9a7-07f6da62f476",
|
||||
"2e12b846-0a34-478e-adf7-a438493803e6",
|
||||
"6686b8ef-7446-4d86-bd8c-df24119e3bfe",
|
||||
"e474a5c5-5793-4d41-b4ab-5423acc56ef1",
|
||||
"ac046573-e718-44dc-a0dc-9037eeaba6a9",
|
||||
"6b0e9099-cf53-4d5a-8a71-977528628fcf",
|
||||
"d51a3f22-0ff9-4087-ba9b-fcee2a2d8ade",
|
||||
"bdc01286-3511-4d22-bfb8-76d01203d366",
|
||||
"ca44eb84-17ff-4f27-8f1e-1bd25f4e8725",
|
||||
"4e9a8c2f-be0b-4913-92d2-c801b9a50d04",
|
||||
"7685d231-dadd-4041-9165-898397438ab7",
|
||||
"86f0bf26-d66a-44d8-99f5-d6768addae3b",
|
||||
"2ca1167c-72ba-45a0-aa42-faf033db0d0b",
|
||||
"199a1182-ea55-49ff-ba51-71c29cdd0aac",
|
||||
"be6a4dd2-c821-4aa0-8b83-d64d6644b5b2",
|
||||
"4c5f4781-7f80-4daa-9c20-76b183000514",
|
||||
"513b31bd-54fb-4d12-a427-42a7c13ff8e1",
|
||||
"8e211bcb-d76c-4012-83ad-74dd7d23b687",
|
||||
"44d5807e-0501-4f66-8779-e244d4fdca0a",
|
||||
"db8cd555-0563-4b7b-b00c-eada300a7065",
|
||||
"cb14d0c9-46cc-4797-bd3a-752b05629f07",
|
||||
"4f68b3ef-ac9b-47a0-b6d7-57f398a5c6a5",
|
||||
"77221aae-1bcf-471c-be45-7f31f733f9d6",
|
||||
"42a7cac8-9e80-4c45-8c71-511d863c98ea",
|
||||
"f9018d22-b82c-468c-bdb5-8864d5964801",
|
||||
"75f4e9b8-62a2-4f21-ad8a-e19eff0419bc",
|
||||
"9b7385c8-8653-4184-951c-b0ac1b36b42e",
|
||||
"571018aa-ffbf-4b42-a16d-07b57a7f5f0e",
|
||||
"35de4a2f-6bf1-45aa-b820-2a27ea833e44",
|
||||
"0b8edb20-3bb4-4cb4-b089-31957466dbab",
|
||||
"97da4778-9a7b-4140-a545-968148c81fb7",
|
||||
"969f326c-8f2a-47c5-b41c-d9c2f06c9b9d",
|
||||
"ae211037-8b53-4b17-bfc8-c06fc7774409",
|
||||
"12c5c3c4-0bd5-45d3-bc1d-d04a3c65d3e6",
|
||||
"ec02024f-ce43-4dd3-8169-a59f7baee043",
|
||||
"5b6afe77-ce48-47ca-90a0-25cd10ca5ffd",
|
||||
"2e3a61d4-6b8f-4d2f-ba86-878b4012efd8",
|
||||
"19a88a67-a5d3-4647-898f-1cde07bce040",
|
||||
"6db6f420-b5c8-48b9-bbb2-8864fe6fed65",
|
||||
"5a45dbde-7b53-4f6b-b864-e3b63be3708a",
|
||||
"c878321b-8a02-4239-9981-15760c2e7d15",
|
||||
"4e36687f-8bf6-4b12-b496-3a8e382d067e",
|
||||
"a59a63cd-43c0-4c6e-b208-6dbca86f8176",
|
||||
"303308c4-2e4a-45b5-8bf3-3e66e9ad05a1",
|
||||
"8b58fdf1-43a6-4c98-9547-6361b50791af",
|
||||
"a3563591-72ed-42b5-8e41-bac1d76d70cf",
|
||||
"38db8c78-3739-4f6e-8313-de4138082114",
|
||||
"86615bea-7e73-4daf-95da-ae6b9eee1bbb",
|
||||
"35d38e3e-076e-40dd-9aa8-05be2603bd59",
|
||||
"9f84c62d-b454-4ba3-8c19-a01878985cdc",
|
||||
"6721bbae-d765-4a06-8289-6fe46a1bf943",
|
||||
"0837796f-d0dd-4e50-9b7c-1983e6cc7c48",
|
||||
"021eb7d7-e869-49b9-80c3-9dd16ce2d981",
|
||||
"819c56f8-e040-475d-aad5-c6d5e98b20aa",
|
||||
"3a61ef02-735e-4229-937d-b3777a3f4e1f",
|
||||
"79dfab84-12e6-4ec8-bfc8-460ae71e4eca",
|
||||
"a106fabf-e149-476c-8053-b62388b6eb57",
|
||||
"9a3900a5-bfb4-4de0-baa5-253a8bd0b634"
|
||||
]
|
||||
102
bin/types/integers.json
Executable file
102
bin/types/integers.json
Executable file
@@ -0,0 +1,102 @@
|
||||
[
|
||||
8125686,
|
||||
8958709,
|
||||
5976222,
|
||||
1889524,
|
||||
7968493,
|
||||
1357486,
|
||||
118415,
|
||||
7081097,
|
||||
4635968,
|
||||
7555332,
|
||||
2270233,
|
||||
3428352,
|
||||
8699968,
|
||||
2087333,
|
||||
7861337,
|
||||
7554440,
|
||||
2017031,
|
||||
7981692,
|
||||
6060687,
|
||||
1877715,
|
||||
3297474,
|
||||
8373177,
|
||||
6158629,
|
||||
7853641,
|
||||
3004441,
|
||||
9650406,
|
||||
2695251,
|
||||
1180761,
|
||||
4988426,
|
||||
6043805,
|
||||
8063373,
|
||||
6103218,
|
||||
2848339,
|
||||
8188690,
|
||||
9235573,
|
||||
5949816,
|
||||
6116081,
|
||||
6471138,
|
||||
3354531,
|
||||
4787414,
|
||||
9660600,
|
||||
942529,
|
||||
7278535,
|
||||
7967399,
|
||||
554292,
|
||||
1436493,
|
||||
267319,
|
||||
2606657,
|
||||
7900601,
|
||||
4276634,
|
||||
7996757,
|
||||
8544466,
|
||||
7266469,
|
||||
3301373,
|
||||
4005350,
|
||||
6437652,
|
||||
7717672,
|
||||
7126292,
|
||||
8588394,
|
||||
2127902,
|
||||
7410190,
|
||||
1517806,
|
||||
4583602,
|
||||
3123440,
|
||||
7747613,
|
||||
5029464,
|
||||
9834390,
|
||||
3087227,
|
||||
4913822,
|
||||
7550487,
|
||||
4518144,
|
||||
5862588,
|
||||
1778599,
|
||||
9493290,
|
||||
5588455,
|
||||
3638706,
|
||||
7394293,
|
||||
4294719,
|
||||
3837830,
|
||||
6381878,
|
||||
7175866,
|
||||
8575492,
|
||||
1415229,
|
||||
1453733,
|
||||
6972404,
|
||||
9782571,
|
||||
4234063,
|
||||
7117418,
|
||||
7293130,
|
||||
8057071,
|
||||
9345285,
|
||||
7626648,
|
||||
3358911,
|
||||
4574537,
|
||||
9371826,
|
||||
7627107,
|
||||
6154093,
|
||||
5392367,
|
||||
5398105,
|
||||
6956377
|
||||
]
|
||||
592
bin/types/mixed.json
Executable file
592
bin/types/mixed.json
Executable file
@@ -0,0 +1,592 @@
|
||||
[
|
||||
{
|
||||
"favoriteFruit": "banana",
|
||||
"greeting": "Hello, Kim! You have 10 unread messages.",
|
||||
"friends": [
|
||||
{
|
||||
"name": "Higgins Rodriquez",
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "James Floyd",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "Gay Stewart",
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"range": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"tags": [
|
||||
"pariatur",
|
||||
"ad",
|
||||
"eiusmod",
|
||||
"sit",
|
||||
"et",
|
||||
"velit",
|
||||
"culpa"
|
||||
],
|
||||
"longitude": -57.919246,
|
||||
"latitude": -36.022812,
|
||||
"registered": "Friday, March 21, 2014 9:13 PM",
|
||||
"about": "Laborum nulla aliquip ullamco proident excepteur est officia ipsum. Eiusmod exercitation minim ex do labore reprehenderit aliqua minim qui excepteur reprehenderit cupidatat. Sint enim exercitation duis id consequat nisi enim magna. Commodo aliqua id ipsum sit magna enim. Veniam officia in labore fugiat veniam ea laboris ex veniam duis.\r\n",
|
||||
"address": "323 Pulaski Street, Ronco, North Carolina, 7701",
|
||||
"phone": "+1 (919) 438-2678",
|
||||
"email": "kim.griffith@cipromox.biz",
|
||||
"company": "CIPROMOX",
|
||||
"name": {
|
||||
"last": "Griffith",
|
||||
"first": "Kim"
|
||||
},
|
||||
"eyeColor": "green",
|
||||
"age": 26,
|
||||
"picture": "http://placehold.it/32x32",
|
||||
"balance": "$1,283.55",
|
||||
"isActive": false,
|
||||
"guid": "10ab0392-c5e2-48a3-9473-aa725bad892d",
|
||||
"index": 0,
|
||||
"_id": "551b91198238a0bcf9a41133"
|
||||
},
|
||||
{
|
||||
"favoriteFruit": "banana",
|
||||
"greeting": "Hello, Skinner! You have 9 unread messages.",
|
||||
"friends": [
|
||||
{
|
||||
"name": "Rhonda Justice",
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "Audra Castaneda",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "Vicky Chavez",
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"range": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"tags": [
|
||||
"dolore",
|
||||
"enim",
|
||||
"sit",
|
||||
"non",
|
||||
"exercitation",
|
||||
"fugiat",
|
||||
"adipisicing"
|
||||
],
|
||||
"longitude": -60.291407,
|
||||
"latitude": -84.619318,
|
||||
"registered": "Friday, February 7, 2014 3:17 AM",
|
||||
"about": "Consectetur eiusmod laboris dolore est ullamco nulla in velit quis esse Lorem. Amet aliqua sunt aute occaecat veniam officia in duis proident aliqua cupidatat mollit. Sint eu qui anim duis ut anim duis eu cillum. Cillum nostrud adipisicing tempor Lorem commodo sit in ad qui non et irure qui. Labore eu aliquip id duis eiusmod veniam.\r\n",
|
||||
"address": "347 Autumn Avenue, Fidelis, Puerto Rico, 543",
|
||||
"phone": "+1 (889) 457-2319",
|
||||
"email": "skinner.maddox@moltonic.co.uk",
|
||||
"company": "MOLTONIC",
|
||||
"name": {
|
||||
"last": "Maddox",
|
||||
"first": "Skinner"
|
||||
},
|
||||
"eyeColor": "green",
|
||||
"age": 22,
|
||||
"picture": "http://placehold.it/32x32",
|
||||
"balance": "$3,553.10",
|
||||
"isActive": false,
|
||||
"guid": "cfbc2fb6-2641-4388-b06d-ec0212cfac1e",
|
||||
"index": 1,
|
||||
"_id": "551b91197e0abe92d6642700"
|
||||
},
|
||||
{
|
||||
"favoriteFruit": "strawberry",
|
||||
"greeting": "Hello, Reynolds! You have 5 unread messages.",
|
||||
"friends": [
|
||||
{
|
||||
"name": "Brady Valdez",
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "Boyer Golden",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "Gladys Knapp",
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"range": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"tags": [
|
||||
"commodo",
|
||||
"eiusmod",
|
||||
"cupidatat",
|
||||
"et",
|
||||
"occaecat",
|
||||
"proident",
|
||||
"Lorem"
|
||||
],
|
||||
"longitude": 140.866287,
|
||||
"latitude": 1.401032,
|
||||
"registered": "Monday, October 20, 2014 8:01 AM",
|
||||
"about": "Deserunt elit consequat ea dolor pariatur aute consectetur et nulla ipsum ad. Laboris occaecat ipsum ad duis et esse ea ut voluptate. Ex magna consequat pariatur amet. Quis excepteur non mollit dolore cillum dolor ex esse veniam esse deserunt non occaecat veniam. Sit amet proident proident amet. Nisi est id ut ut adipisicing esse fugiat non dolor aute.\r\n",
|
||||
"address": "872 Montague Terrace, Haena, Montana, 3106",
|
||||
"phone": "+1 (974) 410-2655",
|
||||
"email": "reynolds.sanford@combot.biz",
|
||||
"company": "COMBOT",
|
||||
"name": {
|
||||
"last": "Sanford",
|
||||
"first": "Reynolds"
|
||||
},
|
||||
"eyeColor": "green",
|
||||
"age": 21,
|
||||
"picture": "http://placehold.it/32x32",
|
||||
"balance": "$3,664.47",
|
||||
"isActive": true,
|
||||
"guid": "f9933a9c-c41a-412f-a18d-e727c569870b",
|
||||
"index": 2,
|
||||
"_id": "551b91197f170b65413a06e3"
|
||||
},
|
||||
{
|
||||
"favoriteFruit": "banana",
|
||||
"greeting": "Hello, Neva! You have 7 unread messages.",
|
||||
"friends": [
|
||||
{
|
||||
"name": "Clara Cotton",
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "Ray Gates",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "Jacobs Reese",
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"range": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"tags": [
|
||||
"magna",
|
||||
"labore",
|
||||
"incididunt",
|
||||
"velit",
|
||||
"ea",
|
||||
"et",
|
||||
"eiusmod"
|
||||
],
|
||||
"longitude": -133.058479,
|
||||
"latitude": 87.803677,
|
||||
"registered": "Friday, May 9, 2014 5:41 PM",
|
||||
"about": "Do duis occaecat ut officia occaecat officia nostrud reprehenderit ex excepteur aute anim in reprehenderit. Cupidatat nulla eiusmod nulla non minim veniam aute nulla deserunt adipisicing consectetur veniam. Sit consequat ex laboris aliqua labore consectetur tempor proident consequat est. Fugiat quis esse culpa aliquip. Excepteur laborum aliquip sunt eu cupidatat magna eiusmod amet nisi labore aliquip. Ut consectetur esse aliquip exercitation nulla ex occaecat elit do ex eiusmod deserunt. Ex eu voluptate minim deserunt fugiat minim est occaecat ad Lorem nisi.\r\n",
|
||||
"address": "480 Eagle Street, Fostoria, Oklahoma, 2614",
|
||||
"phone": "+1 (983) 439-3000",
|
||||
"email": "neva.barker@pushcart.us",
|
||||
"company": "PUSHCART",
|
||||
"name": {
|
||||
"last": "Barker",
|
||||
"first": "Neva"
|
||||
},
|
||||
"eyeColor": "brown",
|
||||
"age": 36,
|
||||
"picture": "http://placehold.it/32x32",
|
||||
"balance": "$3,182.24",
|
||||
"isActive": true,
|
||||
"guid": "52489849-78e1-4b27-8b86-e3e5ab2b7dc8",
|
||||
"index": 3,
|
||||
"_id": "551b9119a13061c083c878d5"
|
||||
},
|
||||
{
|
||||
"favoriteFruit": "banana",
|
||||
"greeting": "Hello, Rodgers! You have 6 unread messages.",
|
||||
"friends": [
|
||||
{
|
||||
"name": "Marguerite Conway",
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "Margarita Cunningham",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "Carmela Gallagher",
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"range": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"tags": [
|
||||
"ipsum",
|
||||
"magna",
|
||||
"amet",
|
||||
"elit",
|
||||
"sit",
|
||||
"occaecat",
|
||||
"elit"
|
||||
],
|
||||
"longitude": -125.436981,
|
||||
"latitude": 19.868524,
|
||||
"registered": "Tuesday, July 8, 2014 8:09 PM",
|
||||
"about": "In cillum esse tempor do magna id ad excepteur ex nostrud mollit deserunt aliqua. Minim aliqua commodo commodo consectetur exercitation nulla nisi dolore aliqua in. Incididunt deserunt mollit nostrud excepteur. Ipsum fugiat anim deserunt Lorem aliquip nisi consequat eu minim in ex duis.\r\n",
|
||||
"address": "989 Varanda Place, Duryea, Palau, 3972",
|
||||
"phone": "+1 (968) 578-2974",
|
||||
"email": "rodgers.conner@frenex.net",
|
||||
"company": "FRENEX",
|
||||
"name": {
|
||||
"last": "Conner",
|
||||
"first": "Rodgers"
|
||||
},
|
||||
"eyeColor": "blue",
|
||||
"age": 23,
|
||||
"picture": "http://placehold.it/32x32",
|
||||
"balance": "$1,665.17",
|
||||
"isActive": true,
|
||||
"guid": "ed3b2374-5afe-4fca-9325-8a7bbc9f81a0",
|
||||
"index": 4,
|
||||
"_id": "551b91197bcedb1b56a241ce"
|
||||
},
|
||||
{
|
||||
"favoriteFruit": "strawberry",
|
||||
"greeting": "Hello, Mari! You have 10 unread messages.",
|
||||
"friends": [
|
||||
{
|
||||
"name": "Irwin Boyd",
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "Dejesus Flores",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "Lane Mcmahon",
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"range": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"tags": [
|
||||
"esse",
|
||||
"aliquip",
|
||||
"excepteur",
|
||||
"dolor",
|
||||
"ex",
|
||||
"commodo",
|
||||
"anim"
|
||||
],
|
||||
"longitude": -17.038176,
|
||||
"latitude": 17.154663,
|
||||
"registered": "Sunday, April 6, 2014 4:46 AM",
|
||||
"about": "Excepteur veniam occaecat sint nulla magna in in officia elit. Eiusmod qui dolor fugiat tempor in minim esse officia minim consequat. Lorem ullamco labore proident ipsum id pariatur fugiat consectetur anim cupidatat qui proident non ipsum.\r\n",
|
||||
"address": "563 Hendrickson Street, Westwood, South Dakota, 4959",
|
||||
"phone": "+1 (980) 434-3976",
|
||||
"email": "mari.fleming@beadzza.org",
|
||||
"company": "BEADZZA",
|
||||
"name": {
|
||||
"last": "Fleming",
|
||||
"first": "Mari"
|
||||
},
|
||||
"eyeColor": "blue",
|
||||
"age": 21,
|
||||
"picture": "http://placehold.it/32x32",
|
||||
"balance": "$1,948.04",
|
||||
"isActive": true,
|
||||
"guid": "6bd02166-3b1f-4ed8-84c9-ed96cbf12abc",
|
||||
"index": 5,
|
||||
"_id": "551b9119b359ff6d24846f77"
|
||||
},
|
||||
{
|
||||
"favoriteFruit": "strawberry",
|
||||
"greeting": "Hello, Maxine! You have 7 unread messages.",
|
||||
"friends": [
|
||||
{
|
||||
"name": "Sullivan Stark",
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "Underwood Mclaughlin",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "Kristy Carlson",
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"range": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"tags": [
|
||||
"commodo",
|
||||
"ipsum",
|
||||
"quis",
|
||||
"non",
|
||||
"est",
|
||||
"mollit",
|
||||
"exercitation"
|
||||
],
|
||||
"longitude": -105.40635,
|
||||
"latitude": 37.197993,
|
||||
"registered": "Tuesday, January 20, 2015 12:30 AM",
|
||||
"about": "Proident ullamco Lorem est consequat consectetur non eiusmod esse nostrud pariatur eiusmod enim exercitation eiusmod. Consequat duis elit elit minim ullamco et dolor eu minim do tempor esse consequat excepteur. Mollit dolor do voluptate nostrud quis anim cillum velit tempor eiusmod adipisicing tempor do culpa. Eu magna dolor sit amet nisi do laborum dolore nisi. Deserunt ipsum et deserunt non nisi.\r\n",
|
||||
"address": "252 Boulevard Court, Brenton, Tennessee, 9444",
|
||||
"phone": "+1 (950) 466-3377",
|
||||
"email": "maxine.moreno@zentia.tv",
|
||||
"company": "ZENTIA",
|
||||
"name": {
|
||||
"last": "Moreno",
|
||||
"first": "Maxine"
|
||||
},
|
||||
"eyeColor": "brown",
|
||||
"age": 24,
|
||||
"picture": "http://placehold.it/32x32",
|
||||
"balance": "$1,200.24",
|
||||
"isActive": false,
|
||||
"guid": "ce307a37-ca1f-43f5-b637-dca2605712be",
|
||||
"index": 6,
|
||||
"_id": "551b91195a6164b2e35f6dc8"
|
||||
},
|
||||
{
|
||||
"favoriteFruit": "strawberry",
|
||||
"greeting": "Hello, Helga! You have 5 unread messages.",
|
||||
"friends": [
|
||||
{
|
||||
"name": "Alicia Vance",
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "Vinson Phelps",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "Francisca Kelley",
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"range": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"tags": [
|
||||
"nostrud",
|
||||
"eiusmod",
|
||||
"dolore",
|
||||
"officia",
|
||||
"sint",
|
||||
"non",
|
||||
"qui"
|
||||
],
|
||||
"longitude": -7.275151,
|
||||
"latitude": 75.54202,
|
||||
"registered": "Wednesday, October 1, 2014 6:35 PM",
|
||||
"about": "Quis duis ullamco velit qui. Consectetur non adipisicing id magna anim. Deserunt est officia qui esse. Et do pariatur incididunt anim ad mollit non. Et eiusmod sunt fugiat elit mollit ad excepteur anim nisi laboris eiusmod aliquip aliquip.\r\n",
|
||||
"address": "981 Bush Street, Beaulieu, Vermont, 3775",
|
||||
"phone": "+1 (956) 506-3807",
|
||||
"email": "helga.burch@synkgen.name",
|
||||
"company": "SYNKGEN",
|
||||
"name": {
|
||||
"last": "Burch",
|
||||
"first": "Helga"
|
||||
},
|
||||
"eyeColor": "blue",
|
||||
"age": 22,
|
||||
"picture": "http://placehold.it/32x32",
|
||||
"balance": "$3,827.89",
|
||||
"isActive": false,
|
||||
"guid": "ff5dfea0-1052-4ef2-8b66-4dc1aad0a4fb",
|
||||
"index": 7,
|
||||
"_id": "551b911946be8358ae40e90e"
|
||||
},
|
||||
{
|
||||
"favoriteFruit": "banana",
|
||||
"greeting": "Hello, Shaw! You have 5 unread messages.",
|
||||
"friends": [
|
||||
{
|
||||
"name": "Christian Cardenas",
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "Cohen Pennington",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "Mary Lindsay",
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"range": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"tags": [
|
||||
"occaecat",
|
||||
"ut",
|
||||
"occaecat",
|
||||
"magna",
|
||||
"exercitation",
|
||||
"incididunt",
|
||||
"irure"
|
||||
],
|
||||
"longitude": -89.102972,
|
||||
"latitude": 89.489596,
|
||||
"registered": "Thursday, August 21, 2014 5:00 PM",
|
||||
"about": "Amet cupidatat quis velit aute Lorem consequat pariatur mollit deserunt et sint culpa excepteur duis. Enim proident duis qui ex tempor sunt nostrud occaecat. Officia sit veniam mollit eiusmod minim do aute eiusmod fugiat qui anim adipisicing in laboris. Do tempor reprehenderit sunt laborum esse irure dolor ad consectetur aute sit id ipsum. Commodo et voluptate anim consequat do. Minim laborum ad veniam ad minim incididunt excepteur excepteur aliqua.\r\n",
|
||||
"address": "237 Pierrepont Street, Herbster, New York, 3490",
|
||||
"phone": "+1 (976) 455-2880",
|
||||
"email": "shaw.zamora@shadease.me",
|
||||
"company": "SHADEASE",
|
||||
"name": {
|
||||
"last": "Zamora",
|
||||
"first": "Shaw"
|
||||
},
|
||||
"eyeColor": "blue",
|
||||
"age": 38,
|
||||
"picture": "http://placehold.it/32x32",
|
||||
"balance": "$3,440.82",
|
||||
"isActive": false,
|
||||
"guid": "ac5fdb0e-e1fb-427e-881d-da461be0d1ca",
|
||||
"index": 8,
|
||||
"_id": "551b9119af0077bc28a2de25"
|
||||
},
|
||||
{
|
||||
"favoriteFruit": "apple",
|
||||
"greeting": "Hello, Melissa! You have 5 unread messages.",
|
||||
"friends": [
|
||||
{
|
||||
"name": "Marion Villarreal",
|
||||
"id": 0
|
||||
},
|
||||
{
|
||||
"name": "Kate Rose",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"name": "Hines Simon",
|
||||
"id": 2
|
||||
}
|
||||
],
|
||||
"range": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
],
|
||||
"tags": [
|
||||
"amet",
|
||||
"veniam",
|
||||
"mollit",
|
||||
"ad",
|
||||
"cupidatat",
|
||||
"deserunt",
|
||||
"Lorem"
|
||||
],
|
||||
"longitude": -52.735052,
|
||||
"latitude": 16.258838,
|
||||
"registered": "Wednesday, April 16, 2014 7:56 PM",
|
||||
"about": "Aute ut culpa eiusmod tempor duis dolor tempor incididunt. Nisi non proident excepteur eiusmod incididunt nisi minim irure sit. In veniam commodo deserunt proident reprehenderit et consectetur ullamco quis nulla cupidatat.\r\n",
|
||||
"address": "642 Halsey Street, Blandburg, Kansas, 6761",
|
||||
"phone": "+1 (941) 539-3851",
|
||||
"email": "melissa.vaughn@memora.io",
|
||||
"company": "MEMORA",
|
||||
"name": {
|
||||
"last": "Vaughn",
|
||||
"first": "Melissa"
|
||||
},
|
||||
"eyeColor": "brown",
|
||||
"age": 24,
|
||||
"picture": "http://placehold.it/32x32",
|
||||
"balance": "$2,399.44",
|
||||
"isActive": true,
|
||||
"guid": "1769f022-a7f1-4a69-bf4c-f5a5ebeab2d1",
|
||||
"index": 9,
|
||||
"_id": "551b9119b607c09c7ffc3b8a"
|
||||
}
|
||||
]
|
||||
102
bin/types/nulls.json
Executable file
102
bin/types/nulls.json
Executable file
@@ -0,0 +1,102 @@
|
||||
[
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]
|
||||
102
bin/types/paragraphs.json
Executable file
102
bin/types/paragraphs.json
Executable file
@@ -0,0 +1,102 @@
|
||||
[
|
||||
"Commodo ullamco cupidatat nisi sit proident ex. Cillum pariatur occaecat in officia do commodo nisi cillum tempor minim. Ad dolor ut et aliquip fugiat eu officia cupidatat occaecat consectetur eiusmod veniam enim officia.\r\n",
|
||||
"Adipisicing cillum laborum nisi irure. Cillum dolor proident duis nulla qui mollit dolore reprehenderit mollit. Irure nulla dolor ipsum irure nulla quis laboris do.\r\n",
|
||||
"Est adipisicing consectetur incididunt in. Occaecat ea magna ex consequat irure sit laborum cillum officia magna sunt do exercitation aliquip. Laboris id aute in dolore reprehenderit voluptate non deserunt laborum.\r\n",
|
||||
"Consectetur eu aute est est occaecat adipisicing sint enim dolor eu. Tempor amet id non mollit eu consectetur cillum duis. Eu labore velit nulla ipsum commodo consequat aliquip. Cupidatat commodo dolore mollit enim sit excepteur nisi duis laboris deserunt esse.\r\n",
|
||||
"Incididunt ullamco est fugiat enim fugiat. Do sit mollit anim ad excepteur eu laboris exercitation officia labore nulla ut. Voluptate non voluptate cillum sit et voluptate anim duis velit consequat aliquip dolor. Elit et et esse laboris consectetur officia eiusmod aliquip nisi est. Qui labore dolore ad dolor.\r\n",
|
||||
"Anim adipisicing est irure proident sit officia ullamco voluptate sunt consectetur duis mollit excepteur veniam. Nostrud ut duis aute exercitation officia et quis elit commodo elit tempor aute aliquip enim. Est officia non cillum consequat voluptate ipsum sit voluptate nulla id.\r\n",
|
||||
"Ipsum enim consectetur aliquip nulla commodo ut ex aliqua elit duis do. Officia et sunt aliqua dolor minim voluptate veniam esse elit enim. Adipisicing reprehenderit duis ex magna non in fugiat sunt ipsum nostrud fugiat aliquip. Labore voluptate id officia voluptate eu. Magna do nostrud excepteur sunt aliqua adipisicing qui.\r\n",
|
||||
"Est occaecat non non cupidatat laborum qui. Veniam sit est voluptate labore sit irure consectetur fugiat. Anim enim enim fugiat exercitation anim ad proident esse in aliqua. Laboris ut aute culpa ullamco.\r\n",
|
||||
"Sit et aliquip cupidatat deserunt eiusmod sint aliquip occaecat nostrud aliqua elit commodo ut magna. Amet sit est deserunt id duis in officia pariatur cupidatat ex. Mollit duis est consequat nulla aute velit ipsum sit consectetur pariatur ut non ex ipsum. Tempor esse velit pariatur reprehenderit et nostrud commodo laborum mollit labore.\r\n",
|
||||
"Aliquip irure quis esse aliquip. Ex non deserunt culpa aliqua ad anim occaecat ad. Lorem consectetur mollit eu consectetur est non nisi non ipsum. Qui veniam ullamco officia est ut excepteur. Nulla elit dolore cupidatat aliqua enim Lorem elit consequat eiusmod non aliqua eu in. Pariatur in culpa labore sint ipsum consectetur occaecat ad ex ipsum laboris aliquip officia. Non officia eiusmod nisi officia id id laboris deserunt sunt enim magna mollit sit.\r\n",
|
||||
"Mollit velit laboris laborum nulla aliquip consequat Lorem non incididunt irure. Eu voluptate sint do consectetur tempor sit Lorem in. Laborum eiusmod nisi Lorem ipsum dolore do aute laborum occaecat aute sunt. Sit laborum in ea do ipsum officia irure cillum irure nisi laboris. Ad anim deserunt excepteur ea veniam eiusmod culpa velit veniam. Commodo incididunt ea Lorem eu enim esse nisi incididunt mollit.\r\n",
|
||||
"Velit proident sunt aute dolore reprehenderit culpa. Pariatur reprehenderit commodo ad ea voluptate anim nulla ipsum eu irure fugiat aliqua et. Adipisicing incididunt anim excepteur voluptate minim qui culpa. Sunt veniam enim reprehenderit magna magna. Sit ad amet deserunt ut aute dolore ad minim.\r\n",
|
||||
"Esse ullamco sunt mollit mollit. Eu enim dolore laboris cupidatat. Cupidatat adipisicing non aute exercitation fugiat. Non ut cillum labore fugiat aliquip ex duis quis consectetur ut nisi Lorem amet qui. Proident veniam amet qui reprehenderit duis qui. Nisi culpa sit occaecat ullamco occaecat laborum fugiat ut. Non duis deserunt culpa duis.\r\n",
|
||||
"Id ipsum eiusmod laboris non est ipsum deserunt labore duis reprehenderit deserunt. Sint tempor fugiat eiusmod nostrud in ut laborum esse in nostrud sit deserunt nostrud reprehenderit. Cupidatat aliqua qui anim consequat eu quis consequat consequat elit ipsum pariatur. Cupidatat in dolore velit quis. Exercitation cillum ullamco ex consectetur commodo tempor incididunt exercitation labore ad dolore. Minim incididunt consequat adipisicing esse eu eu voluptate.\r\n",
|
||||
"Anim sint eiusmod nisi anim do deserunt voluptate ut cillum eiusmod esse ex reprehenderit laborum. Dolore nulla excepteur duis excepteur. Magna nisi nostrud duis non commodo velit esse ipsum Lorem incididunt. Nulla enim consequat ad aliqua. Incididunt irure culpa nostrud ea aute ex sit non ad esse.\r\n",
|
||||
"Ullamco nostrud cupidatat adipisicing anim fugiat mollit eu. Et ut eu in nulla consequat. Sunt do pariatur culpa non est.\r\n",
|
||||
"Pariatur incididunt reprehenderit non qui excepteur cillum exercitation nisi occaecat ad. Lorem aliquip laborum commodo reprehenderit sint. Laboris qui ut veniam magna quis et et ullamco voluptate. Tempor reprehenderit deserunt consequat nisi. Esse duis sint in tempor. Amet aute cupidatat in sint et.\r\n",
|
||||
"Est officia nisi dolore consequat irure et excepteur. Sit qui elit tempor magna qui cillum anim amet proident exercitation proident. Eu cupidatat laborum consectetur duis ullamco irure nulla. Adipisicing culpa non reprehenderit anim aute.\r\n",
|
||||
"Eu est laborum culpa velit dolore non sunt. Tempor magna veniam ea sit non qui Lorem qui exercitation aliqua aliqua et excepteur eiusmod. Culpa aute anim proident culpa adipisicing duis tempor elit aliquip elit nulla laboris esse dolore. Sit adipisicing non dolor eiusmod occaecat cupidatat.\r\n",
|
||||
"Culpa velit eu esse sunt. Laborum irure aliqua reprehenderit velit ipsum fugiat officia dolor ut aute officia deserunt. Ipsum sit quis fugiat nostrud aliqua cupidatat ex pariatur et. Cillum proident est irure nisi dolor aliqua deserunt esse occaecat velit dolor.\r\n",
|
||||
"Exercitation nulla officia sit eiusmod cillum eu incididunt officia exercitation qui Lorem deserunt. Voluptate Lorem minim commodo laborum esse in duis excepteur do duis aliquip nisi voluptate consectetur. Amet tempor officia enim ex esse minim reprehenderit.\r\n",
|
||||
"Laboris sint deserunt ad aute incididunt. Anim officia sunt elit qui laborum labore commodo irure non. Mollit adipisicing ullamco do aute nulla eu laborum et quis sint aute adipisicing amet. Aliqua officia irure nostrud duis ex.\r\n",
|
||||
"Eiusmod ipsum aliqua reprehenderit esse est non aute id veniam eiusmod. Elit consequat ad sit tempor elit eu incididunt quis irure ad. Eu incididunt veniam consequat Lorem nostrud cillum officia ea consequat ad cillum. Non nisi irure cupidatat incididunt pariatur incididunt. Duis velit officia ad cillum qui. Aliquip consequat sint aute nisi cillum. Officia commodo nisi incididunt laborum nisi voluptate aliquip Lorem cupidatat anim consequat sit laboris.\r\n",
|
||||
"Veniam cupidatat et incididunt mollit do ex voluptate veniam nostrud labore esse. Eiusmod irure sint fugiat esse. Aute irure consectetur ut mollit nulla sint esse. Lorem ut quis ex proident nostrud mollit nostrud ea duis duis in magna anim consectetur.\r\n",
|
||||
"Irure culpa esse qui do dolor fugiat veniam ad. Elit commodo aute elit magna incididunt tempor pariatur velit irure pariatur cillum et ea ad. Ad consequat ea et ad minim ut sunt qui commodo voluptate. Laboris est aliquip anim reprehenderit eu officia et exercitation. Occaecat laboris cupidatat Lorem ullamco in nostrud commodo ipsum in quis esse ex.\r\n",
|
||||
"Incididunt officia quis voluptate eiusmod esse nisi ipsum quis commodo. Eiusmod dolore tempor occaecat sit exercitation aliqua minim consequat minim mollit qui ad nisi. Aute quis irure adipisicing veniam nisi nisi velit deserunt incididunt anim nostrud.\r\n",
|
||||
"Voluptate exercitation exercitation id minim excepteur excepteur mollit. Fugiat aute proident nulla ullamco ea. Nisi ea culpa duis dolore veniam anim tempor officia in dolore exercitation exercitation. Dolore quis cillum adipisicing sunt do nulla esse proident ad sint.\r\n",
|
||||
"Laborum ut mollit sint commodo nulla laborum deserunt Lorem magna commodo mollit tempor deserunt ut. Qui aliquip commodo ea id. Consectetur dolor fugiat dolor excepteur eiusmod. Eu excepteur ex aute ex ex elit ex esse officia cillum exercitation. Duis ut labore ea nostrud excepteur. Reprehenderit labore aute sunt nisi quis Lorem officia. Ad aliquip cupidatat voluptate exercitation voluptate ad irure magna quis.\r\n",
|
||||
"Tempor velit veniam sit labore elit minim do elit cillum eiusmod sunt excepteur nisi. Aliquip est deserunt excepteur duis fugiat incididunt veniam fugiat. Pariatur sit irure labore et minim non. Cillum quis aute anim sint laboris laboris ullamco exercitation nostrud. Nulla pariatur id laborum minim nisi est adipisicing irure.\r\n",
|
||||
"Irure exercitation laboris nostrud in do consectetur ad. Magna aliqua Lorem culpa exercitation sint do culpa incididunt mollit eu exercitation. Elit tempor Lorem dolore enim deserunt. Anim et ullamco sint ullamco mollit cillum officia et. Proident incididunt laboris aliquip laborum sint veniam deserunt eu consequat deserunt voluptate laboris. Anim Lorem non laborum exercitation voluptate. Cupidatat reprehenderit culpa Lorem fugiat enim minim consectetur tempor quis ad reprehenderit laboris irure.\r\n",
|
||||
"Deserunt elit mollit nostrud occaecat labore reprehenderit laboris ex. Esse reprehenderit adipisicing cillum minim in esse aliquip excepteur ex et nisi cillum quis. Cillum labore ut ex sunt. Occaecat proident et mollit magna consequat irure esse. Dolor do enim esse nisi ad.\r\n",
|
||||
"Pariatur est anim cillum minim elit magna adipisicing quis tempor proident nisi laboris incididunt cupidatat. Nulla est adipisicing sit adipisicing id nostrud amet qui consequat eiusmod tempor voluptate ad. Adipisicing non magna sit occaecat magna mollit ad ex nulla velit ea pariatur. Irure labore ad ea exercitation ex cillum.\r\n",
|
||||
"Lorem fugiat eu eu cillum nulla tempor sint. Lorem id officia nulla velit labore ut duis ad tempor non. Excepteur quis aute adipisicing nisi nisi consectetur aliquip enim Lorem id ullamco cillum sint voluptate. Qui aliquip incididunt tempor aliqua voluptate labore reprehenderit. Veniam eiusmod elit occaecat voluptate tempor culpa consectetur ea ut exercitation eiusmod exercitation qui.\r\n",
|
||||
"Aliqua esse pariatur nulla veniam velit ea. Aliquip consectetur tempor ex magna sit aliquip exercitation veniam. Dolor ullamco minim commodo pariatur. Et amet reprehenderit dolore proident elit tempor eiusmod eu incididunt enim ullamco. Adipisicing id officia incididunt esse dolor sunt cupidatat do deserunt mollit do non. Magna ut officia fugiat adipisicing quis ea cillum laborum dolore ad nostrud magna minim est. Dolor voluptate officia proident enim ea deserunt eu voluptate dolore proident laborum officia ea.\r\n",
|
||||
"Culpa aute consequat esse fugiat cupidatat minim voluptate voluptate eiusmod irure anim elit. Do eiusmod culpa laboris consequat incididunt minim nostrud eiusmod commodo velit ea ullamco proident. Culpa pariatur magna ut mollit nisi. Ea officia do magna deserunt minim nisi tempor ea deserunt veniam cillum exercitation esse.\r\n",
|
||||
"Anim ullamco nostrud commodo Lorem. Do sunt laborum exercitation proident proident magna. Lorem officia laborum laborum dolor sunt duis commodo Lorem. Officia aute adipisicing ea cupidatat ea dolore. Aliquip adipisicing pariatur consectetur aliqua sit amet officia reprehenderit laborum culpa. Occaecat Lorem eu nisi do Lorem occaecat enim eiusmod laboris id quis. Ad mollit adipisicing sunt adipisicing esse.\r\n",
|
||||
"Laborum quis sit adipisicing cupidatat. Veniam Lorem eiusmod esse esse sint nisi labore elit et. Deserunt aliqua mollit ut commodo aliqua non incididunt ipsum reprehenderit consectetur. Eiusmod nulla minim laboris Lorem ea Lorem aute tempor pariatur in sit. Incididunt culpa ut do irure amet irure cupidatat est anim anim culpa occaecat. Est velit consectetur eiusmod veniam reprehenderit officia sunt occaecat eiusmod ut sunt occaecat amet.\r\n",
|
||||
"Elit minim aute fugiat nulla ex quis. Labore fugiat sint nostrud amet quis culpa excepteur in. Consectetur exercitation cupidatat laborum sit. Aute nisi eu aliqua est deserunt eiusmod commodo dolor id. Mollit laborum esse sint ipsum voluptate reprehenderit velit et. Veniam aliquip enim in veniam Lorem voluptate quis deserunt consequat qui commodo ut excepteur aute.\r\n",
|
||||
"Dolore deserunt veniam aute nisi labore sunt et voluptate irure nisi anim ea. Magna nisi quis anim mollit nisi est dolor do ex aliquip elit aliquip ipsum minim. Dolore est officia nostrud eiusmod ex laborum ea amet est. Officia culpa non est et tempor consectetur exercitation tempor eiusmod enim. Ea tempor laboris qui amet ex nisi culpa dolore consectetur incididunt sunt sunt. Lorem aliquip incididunt magna do et ullamco ex elit aliqua eiusmod qui. Commodo amet dolor sint incididunt ex veniam non Lorem fugiat.\r\n",
|
||||
"Officia culpa enim voluptate dolore commodo. Minim commodo aliqua minim ex sint excepteur cupidatat adipisicing eu irure. Anim magna deserunt anim Lorem non.\r\n",
|
||||
"Cupidatat aliquip nulla excepteur sunt cupidatat cupidatat laborum cupidatat exercitation. Laboris minim ex cupidatat culpa elit. Amet enim reprehenderit aliqua laborum est tempor exercitation cupidatat ex dolore do. Do incididunt labore fugiat commodo consectetur nisi incididunt irure sit culpa sit. Elit aute occaecat qui excepteur velit proident cillum qui aliqua ex do ex. Dolore irure ex excepteur veniam id proident mollit Lorem.\r\n",
|
||||
"Ad commodo cillum duis deserunt elit officia consectetur veniam eiusmod. Reprehenderit et veniam ad commodo reprehenderit magna elit laboris sunt non quis. Adipisicing dolor aute proident ea magna sunt et proident in consectetur.\r\n",
|
||||
"Veniam exercitation esse esse veniam est nisi. Minim velit incididunt sint aute dolor anim. Fugiat cupidatat id ad nisi in voluptate dolor culpa eiusmod magna eiusmod amet id. Duis aliquip labore et ex amet amet aliquip laborum eiusmod ipsum. Quis qui ut duis duis. Minim in voluptate reprehenderit aliqua.\r\n",
|
||||
"Elit ut pariatur dolor veniam ipsum consequat. Voluptate Lorem mollit et esse dolore mollit Lorem ad. Elit nostrud eu Lorem labore mollit minim cupidatat officia quis minim dolore incididunt. In cillum aute cillum ut.\r\n",
|
||||
"Commodo laborum deserunt ut cupidatat pariatur ullamco in esse anim exercitation cillum duis. Consectetur incididunt sit esse Lorem in aute. Eiusmod mollit Lorem consequat minim reprehenderit laborum enim excepteur irure nisi elit. Laborum esse proident aute aute proident adipisicing laborum. Pariatur tempor duis incididunt qui velit pariatur ut officia ea mollit labore dolore. Cillum pariatur minim ullamco sunt incididunt culpa id ullamco exercitation consectetur. Ea exercitation consequat reprehenderit ut ullamco velit eu ad velit magna excepteur eiusmod.\r\n",
|
||||
"Eu deserunt magna laboris laborum laborum in consequat dolore. Officia proident consectetur proident do occaecat minim pariatur officia ipsum sit non velit officia cillum. Laborum excepteur labore eu minim eiusmod. Sit anim dolore cillum ad do minim culpa sit est ad.\r\n",
|
||||
"Cupidatat dolor nostrud Lorem sint consequat quis. Quis labore sint incididunt officia tempor. Fugiat nostrud in elit reprehenderit dolor. Nisi sit enim officia minim est adipisicing nulla aute labore nulla nostrud cupidatat est. Deserunt dolore qui irure Lorem esse voluptate velit qui nostrud.\r\n",
|
||||
"Fugiat Lorem amet nulla nisi qui amet laboris enim cillum. Dolore occaecat exercitation id labore velit do commodo ut cupidatat laborum velit fugiat mollit. Ut et aliqua pariatur occaecat. Lorem occaecat dolore quis esse enim cupidatat exercitation ut tempor sit laboris fugiat adipisicing. Est tempor ex irure consectetur ipsum magna labore. Lorem non quis qui minim nisi magna amet aliquip ex cillum fugiat tempor.\r\n",
|
||||
"Aliquip eiusmod laborum ipsum deserunt velit esse do magna excepteur consectetur exercitation sit. Minim ullamco reprehenderit commodo nostrud exercitation id irure ex qui ullamco sit esse laboris. Nulla cillum non minim qui cillum nisi aute proident. Dolor anim culpa elit quis excepteur aliqua eiusmod. Elit ea est excepteur consectetur sunt eiusmod enim id commodo irure amet et pariatur laboris. Voluptate magna ad magna dolore cillum cillum irure laboris ipsum officia id Lorem veniam.\r\n",
|
||||
"Esse sunt elit est aliquip cupidatat commodo deserunt. Deserunt pariatur ipsum qui ad esse esse magna qui cillum laborum. Exercitation veniam pariatur elit amet enim.\r\n",
|
||||
"Esse quis in id elit nulla occaecat incididunt. Et amet Lorem mollit in veniam do. Velit mollit Lorem consequat commodo Lorem aliquip cupidatat. Minim consequat nostrud nulla in nostrud.\r\n",
|
||||
"Cillum nulla et eu est nostrud quis elit cupidatat dolor enim excepteur exercitation nisi voluptate. Nulla dolore non ex velit et qui tempor proident id deserunt nisi eu. Tempor ad Lorem ipsum reprehenderit in anim. Anim dolore ullamco enim deserunt quis ex id exercitation velit. Magna exercitation fugiat mollit pariatur ipsum ex consectetur nostrud. Id dolore officia nostrud excepteur laborum. Magna incididunt elit ipsum pariatur adipisicing enim duis est qui commodo velit aute.\r\n",
|
||||
"Quis esse ex qui nisi dolor. Ullamco laborum dolor esse laboris eiusmod ea magna laboris ea esse ut. Dolore ipsum pariatur veniam sint mollit. Lorem ea proident fugiat ullamco ut nisi culpa eu exercitation exercitation aliquip veniam laborum consectetur.\r\n",
|
||||
"Pariatur veniam laboris sit aliquip pariatur tempor aute sunt id et ut. Laboris excepteur eiusmod nisi qui quis elit enim ut cupidatat. Et et laborum in fugiat veniam consectetur ipsum laboris duis excepteur ullamco aliqua dolor Lorem. Aliqua ex amet sint anim cupidatat nisi ipsum anim et sunt deserunt. Occaecat culpa ut tempor cillum pariatur ex tempor.\r\n",
|
||||
"Dolor deserunt eiusmod magna do officia voluptate excepteur est cupidatat. Veniam qui cupidatat amet anim est qui consectetur sit commodo commodo ea ad. Enim ad adipisicing qui nostrud. Non nulla esse ullamco nulla et ex.\r\n",
|
||||
"Id ullamco ea consectetur est incididunt deserunt et esse. Elit nostrud voluptate eiusmod ut. Excepteur adipisicing qui cupidatat consequat labore id. Qui dolor aliqua do dolore do cupidatat labore ex consectetur ea sit cillum. Sint veniam eiusmod in consectetur consequat fugiat et mollit ut fugiat esse dolor adipisicing.\r\n",
|
||||
"Ea magna proident labore duis pariatur. Esse cillum aliquip dolor duis fugiat ea ex officia ea irure. Sint elit nisi pariatur sunt nostrud exercitation ullamco culpa magna do.\r\n",
|
||||
"Minim aliqua voluptate dolor consequat sint tempor deserunt amet magna excepteur. Irure do voluptate magna velit. Nostrud in reprehenderit magna officia nostrud. Cupidatat nulla irure laboris non fugiat ex ex est cupidatat excepteur officia aute velit duis. Sit voluptate id ea exercitation deserunt culpa voluptate nostrud est adipisicing incididunt. Amet proident laborum commodo magna ipsum quis.\r\n",
|
||||
"Ipsum consectetur consectetur excepteur tempor eiusmod ea fugiat aute velit magna in officia sunt. Sit ut sunt dolore cupidatat dolor adipisicing. Veniam nisi adipisicing esse reprehenderit amet aliqua voluptate ex commodo occaecat est voluptate mollit sunt. Pariatur aliqua qui qui in dolor. Fugiat reprehenderit sit nostrud do sint esse. Tempor sit irure adipisicing ea pariatur duis est sit est incididunt laboris quis do. Et voluptate anim minim aliquip excepteur consequat nisi anim pariatur aliquip ut ipsum dolor magna.\r\n",
|
||||
"Cillum sit labore excepteur magna id aliqua exercitation consequat laborum Lorem id pariatur nostrud. Lorem qui est labore sint cupidatat sint excepteur nulla in eu aliqua et. Adipisicing velit do enim occaecat laboris quis excepteur ipsum dolor occaecat Lorem dolore id exercitation.\r\n",
|
||||
"Incididunt in laborum reprehenderit eiusmod irure ex. Elit duis consequat minim magna. Esse consectetur aliquip cillum excepteur excepteur fugiat. Sint tempor consequat minim reprehenderit consectetur adipisicing dolor id Lorem elit non. Occaecat esse quis mollit ea et sint aute fugiat qui tempor. Adipisicing tempor duis non dolore irure elit deserunt qui do.\r\n",
|
||||
"Labore fugiat eiusmod sint laborum sit duis occaecat. Magna in laborum non cillum excepteur nostrud sit proident pariatur voluptate voluptate adipisicing exercitation occaecat. Ad non dolor aute ex sint do do minim exercitation veniam laborum irure magna ea. Magna do non quis sit consequat Lorem aliquip.\r\n",
|
||||
"Velit anim do laborum laboris laborum Lorem. Sunt do Lorem amet ipsum est sint velit sit do voluptate mollit veniam enim. Commodo do deserunt in pariatur ut elit sint elit deserunt ea. Ad dolor anim consequat aliquip ut mollit nostrud tempor sunt mollit elit. Reprehenderit laboris labore excepteur occaecat veniam adipisicing cupidatat esse. Ad enim aliquip ea minim excepteur magna. Sint velit veniam pariatur qui dolor est adipisicing ex laboris.\r\n",
|
||||
"Ea cupidatat ex nulla in sunt est sit dolor enim ad. Eu tempor consequat cupidatat consequat ex incididunt sint culpa. Est Lorem Lorem non cupidatat sunt ut aliqua non nostrud do ullamco. Reprehenderit ad ad nulla nostrud do nulla in. Ipsum adipisicing commodo mollit ipsum exercitation. Aliqua ea anim anim est elit. Ea incididunt consequat minim ad sunt eu cillum.\r\n",
|
||||
"Tempor quis excepteur eiusmod cupidatat ipsum occaecat id et occaecat. Eiusmod magna aliquip excepteur id amet elit. Ullamco dolore amet anim dolor enim ea magna magna elit. Occaecat magna pariatur in deserunt consectetur officia aliquip ullamco ex aute anim. Minim laborum eu sit elit officia esse do irure pariatur tempor et reprehenderit ullamco labore.\r\n",
|
||||
"Sit tempor eu minim dolore velit pariatur magna duis reprehenderit ea nulla in. Amet est do consectetur commodo do adipisicing adipisicing in amet. Cillum id ut commodo do pariatur duis aliqua nisi sint ad irure officia reprehenderit. Mollit labore id enim fugiat ullamco irure mollit cupidatat. Quis nisi amet labore eu dolor occaecat commodo aliqua laboris deserunt excepteur deserunt officia. Aliqua non ut sit ad. Laborum veniam ad velit minim dolore ea id magna dolor qui in.\r\n",
|
||||
"Dolore nostrud ipsum aliqua pariatur id reprehenderit enim ad eiusmod qui. Deserunt anim commodo pariatur excepteur velit eu irure nulla ex labore ipsum aliqua minim aute. Id consequat amet tempor aliquip ex elit adipisicing est do. Eu enim Lorem consectetur minim id irure nulla culpa. Consectetur do consequat aute tempor anim. Qui ad non elit dolor est adipisicing nisi amet cillum sunt quis anim laboris incididunt. Incididunt proident adipisicing labore Lorem.\r\n",
|
||||
"Et reprehenderit ea officia veniam. Aliquip ullamco consequat elit nisi magna mollit id elit. Amet amet sint velit labore ad nisi. Consectetur tempor id dolor aliqua esse deserunt amet. Qui laborum enim proident voluptate aute eu aute aute sit sit incididunt eu. Sunt ullamco nisi nostrud labore commodo non consectetur quis do duis minim irure. Tempor sint dolor sint aliquip dolore nostrud fugiat.\r\n",
|
||||
"Aute ullamco quis nisi ut excepteur nostrud duis elit. Veniam ex ad incididunt veniam voluptate. Commodo dolore ullamco sit sint adipisicing proident amet aute duis deserunt.\r\n",
|
||||
"Labore velit eu cillum nisi. Laboris do cupidatat et non duis cillum. Ullamco dolor tempor cupidatat voluptate laborum ullamco ea duis.\r\n",
|
||||
"Deserunt consequat aliqua duis aliquip nostrud nostrud dolore nisi. Culpa do sint laborum consectetur ipsum quis laborum laborum pariatur eiusmod. Consectetur laboris ad ad ut quis. Ullamco laboris qui velit id laborum voluptate qui aute nostrud aliquip ea.\r\n",
|
||||
"Ad cillum anim ex est consectetur mollit id in. Non enim aliquip consequat qui deserunt commodo cillum ad laborum fugiat. Dolor deserunt amet laborum tempor adipisicing voluptate dolor pariatur dolor cillum. Eu mollit ex sunt officia veniam qui est sunt proident. Non aliqua qui elit eu cupidatat ex enim ex proident. Lorem sit minim ullamco officia cupidatat duis minim. Exercitation laborum deserunt voluptate culpa tempor quis nulla id pariatur.\r\n",
|
||||
"Nostrud quis consectetur ut aliqua excepteur elit consectetur occaecat. Occaecat voluptate Lorem pariatur consequat ullamco fugiat minim. Anim voluptate eu eu cillum tempor dolore aliquip aliqua. Fugiat incididunt ut tempor amet minim. Voluptate nostrud minim pariatur non excepteur ullamco.\r\n",
|
||||
"Dolore nulla velit officia exercitation irure laboris incididunt anim in laborum in fugiat ut proident. Fugiat aute id consequat fugiat officia ut. Labore sint amet proident amet sint nisi laboris amet id ullamco culpa quis consequat proident. Magna do fugiat veniam dolore elit irure minim. Esse ullamco excepteur labore tempor labore fugiat dolore nisi cupidatat irure dolor pariatur. Magna excepteur laboris nisi eiusmod sit pariatur mollit.\r\n",
|
||||
"In enim aliquip officia ea ad exercitation cillum culpa occaecat dolore Lorem. Irure cillum commodo adipisicing sunt pariatur ea duis fugiat exercitation laboris culpa ullamco aute. Ut voluptate exercitation qui dolor. Irure et duis elit consequat deserunt proident.\r\n",
|
||||
"Officia ea Lorem sunt culpa id et tempor excepteur enim deserunt proident. Dolore aliquip dolor laboris cillum proident velit. Et culpa occaecat exercitation cupidatat irure sint adipisicing excepteur pariatur incididunt ad occaecat. Qui proident ipsum cillum minim. Quis ut culpa irure aliqua minim fugiat. In voluptate cupidatat fugiat est laborum dolor esse in pariatur voluptate.\r\n",
|
||||
"Voluptate enim ipsum officia aute ea adipisicing nisi ut ex do aliquip amet. Reprehenderit enim voluptate tempor ex adipisicing culpa. Culpa occaecat voluptate dolor mollit ipsum exercitation labore et tempor sit ea consectetur aliqua. Elit elit sit minim ea ea commodo do tempor cupidatat irure dolore. Occaecat esse adipisicing anim eiusmod commodo fugiat mollit amet. Incididunt tempor tempor qui occaecat cupidatat in.\r\n",
|
||||
"Ut qui anim velit enim aliquip do ut nulla labore. Mollit ut commodo ut eiusmod consectetur laboris aliqua qui voluptate culpa fugiat incididunt elit. Lorem ullamco esse elit elit. Labore amet incididunt ea nulla aliquip eiusmod. Sit nulla est voluptate officia ipsum aute aute cillum tempor deserunt. Laboris commodo eiusmod labore sunt aute excepteur ea consectetur reprehenderit veniam nisi. Culpa nisi sint sunt sint tempor laboris dolore cupidatat.\r\n",
|
||||
"Duis cillum qui nisi duis amet velit ad cillum ut elit aute sint ad. Amet laboris pariatur excepteur ipsum Lorem aliqua veniam Lorem quis mollit cupidatat aliqua exercitation. Pariatur ex ullamco sit commodo cillum eiusmod ut proident elit cillum. Commodo ut ipsum excepteur occaecat sint elit consequat ex dolor adipisicing consectetur id ut ad. Velit sit eiusmod est esse tempor incididunt consectetur eiusmod duis commodo veniam.\r\n",
|
||||
"Ut sunt qui officia anim laboris exercitation Lorem quis laborum do eiusmod officia. Enim consectetur occaecat fugiat cillum cillum. Dolore dolore nostrud in commodo fugiat mollit consequat occaecat non et et elit ullamco. Sit voluptate minim ut est culpa velit nulla fugiat reprehenderit eu aliquip adipisicing labore. Sit minim minim do dolor dolor. Lorem Lorem labore exercitation magna veniam eiusmod do.\r\n",
|
||||
"Fugiat dolor adipisicing quis aliquip aute dolore. Qui proident anim elit veniam ex aliquip eiusmod ipsum sunt pariatur est. Non fugiat duis do est officia adipisicing.\r\n",
|
||||
"Nulla deserunt do laboris cupidatat veniam do consectetur ipsum elit veniam in mollit eu. Ea in consequat cupidatat laboris sint fugiat irure. In commodo esse reprehenderit deserunt minim velit ullamco enim eu cupidatat tempor ex. Ullamco in non id culpa amet occaecat culpa nostrud id. Non occaecat culpa magna incididunt.\r\n",
|
||||
"Enim laboris ex mollit reprehenderit eiusmod exercitation magna. Exercitation Lorem ex mollit non non culpa labore enim. Adipisicing labore dolore incididunt do amet aliquip excepteur ad et nostrud officia aute veniam voluptate. Fugiat enim eiusmod Lorem esse. Minim ullamco commodo consequat ex commodo aliqua eu nulla eu. Veniam non enim nulla ut Lorem nostrud minim sint duis.\r\n",
|
||||
"Enim duis consectetur in ullamco cillum veniam nulla amet. Exercitation nisi sunt sunt duis in culpa nisi magna ex id ipsum laboris reprehenderit qui. Officia pariatur qui ex fugiat veniam et sunt sit nostrud. Veniam ullamco tempor fugiat minim Lorem proident velit in eiusmod elit. Enim minim excepteur aute aliquip ex magna commodo dolore qui et labore. Proident eu aliquip cillum dolor. Nostrud ipsum ut irure consequat fugiat nulla proident occaecat laborum.\r\n",
|
||||
"Amet duis eiusmod sunt adipisicing esse ex nostrud consectetur voluptate cillum. Ipsum occaecat sit et anim velit irure ea incididunt cupidatat ullamco in nisi quis. Esse officia ipsum commodo qui quis qui do. Commodo aliquip amet aute sit sit ut cupidatat elit nostrud.\r\n",
|
||||
"Laboris laboris sit mollit cillum nulla deserunt commodo culpa est commodo anim id anim sit. Officia id consectetur velit incididunt est dolor sunt ipsum magna aliqua consectetur. Eiusmod pariatur minim deserunt cupidatat veniam Lorem aliquip sunt proident eu Lorem sit dolor fugiat. Proident qui ut ex in incididunt nulla nulla dolor ex laboris ea ad.\r\n",
|
||||
"Ex incididunt enim labore nulla cupidatat elit. Quis ut incididunt incididunt non irure commodo do mollit cillum anim excepteur. Qui consequat laborum dolore elit tempor aute ut nulla pariatur eu ullamco veniam. Nisi non velit labore in commodo excepteur culpa nulla tempor cillum. Ipsum qui sit sint reprehenderit ut labore incididunt dolor aliquip sunt. Reprehenderit occaecat tempor nisi laborum.\r\n",
|
||||
"Lorem officia ullamco eu occaecat in magna eiusmod consectetur nisi aliqua mollit esse. Ullamco ex aute nostrud pariatur do enim cillum sint do fugiat nostrud culpa tempor. Do aliquip excepteur nostrud culpa eu pariatur eiusmod cillum excepteur do. Est sunt non quis cillum voluptate ex.\r\n",
|
||||
"Deserunt consectetur tempor irure mollit qui tempor et. Labore enim eu irure laboris in. Nisi in tempor ex occaecat amet cupidatat laboris occaecat amet minim ut magna incididunt id. Consequat cillum laborum commodo mollit. Et magna culpa sunt dolore consequat laboris et sit. Deserunt qui voluptate excepteur dolor. Eu qui amet est proident.\r\n",
|
||||
"Eu elit minim eiusmod occaecat eu nostrud dolor qui ut elit. Sunt dolore proident ea eu do eiusmod fugiat incididunt pariatur duis amet Lorem nisi ut. Adipisicing quis veniam cupidatat Lorem sint culpa sunt veniam sint. Excepteur eu exercitation est magna pariatur veniam dolore qui fugiat labore proident eiusmod cillum. Commodo reprehenderit elit proident duis sint magna.\r\n",
|
||||
"Ut aliquip pariatur deserunt nostrud commodo ad proident est exercitation. Sit minim do ea enim sint officia nisi incididunt laborum. Ex amet duis commodo fugiat. Ut aute tempor deserunt irure occaecat aliquip voluptate cillum aute elit qui nostrud.\r\n",
|
||||
"Irure et quis consectetur sit est do sunt aliquip eu. Cupidatat pariatur consequat dolore consectetur. Adipisicing magna velit mollit occaecat do id. Nisi pariatur cupidatat cillum incididunt excepteur consectetur excepteur do laborum deserunt irure pariatur cillum.\r\n",
|
||||
"Adipisicing esse incididunt cillum est irure consequat irure ad aute voluptate. Incididunt do occaecat nostrud do ipsum pariatur Lorem qui laboris et pariatur. Est exercitation dolor culpa ad velit ut et.\r\n",
|
||||
"Sit eiusmod id enim ad ex dolor pariatur do. Ullamco occaecat quis dolor minim non elit labore amet est. Commodo velit eu nulla eiusmod ullamco. Incididunt anim pariatur aute eiusmod veniam tempor enim officia elit id. Elit Lorem est commodo dolore nostrud. Labore et consectetur do exercitation veniam laboris incididunt aliqua proident dolore ea officia cupidatat. Velit laboris aliquip deserunt labore commodo.\r\n",
|
||||
"Proident nostrud labore eu nostrud. Excepteur ut in velit labore ea proident labore ea sint cillum. Incididunt ipsum consectetur officia irure sit pariatur veniam id velit officia mollit. Adipisicing magna voluptate velit excepteur enim consectetur incididunt voluptate tempor occaecat fugiat velit excepteur labore. Do do incididunt qui nisi voluptate enim. Laboris aute sit voluptate cillum pariatur minim excepteur ullamco mollit deserunt.\r\n",
|
||||
"Excepteur laborum adipisicing nisi elit fugiat tempor. Elit laboris qui enim labore duis. Proident tempor in consectetur proident excepteur do ex laboris sit.\r\n",
|
||||
"Dolore do ea incididunt do duis dolore eu labore nisi cupidatat voluptate amet incididunt minim. Nulla pariatur mollit cupidatat adipisicing nulla et. Dolor aliquip in ex magna excepteur. Nulla consequat minim consequat ullamco dolor laboris ullamco eu reprehenderit duis nostrud pariatur.\r\n",
|
||||
"Id nisi labore duis qui. Incididunt laboris tempor aute do sit. Occaecat excepteur est mollit ea in mollit ullamco est amet reprehenderit.\r\n",
|
||||
"Aute labore ipsum velit non voluptate eiusmod et reprehenderit cupidatat occaecat. Lorem tempor tempor consectetur exercitation qui nostrud sunt cillum quis ut non dolore. Reprehenderit consequat reprehenderit laborum qui pariatur anim et officia est cupidatat enim velit velit.\r\n",
|
||||
"Commodo ex et fugiat cupidatat non adipisicing commodo. Minim ad dolore fugiat mollit cupidatat aliqua sunt dolor sit. Labore esse labore velit aute enim. Nulla duis incididunt est aliquip consectetur elit qui incididunt minim minim labore amet sit cillum.\r\n"
|
||||
]
|
||||
1
bin/types/readme.txt
Normal file
1
bin/types/readme.txt
Normal file
@@ -0,0 +1 @@
|
||||
Test data obtained from https://github.com/xpol/lua-rapidjson/tree/master/performance
|
||||
@@ -764,18 +764,19 @@ WARN_LOGFILE =
|
||||
# spaces.
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = ./readme.zh-cn.md \
|
||||
./include/rapidjson/rapidjson.h \
|
||||
./include/ \
|
||||
./doc/features.zh-cn.md \
|
||||
./doc/tutorial.zh-cn.md \
|
||||
./doc/stream.zh-cn.md \
|
||||
./doc/encoding.zh-cn.md \
|
||||
./doc/dom.zh-cn.md \
|
||||
./doc/sax.zh-cn.md \
|
||||
./doc/performance.zh-cn.md \
|
||||
./doc/internals.md \
|
||||
./doc/faq.zh-cn.md
|
||||
INPUT = readme.zh-cn.md \
|
||||
include/rapidjson/rapidjson.h \
|
||||
include/ \
|
||||
doc/features.zh-cn.md \
|
||||
doc/tutorial.zh-cn.md \
|
||||
doc/pointer.zh-cn.md \
|
||||
doc/stream.zh-cn.md \
|
||||
doc/encoding.zh-cn.md \
|
||||
doc/dom.zh-cn.md \
|
||||
doc/sax.zh-cn.md \
|
||||
doc/performance.zh-cn.md \
|
||||
doc/internals.md \
|
||||
doc/faq.zh-cn.md
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
|
||||
@@ -115,6 +115,7 @@ Parse flags | Meaning
|
||||
`kParseIterativeFlag` | Iterative(constant complexity in terms of function call stack size) parsing.
|
||||
`kParseStopWhenDoneFlag` | After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate `kParseErrorDocumentRootNotSingular` error. Using this flag for parsing multiple JSONs in the same stream.
|
||||
`kParseFullPrecisionFlag` | Parse number in full precision (slower). If this flag is not set, the normal precision (faster) is used. Normal precision has maximum 3 [ULP](http://en.wikipedia.org/wiki/Unit_in_the_last_place) error.
|
||||
`kParseCommentsFlag` | Allow one-line `// ...` and multi-line `/* ... */` comments (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.
|
||||
|
||||
|
||||
@@ -115,6 +115,7 @@ GenericDocument& GenericDocument::Parse(const Ch* str);
|
||||
`kParseIterativeFlag` | 迭代式(调用堆栈大小为常数复杂度)解析。
|
||||
`kParseStopWhenDoneFlag` | 当从流解析了一个完整的JSON根节点之后,停止继续处理余下的流。当使用了此标志,解析器便不会产生`kParseErrorDocumentRootNotSingular`错误。可使用本标志去解析同一个流里的多个JSON。
|
||||
`kParseFullPrecisionFlag` | 使用完整的精确度去解析数字(较慢)。如不设置此标节,则会使用正常的精确度(较快)。正常精确度会有最多3个[ULP](http://en.wikipedia.org/wiki/Unit_in_the_last_place)的误差。
|
||||
`kParseCommentsFlag` | 容许单行 `// ...` 及多行 `/* ... */` 注释(放宽的JSON语法)。
|
||||
|
||||
由于使用了非类型模板参数,而不是函数参数,C++编译器能为个别组合生成代码,以改善性能及减少代码尺寸(当只用单种特化)。缺点是需要在编译期决定标志。
|
||||
|
||||
|
||||
34
doc/faq.md
34
doc/faq.md
@@ -106,59 +106,59 @@
|
||||
|
||||
Call one of the `SetXXX()` methods - they call destructor which deallocates DOM data:
|
||||
|
||||
```
|
||||
~~~~~~~~~~cpp
|
||||
Document d;
|
||||
...
|
||||
d.SetObject(); // clear and minimize
|
||||
```
|
||||
~~~~~~~~~~
|
||||
|
||||
Alternatively, use equivalent of the [C++ swap with temporary idiom](https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Clear-and-minimize):
|
||||
```
|
||||
~~~~~~~~~~cpp
|
||||
Value(kObjectType).Swap(d);
|
||||
```
|
||||
~~~~~~~~~~
|
||||
or equivalent, but sightly longer to type:
|
||||
```
|
||||
~~~~~~~~~~cpp
|
||||
d.Swap(Value(kObjectType).Move());
|
||||
```
|
||||
~~~~~~~~~~
|
||||
|
||||
9. How to insert a document node into another document?
|
||||
|
||||
Let's take the following two DOM trees represented as JSON documents:
|
||||
```
|
||||
~~~~~~~~~~cpp
|
||||
Document person;
|
||||
person.Parse("{\"person\":{\"name\":{\"first\":\"Adam\",\"last\":\"Thomas\"}}}");
|
||||
|
||||
Document address;
|
||||
address.Parse("{\"address\":{\"city\":\"Moscow\",\"street\":\"Quiet\"}}");
|
||||
```
|
||||
~~~~~~~~~~
|
||||
Let's assume we want to merge them in such way that the whole `address` document becomes a node of the `person`:
|
||||
```
|
||||
~~~~~~~~~~js
|
||||
{ "person": {
|
||||
"name": { "first": "Adam", "last": "Thomas" },
|
||||
"address": { "city": "Moscow", "street": "Quiet" }
|
||||
}
|
||||
}
|
||||
```
|
||||
~~~~~~~~~~
|
||||
|
||||
The most important requirement to take care of document and value life-cycle as well as consistent memory managent using the right allocator during the value transfer.
|
||||
|
||||
Simple yet most efficient way to achieve that is to modify the `address` definition above to initialize it with allocator of the `person` document, then we just add the root nenber of the value:
|
||||
```
|
||||
Simple yet most efficient way to achieve that is to modify the `address` definition above to initialize it with allocator of the `person` document, then we just add the root member of the value:
|
||||
~~~~~~~~~~cpp
|
||||
Documnet address(person.GetAllocator());
|
||||
...
|
||||
person["person"].AddMember("address", address["address"], person.GetAllocator());
|
||||
```
|
||||
~~~~~~~~~~
|
||||
Alternatively, if we don't want to explicitly refer to the root value of `address` by name, we can refer to it via iterator:
|
||||
```
|
||||
~~~~~~~~~~cpp
|
||||
auto addressRoot = address.MemberBegin();
|
||||
person["person"].AddMember(addressRoot->name, addressRoot->value, person.GetAllocator());
|
||||
```
|
||||
~~~~~~~~~~
|
||||
|
||||
Second way is to deep-clone the value from the address document:
|
||||
```
|
||||
~~~~~~~~~~cpp
|
||||
Value addressValue = Value(address["address"], person.GetAllocator());
|
||||
person["person"].AddMember("address", addressValue, person.GetAllocator());
|
||||
```
|
||||
~~~~~~~~~~
|
||||
|
||||
## Document/Value (DOM)
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
6. 怎样安装RapidJSON?
|
||||
|
||||
见[安装一节](readme.zh-cn.md)。
|
||||
见[安装一节](../readme.zh-cn.md#安装)。
|
||||
|
||||
7. RapidJSON能否运行于我的平台?
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
12. 有没有其他替代品?
|
||||
|
||||
有许多替代品。例如nativejson-benchmark](https://github.com/miloyip/nativejson-benchmark)列出了一些开源的C/C++ JSON库。[json.org](http://www.json.org/)也有一个列表。
|
||||
有许多替代品。例如[nativejson-benchmark](https://github.com/miloyip/nativejson-benchmark)列出了一些开源的C/C++ JSON库。[json.org](http://www.json.org/)也有一个列表。
|
||||
|
||||
## JSON
|
||||
|
||||
@@ -98,10 +98,69 @@
|
||||
|
||||
错误信息存储在`ParseResult`,它包含错误代号及偏移值(从JSON开始至错误处的字符数目)。可以把错误代号翻译为人类可读的错误讯息。
|
||||
|
||||
7. 为可不只使用`double`去表示JSON number?
|
||||
7. 为何不只使用`double`去表示JSON number?
|
||||
|
||||
一些应用需要使用64位无号/有号整数。这些整数不能无损地转换成`double`。因此解析器会检测一个JSON number是否能转换至各种整数类型及`double`。
|
||||
|
||||
8. 如何清空并最小化`document`或`value`的容量?
|
||||
|
||||
调用 `SetXXX()` 方法 - 这些方法会调用析构函数,并重建空的Object或Array:
|
||||
|
||||
~~~~~~~~~~cpp
|
||||
Document d;
|
||||
...
|
||||
d.SetObject(); // clear and minimize
|
||||
~~~~~~~~~~
|
||||
|
||||
另外,也可以参考在 [C++ swap with temporary idiom](https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Clear-and-minimize)中的一种等价的方法:
|
||||
~~~~~~~~~~cpp
|
||||
Value(kObjectType).Swap(d);
|
||||
~~~~~~~~~~
|
||||
或者,使用这个稍微长一点的代码也能完成同样的事情:
|
||||
~~~~~~~~~~cpp
|
||||
d.Swap(Value(kObjectType).Move());
|
||||
~~~~~~~~~~
|
||||
|
||||
9. 如何将一个`document`节点插入到另一个`document`中?
|
||||
|
||||
比如有以下两个document(DOM):
|
||||
~~~~~~~~~~cpp
|
||||
Document person;
|
||||
person.Parse("{\"person\":{\"name\":{\"first\":\"Adam\",\"last\":\"Thomas\"}}}");
|
||||
|
||||
Document address;
|
||||
address.Parse("{\"address\":{\"city\":\"Moscow\",\"street\":\"Quiet\"}}");
|
||||
~~~~~~~~~~
|
||||
假设我们希望将整个 `address` 插入到`person`中,作为其的一个子节点:
|
||||
~~~~~~~~~~js
|
||||
{ "person": {
|
||||
"name": { "first": "Adam", "last": "Thomas" },
|
||||
"address": { "city": "Moscow", "street": "Quiet" }
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
||||
|
||||
在插入节点的过程中需要注意`document`和`value`的生命周期并且正确地使用allocator进行内存分配和管理。
|
||||
|
||||
一个简单有效的方法就是修改上述`address`变量的定义,让其使用`person`的allocator初始化,然后将其添加到根节点。
|
||||
|
||||
~~~~~~~~~~cpp
|
||||
Documnet address(person.GetAllocator());
|
||||
...
|
||||
person["person"].AddMember("address", address["address"], person.GetAllocator());
|
||||
~~~~~~~~~~
|
||||
当然,如果你不想通过显式地写出`address`的key来得到其值,可以使用迭代器来实现:
|
||||
~~~~~~~~~~cpp
|
||||
auto addressRoot = address.MemberBegin();
|
||||
person["person"].AddMember(addressRoot->name, addressRoot->value, person.GetAllocator());
|
||||
~~~~~~~~~~
|
||||
|
||||
此外,还可以通过深拷贝address document来实现:
|
||||
~~~~~~~~~~cpp
|
||||
Value addressValue = Value(address["address"], person.GetAllocator());
|
||||
person["person"].AddMember("address", addressValue, person.GetAllocator());
|
||||
~~~~~~~~~~
|
||||
|
||||
## Document/Value (DOM)
|
||||
|
||||
1. 什么是转移语意?为什么?
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
* Support Unicode surrogate.
|
||||
* Support null character (`"\u0000"`)
|
||||
* For example, `["Hello\u0000World"]` can be parsed and handled gracefully. There is API for getting/setting lengths of string.
|
||||
* Support optional relaxed syntax.
|
||||
* Single line (`// ...`) and multiple line (`/* ... */`) comments.
|
||||
|
||||
## Unicode
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
* 支持Unicod代理对(surrogate pair)。
|
||||
* 支持空字符(`"\u0000"`)。
|
||||
* 例如,可以优雅地解析及处理`["Hello\u0000World"]`。含读写字符串长度的API。
|
||||
* 支持放宽的可选语法
|
||||
* 单行(`// ...`)及多行(`/* ... */`) 注释。
|
||||
|
||||
## Unicode
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ When using `p.Get(root)` or `GetValueByPointer(root, p)`, `root` is a (const) `V
|
||||
|
||||
The other functions have two groups of signature. One group uses `Document& document` as parameter, another one uses `Value& root`. The first group uses `document.GetAllocator()` for creating values. And the second group needs user to supply an allocator, like the functions in DOM.
|
||||
|
||||
All examples above do not require an allocator parameter, because the parameter is a `Document&`. But if you want to resolve a pointer to a subtree. You need to supply it as in the following example:
|
||||
All examples above do not require an allocator parameter, because the first parameter is a `Document&`. But if you want to resolve a pointer to a subtree, you need to supply the allocator as in the following example:
|
||||
|
||||
~~~cpp
|
||||
class Person {
|
||||
@@ -179,7 +179,7 @@ private:
|
||||
|
||||
# Error Handling {#ErrorHandling}
|
||||
|
||||
A `Pointer` parses a source string in its constructor. If there is parsing error, `Pointer::IsValid()` returns false. And you can use `Pointer::GetParseErrorCode()` and `GetParseErrorOffset()` to retrieve the error information.
|
||||
A `Pointer` parses a source string in its constructor. If there is parsing error, `Pointer::IsValid()` returns `false`. And you can use `Pointer::GetParseErrorCode()` and `GetParseErrorOffset()` to retrieve the error information.
|
||||
|
||||
Note that, all resolving functions assumes valid pointer. Resolving with an invalid pointer causes assertion failure.
|
||||
|
||||
@@ -215,7 +215,7 @@ It can also stringify to URI fragment reprsentation by `StringifyUriFragment()`.
|
||||
|
||||
# User-Supplied Tokens {#UserSuppliedTokens}
|
||||
|
||||
If a pointer will be resolved multiple times, it should be construct once, and then apply it to different DOMs or in different times. This reduce time and memory allocation for constructing `Pointer` multiple times.
|
||||
If a pointer will be resolved multiple times, it should be constructed once, and then apply it to different DOMs or in different times. This reduce time and memory allocation for constructing `Pointer` multiple times.
|
||||
|
||||
We can go one step further, to completely eliminate the parsing process and dynamic memory allocation, we can establish the token array directly:
|
||||
|
||||
|
||||
234
doc/pointer.zh-cn.md
Normal file
234
doc/pointer.zh-cn.md
Normal file
@@ -0,0 +1,234 @@
|
||||
# Pointer
|
||||
|
||||
## 状态: 实验性,应该会合进 v1.1
|
||||
|
||||
JSON Pointer 是一个标准化([RFC6901])的方式去选取一个 JSON Document(DOM)中的值。这类似于 XML 的 XPath。然而,JSON Pointer 简单得多,而且每个 JSON Pointer 仅指向单个值。
|
||||
|
||||
使用 RapidJSON 的 JSON Pointer 实现能简化一些 DOM 的操作。
|
||||
|
||||
[TOC]
|
||||
|
||||
# JSON Pointer {#JsonPointer}
|
||||
|
||||
一个 JSON Pointer 由一串(零至多个)token 所组成,每个 token 都有 `/` 前缀。每个 token 可以是一个字符串或数字。例如,给定一个 JSON:
|
||||
~~~javascript
|
||||
{
|
||||
"foo" : ["bar", "baz"],
|
||||
"pi" : 3.1416
|
||||
}
|
||||
~~~
|
||||
|
||||
以下的 JSON Pointer 解析为:
|
||||
|
||||
1. `"/foo"` → `[ "bar", "baz" ]`
|
||||
2. `"/foo/0"` → `"bar"`
|
||||
3. `"/foo/1"` → `"baz"`
|
||||
4. `"/pi"` → `3.1416`
|
||||
|
||||
要注意,一个空 JSON Pointer `""` (零个token)解析为整个 JSON。
|
||||
|
||||
# 基本使用方法 {#BasicUsage}
|
||||
|
||||
以下的代码范例不解自明。
|
||||
|
||||
~~~cpp
|
||||
#include "rapidjson/pointer.h"
|
||||
|
||||
// ...
|
||||
Document d;
|
||||
|
||||
// 使用 Set() 创建 DOM
|
||||
Pointer("/project").Set(d, "RapidJSON");
|
||||
Pointer("/stars").Set(d, 10);
|
||||
|
||||
// { "project" : "RapidJSON", "stars" : 10 }
|
||||
|
||||
// 使用 Get() 访问 DOM。若该值不存在则返回 nullptr。
|
||||
if (Value* stars = Pointer("/stars").Get(d))
|
||||
stars->SetInt(stars->GetInt() + 1);
|
||||
|
||||
// { "project" : "RapidJSON", "stars" : 11 }
|
||||
|
||||
// Set() 和 Create() 自动生成父值(如果它们不存在)。
|
||||
Pointer("/a/b/0").Create(d);
|
||||
|
||||
// { "project" : "RapidJSON", "stars" : 11, "a" : { "b" : [ null ] } }
|
||||
|
||||
// GetWithDefault() 返回引用。若该值不存在则会深拷贝缺省值。
|
||||
Value& hello = Pointer("/hello").GetWithDefault(d, "world");
|
||||
|
||||
// { "project" : "RapidJSON", "stars" : 11, "a" : { "b" : [ null ] }, "hello" : "world" }
|
||||
|
||||
// Swap() 和 Set() 相似
|
||||
Value x("C++");
|
||||
Pointer("/hello").Swap(d, x);
|
||||
|
||||
// { "project" : "RapidJSON", "stars" : 11, "a" : { "b" : [ null ] }, "hello" : "C++" }
|
||||
// x 变成 "world"
|
||||
|
||||
// 删去一个成员或元素,若值存在返回 true
|
||||
bool success = Pointer("/a").Erase(d);
|
||||
assert(success);
|
||||
|
||||
// { "project" : "RapidJSON", "stars" : 10 }
|
||||
~~~
|
||||
|
||||
# 辅助函数 {#HelperFunctions}
|
||||
|
||||
由于面向对象的调用习惯可能不符直觉,RapidJSON 也提供了一些辅助函数,它们把成员函数包装成自由函数。
|
||||
|
||||
以下的例子与上面例子所做的事情完全相同。
|
||||
|
||||
~~~cpp
|
||||
Document d;
|
||||
|
||||
SetValueByPointer(d, "/project", "RapidJSON");
|
||||
SetValueByPointer(d, "/stars", 10);
|
||||
|
||||
if (Value* stars = GetValueByPointer(d, "/stars"))
|
||||
stars->SetInt(stars->GetInt() + 1);
|
||||
|
||||
CreateValueByPointer(d, "/a/b/0");
|
||||
|
||||
Value& hello = GetValueByPointerWithDefault(d, "/hello", "world");
|
||||
|
||||
Value x("C++");
|
||||
SwapValueByPointer(d, "/hello", x);
|
||||
|
||||
bool success = EraseValueByPointer(d, "/a");
|
||||
assert(success);
|
||||
~~~
|
||||
|
||||
以下对比 3 种调用方式:
|
||||
|
||||
1. `Pointer(source).<Method>(root, ...)`
|
||||
2. `<Method>ValueByPointer(root, Pointer(source), ...)`
|
||||
3. `<Method>ValueByPointer(root, source, ...)`
|
||||
|
||||
# 解析 Pointer {#ResolvingPointer}
|
||||
|
||||
`Pointer::Get()` 或 `GetValueByPointer()` 函数并不修改 DOM。若那些 token 不能匹配 DOM 里的值,这些函数便返回 `nullptr`。使用者可利用这个方法来检查一个值是否存在。
|
||||
|
||||
注意,数值 token 可表示数组索引或成员名字。解析过程中会按值的类型来匹配。
|
||||
|
||||
~~~javascript
|
||||
{
|
||||
"0" : 123,
|
||||
"1" : [456]
|
||||
}
|
||||
~~~
|
||||
|
||||
1. `"/0"` → `123`
|
||||
2. `"/1/0"` → `456`
|
||||
|
||||
Token `"0"` 在第一个 pointer 中被当作成员名字。它在第二个 pointer 中被当作成数组索引。
|
||||
|
||||
其他函数会改变 DOM,包括`Create()`、`GetWithDefault()`、`Set()`、`Swap()`。这些函数总是成功的。若一些父值不存在,就会创建它们。若父值类型不匹配 token,也会强行改变其类型。改变类型也意味着完全移除其 DOM 子树的内容。
|
||||
|
||||
例如,把上面的 JSON 解译至 `d` 之后,
|
||||
|
||||
~~~cpp
|
||||
SetValueByPointer(d, "1/a", 789); // { "0" : 123, "1" : { "a" : 789 } }
|
||||
~~~
|
||||
|
||||
## 解析负号 token
|
||||
|
||||
另外,[RFC6901] 定义了一个特殊 token `-` (单个负号),用于表示数组最后元素的下一个元素。 `Get()` 只会把此 token 当作成员名字 '"-"'。而其他函数则会以此解析数组,等同于对数组调用 `Value::PushBack()` 。
|
||||
|
||||
~~~cpp
|
||||
Document d;
|
||||
d.Parse("{\"foo\":[123]}");
|
||||
SetValueByPointer(d, "/foo/-", 456); // { "foo" : [123, 456] }
|
||||
SetValueByPointer(d, "/-", 789); // { "foo" : [123, 456], "-" : 789 }
|
||||
~~~
|
||||
|
||||
## 解析 Document 及 Value
|
||||
|
||||
当使用 `p.Get(root)` 或 `GetValueByPointer(root, p)`,`root` 是一个(常数) `Value&`。这意味着,它也可以是 DOM 里的一个子树。
|
||||
|
||||
其他函数有两组签名。一组使用 `Document& document` 作为参数,另一组使用 `Value& root`。第一组使用 `document.GetAllocator()` 去创建值,而第二组则需要使用者提供一个 allocator,如同 DOM 里的函数。
|
||||
|
||||
以上例子都不需要 allocator 参数,因为它的第一个参数是 `Document&`。但如果你需要对一个子树进行解析,就需要如下面的例子般提供 allocator:
|
||||
|
||||
~~~cpp
|
||||
class Person {
|
||||
public:
|
||||
Person() {
|
||||
document_ = new Document();
|
||||
// CreateValueByPointer() here no need allocator
|
||||
SetLocation(CreateValueByPointer(*document_, "/residence"), ...);
|
||||
SetLocation(CreateValueByPointer(*document_, "/office"), ...);
|
||||
};
|
||||
|
||||
private:
|
||||
void SetLocation(Value& location, const char* country, const char* addresses[2]) {
|
||||
Value::Allocator& a = document_->GetAllocator();
|
||||
// SetValueByPointer() here need allocator
|
||||
SetValueByPointer(location, "/country", country, a);
|
||||
SetValueByPointer(location, "/address/0", address[0], a);
|
||||
SetValueByPointer(location, "/address/1", address[1], a);
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
Document* document_;
|
||||
};
|
||||
~~~
|
||||
|
||||
`Erase()` 或 `EraseValueByPointer()` 不需要 allocator。而且它们成功删除值之后会返回 `true`。
|
||||
|
||||
# 错误处理 {#ErrorHandling}
|
||||
|
||||
`Pointer` 在其建构函数里会解译源字符串。若有解析错误,`Pointer::IsValid()` 返回 `false`。你可使用 `Pointer::GetParseErrorCode()` 和 `GetParseErrorOffset()` 去获取错信息。
|
||||
|
||||
要注意的是,所有解析函数都假设 pointer 是合法的。对一个非法 pointer 解析会做成断言失败。
|
||||
|
||||
# URI 片段表示方式 {#URIFragment}
|
||||
|
||||
除了我们一直在使用的字符串方式表示 JSON pointer,[RFC6901]也定义了一个 JSON Pointer 的 URI 片段(fragment)表示方式。URI 片段是定义于 [RFC3986] "Uniform Resource Identifier (URI): Generic Syntax"。
|
||||
|
||||
URI 片段的主要分别是必然以 `#` (pound sign)开头,而一些字符也会以百分比编码成 UTF-8 序列。例如,以下的表展示了不同表示法下的 C/C++ 字符串常数。
|
||||
|
||||
字符串表示方式 | URI 片段表示方式 | Pointer Tokens (UTF-8)
|
||||
----------------------|-----------------------------|------------------------
|
||||
`"/foo/0"` | `"#/foo/0"` | `{"foo", 0}`
|
||||
`"/a~1b"` | `"#/a~1b"` | `{"a/b"}`
|
||||
`"/m~0n"` | `"#/m~0n"` | `{"m~n"}`
|
||||
`"/ "` | `"#/%20"` | `{" "}`
|
||||
`"/\0"` | `"#/%00"` | `{"\0"}`
|
||||
`"/€"` | `"#/%E2%82%AC"` | `{"€"}`
|
||||
|
||||
RapidJSON 完全支持 URI 片段表示方式。它在解译时会自动检测 `#` 号。
|
||||
|
||||
# 字符串化
|
||||
|
||||
你也可以把一个 `Pointer` 字符串化,储存于字符串或其他输出流。例如:
|
||||
|
||||
~~~
|
||||
Pointer p(...);
|
||||
StringBuffer sb;
|
||||
p.Stringify(sb);
|
||||
std::cout << sb.GetString() << std::endl;
|
||||
~~~
|
||||
|
||||
使用 `StringifyUriFragment()` 可以把 pointer 字符串化为 URI 片段表示法。
|
||||
|
||||
# 使用者提供的 tokens {#UserSuppliedTokens}
|
||||
|
||||
若一个 pointer 会用于多次解析,它应该只被创建一次,然后再施于不同的 DOM ,或在不同时间做解析。这样可以避免多次创键 `Pointer`,节省时间和内存分配。
|
||||
|
||||
我们甚至可以再更进一步,完全消去解析过程及动态内存分配。我们可以直接生成 token 数组:
|
||||
|
||||
~~~cpp
|
||||
#define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex }
|
||||
#define INDEX(i) { #i, sizeof(#i) - 1, i }
|
||||
|
||||
static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) };
|
||||
static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
|
||||
// Equivalent to static const Pointer p("/foo/123");
|
||||
~~~
|
||||
|
||||
这种做法可能适合内存受限的系统。
|
||||
|
||||
[RFC3986]: https://tools.ietf.org/html/rfc3986
|
||||
[RFC6901]: https://tools.ietf.org/html/rfc6901
|
||||
@@ -175,7 +175,7 @@ bool Parse(InputStream& is, Handler& handler);
|
||||
|
||||
# Writer {#Writer}
|
||||
|
||||
`Reader`把JSON转换(解析)成为事件。`Writer`完全做相反的事情。它把事件转换成JSON。
|
||||
`Reader`把JSON转换(解析)成为事件。`Writer`做完全相反的事情。它把事件转换成JSON。
|
||||
|
||||
`Writer`是非常容易使用的。若你的应用程序只需把一些数据转换成JSON,可能直接使用`Writer`,会比建立一个`Document`然后用`Writer`把它转换成JSON更加方便。
|
||||
|
||||
@@ -265,7 +265,7 @@ public:
|
||||
|
||||
## PrettyWriter {#PrettyWriter}
|
||||
|
||||
`Writer`所输出的是没有空格字符的最紧凑JSON,适合网络传输或储存,但就适合人类阅读。
|
||||
`Writer`所输出的是没有空格字符的最紧凑JSON,适合网络传输或储存,但不适合人类阅读。
|
||||
|
||||
因此,RapidJSON提供了一个`PrettyWriter`,它在输出中加入缩进及换行。
|
||||
|
||||
@@ -386,13 +386,13 @@ Error: Terminate parsing due to Handler error.
|
||||
at offset 59 near '} }...'
|
||||
~~~~~~~~~~
|
||||
|
||||
第一个JSON(`json1`)被成功地解析至`MessageMap`。由于`MessageMap`是一个`std::map`,列印次序按键值排序。此次序与JSON中的次序不同。
|
||||
第一个JSON(`json1`)被成功地解析至`MessageMap`。由于`MessageMap`是一个`std::map`,打印次序按键值排序。此次序与JSON中的次序不同。
|
||||
|
||||
在第二个JSON(`json2`)中,`foo`的值是一个空object。由于它是一个object,`MessageHandler::StartObject()`会被调用。然而,在`state_ = kExpectValue`的情况下,该函数会返回`false`,并令到解析过程终止。错误代码是`kParseErrorTermination`。
|
||||
在第二个JSON(`json2`)中,`foo`的值是一个空object。由于它是一个object,`MessageHandler::StartObject()`会被调用。然而,在`state_ = kExpectValue`的情况下,该函数会返回`false`,并导致解析过程终止。错误代码是`kParseErrorTermination`。
|
||||
|
||||
## 过滤JSON {#Filtering}
|
||||
|
||||
如前面提及过,`Writer`可处理`Reader`发出的事件。`condense`例子简单地设置`Writer`作为一个`Reader`的处理器,因此它能移除JSON中的所有空白字符。`pretty`例子使用同样的关系,只是以`PrettyWriter`取代`Writer`。因此`pretty`能够重新格式化JSON,加入缩进及换行。
|
||||
如前面提及过,`Writer`可处理`Reader`发出的事件。`example/condense/condense.cpp`例子简单地设置`Writer`作为一个`Reader`的处理器,因此它能移除JSON中的所有空白字符。`example/pretty/pretty.cpp`例子使用同样的关系,只是以`PrettyWriter`取代`Writer`。因此`pretty`能够重新格式化JSON,加入缩进及换行。
|
||||
|
||||
实际上,我们可以使用SAX风格API去加入(多个)中间层去过滤JSON的内容。例如`capitalize`例子可以把所有JSON string改为大写。
|
||||
|
||||
@@ -472,5 +472,5 @@ int main(int, char*[]) {
|
||||
["HELLO\nWORLD"]
|
||||
~~~~~~~~~~
|
||||
|
||||
我们还可以开发更复杂的过滤器。然而,由于SAX风格API在某一时间点只能提供单一事件的信息,使用者需要自行记录一些上下文信息(例如从根节点起的路径、储存其他相关值)。对些一些处理情况,用DOM会比SAX更容易实现。
|
||||
我们还可以开发更复杂的过滤器。然而,由于SAX风格API在某一时间点只能提供单一事件的信息,使用者需要自行记录一些上下文信息(例如从根节点起的路径、储存其他相关值)。对于处理某些情况,用DOM会比SAX更容易实现。
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
本教程简介文件对象模型(Document Object Model, DOM)API。
|
||||
|
||||
如[用法一览](readme.zh-cn.md)中所示,可以解析一个JSON至DOM,然后就可以轻松查询及修改DOM,并最终转换回JSON。
|
||||
如[用法一览](../readme.zh-cn.md#用法一览)中所示,可以解析一个JSON至DOM,然后就可以轻松查询及修改DOM,并最终转换回JSON。
|
||||
|
||||
[TOC]
|
||||
|
||||
@@ -123,7 +123,7 @@ a[3] = 4
|
||||
|
||||
你可以用整数字面量访问元素,如`a[0]`、`a[1]`、`a[2]`。
|
||||
|
||||
Array与`std::vector`相似,除了使用索引,也可使用迭待器来访问所有元素。
|
||||
Array与`std::vector`相似,除了使用索引,也可使用迭代器来访问所有元素。
|
||||
~~~~~~~~~~cpp
|
||||
for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
|
||||
printf("%d ", itr->GetInt());
|
||||
@@ -461,7 +461,7 @@ contact.AddMember(key, val, document.GetAllocator());
|
||||
|
||||
* `bool RemoveMember(const Ch* name)`:使用键名来移除成员(线性时间复杂度)。
|
||||
* `bool RemoveMember(const Value& name)`:除了`name`是一个Value,和上一行相同。
|
||||
* `MemberIterator RemoveMember(MemberIterator)`:使用迭待器移除成员(_常数_时间复杂度)。
|
||||
* `MemberIterator RemoveMember(MemberIterator)`:使用迭代器移除成员(_常数_时间复杂度)。
|
||||
* `MemberIterator EraseMember(MemberIterator)`:和上行相似但维持成员次序(线性时间复杂度)。
|
||||
* `MemberIterator EraseMember(MemberIterator first, MemberIterator last)`:移除一个范围内的成员,维持次序(线性时间复杂度)。
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ include_directories("../include/")
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default")
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough -Weverything")
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
|
||||
endif()
|
||||
|
||||
@@ -27,7 +27,7 @@ struct CapitalizeFilter {
|
||||
bool String(const char* str, SizeType length, bool) {
|
||||
buffer_.clear();
|
||||
for (SizeType i = 0; i < length; i++)
|
||||
buffer_.push_back(std::toupper(str[i]));
|
||||
buffer_.push_back(static_cast<char>(std::toupper(str[i])));
|
||||
return out_.String(&buffer_.front(), length, true); // true = output handler need to copy the string
|
||||
}
|
||||
bool StartObject() { return out_.StartObject(); }
|
||||
@@ -58,7 +58,7 @@ int main(int, char*[]) {
|
||||
// JSON reader parse from the input stream and let writer generate the output.
|
||||
CapitalizeFilter<Writer<FileWriteStream> > filter(writer);
|
||||
if (!reader.Parse(is, filter)) {
|
||||
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode()));
|
||||
fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ int main(int, char*[]) {
|
||||
|
||||
// JSON reader parse from the input stream and let writer generate the output.
|
||||
if (!reader.Parse(is, writer)) {
|
||||
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode()));
|
||||
fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@ RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||
#endif
|
||||
|
||||
struct MessageHandler
|
||||
: public BaseReaderHandler<UTF8<>, MessageHandler> {
|
||||
MessageHandler() : messages_(), state_(kExpectObjectStart), name_() {}
|
||||
@@ -63,7 +68,11 @@ struct MessageHandler
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
void ParseMessages(const char* json, MessageMap& messages) {
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
static void ParseMessages(const char* json, MessageMap& messages) {
|
||||
Reader reader;
|
||||
MessageHandler handler;
|
||||
StringStream ss(json);
|
||||
|
||||
@@ -22,7 +22,7 @@ int main(int, char*[]) {
|
||||
|
||||
// JSON reader parse from the input stream and let writer generate the output.
|
||||
if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) {
|
||||
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode()));
|
||||
fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ int main(int, char*[]) {
|
||||
// JSON reader parse from the input stream and let writer generate the output.
|
||||
//if (!reader.Parse<kParseValidateEncodingFlag>(is, writer)) {
|
||||
if (!reader.Parse<kParseValidateEncodingFlag>(eis, writer)) { // CHANGED
|
||||
fprintf(stderr, "\nError(%u): %s\n", (unsigned)reader.GetErrorOffset(), GetParseError_En(reader.GetParseErrorCode()));
|
||||
fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,17 +11,24 @@ using namespace rapidjson;
|
||||
class Person {
|
||||
public:
|
||||
Person(const std::string& name, unsigned age) : name_(name), age_(age) {}
|
||||
Person(const Person& rhs) : name_(rhs.name_), age_(rhs.age_) {}
|
||||
virtual ~Person();
|
||||
|
||||
Person& operator=(const Person& rhs) {
|
||||
name_ = rhs.name_;
|
||||
age_ = rhs.age_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename Writer>
|
||||
void Serialize(Writer& writer) const {
|
||||
// This base class just write out name-value pairs, without wrapping within an object.
|
||||
writer.String("name");
|
||||
#ifdef RAPIDJSON_HAS_STDSTRING
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
writer.String(name_);
|
||||
#else
|
||||
writer.String(name_.c_str(), (SizeType)name_.length()); // Supplying length of string is faster.
|
||||
writer.String(name_.c_str(), static_cast<SizeType>(name_.length())); // Supplying length of string is faster.
|
||||
#endif
|
||||
writer.String("age");
|
||||
writer.Uint(age_);
|
||||
@@ -38,16 +45,17 @@ Person::~Person() {
|
||||
class Education {
|
||||
public:
|
||||
Education(const std::string& school, double GPA) : school_(school), GPA_(GPA) {}
|
||||
Education(const Education& rhs) : school_(rhs.school_), GPA_(rhs.GPA_) {}
|
||||
|
||||
template <typename Writer>
|
||||
void Serialize(Writer& writer) const {
|
||||
writer.StartObject();
|
||||
|
||||
writer.String("school");
|
||||
#ifdef RAPIDJSON_HAS_STDSTRING
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
writer.String(school_);
|
||||
#else
|
||||
writer.String(school_.c_str(), (SizeType)school_.length());
|
||||
writer.String(school_.c_str(), static_cast<SizeType>(school_.length()));
|
||||
#endif
|
||||
|
||||
writer.String("GPA");
|
||||
@@ -102,8 +110,16 @@ Dependent::~Dependent() {
|
||||
class Employee : public Person {
|
||||
public:
|
||||
Employee(const std::string& name, unsigned age, bool married) : Person(name, age), dependents_(), married_(married) {}
|
||||
Employee(const Employee& rhs) : Person(rhs), dependents_(rhs.dependents_), married_(rhs.married_) {}
|
||||
virtual ~Employee();
|
||||
|
||||
Employee& operator=(const Employee& rhs) {
|
||||
static_cast<Person&>(*this) = rhs;
|
||||
dependents_ = rhs.dependents_;
|
||||
married_ = rhs.married_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void AddDependent(const Dependent& dependent) {
|
||||
dependents_.push_back(dependent);
|
||||
}
|
||||
|
||||
@@ -121,17 +121,17 @@ int main(int, char*[]) {
|
||||
// This version of SetString() needs an allocator, which means it will allocate a new buffer and copy the the string into the buffer.
|
||||
Value author;
|
||||
{
|
||||
char buffer[10];
|
||||
int len = sprintf(buffer, "%s %s", "Milo", "Yip"); // synthetic example of dynamically created string.
|
||||
char buffer2[10];
|
||||
int len = sprintf(buffer2, "%s %s", "Milo", "Yip"); // synthetic example of dynamically created string.
|
||||
|
||||
author.SetString(buffer, static_cast<size_t>(len), document.GetAllocator());
|
||||
author.SetString(buffer2, static_cast<SizeType>(len), document.GetAllocator());
|
||||
// Shorter but slower version:
|
||||
// document["hello"].SetString(buffer, document.GetAllocator());
|
||||
|
||||
// Constructor version:
|
||||
// Value author(buffer, len, document.GetAllocator());
|
||||
// Value author(buffer, document.GetAllocator());
|
||||
memset(buffer, 0, sizeof(buffer)); // For demonstration purpose.
|
||||
memset(buffer2, 0, sizeof(buffer2)); // For demonstration purpose.
|
||||
}
|
||||
// Variable 'buffer' is unusable now but 'author' has already made a copy.
|
||||
document.AddMember("author", author, document.GetAllocator());
|
||||
|
||||
@@ -199,7 +199,7 @@ public:
|
||||
return originalPtr;
|
||||
|
||||
// Simply expand it if it is the last allocation and there is sufficient space
|
||||
if (originalPtr == (char *)(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
|
||||
if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
|
||||
size_t increment = static_cast<size_t>(newSize - originalSize);
|
||||
increment = RAPIDJSON_ALIGN(increment);
|
||||
if (chunkHead_->size + increment <= chunkHead_->capacity) {
|
||||
|
||||
@@ -25,36 +25,20 @@
|
||||
#ifdef _MSC_VER
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
|
||||
#elif defined(__GNUC__)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(padded)
|
||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_HAS_STDSTRING
|
||||
|
||||
#ifndef RAPIDJSON_HAS_STDSTRING
|
||||
#ifdef RAPIDJSON_DOXYGEN_RUNNING
|
||||
#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation
|
||||
#else
|
||||
#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default
|
||||
#endif
|
||||
/*! \def RAPIDJSON_HAS_STDSTRING
|
||||
\ingroup RAPIDJSON_CONFIG
|
||||
\brief Enable RapidJSON support for \c std::string
|
||||
|
||||
By defining this preprocessor symbol to \c 1, several convenience functions for using
|
||||
\ref rapidjson::GenericValue with \c std::string are enabled, especially
|
||||
for construction and comparison.
|
||||
|
||||
\hideinitializer
|
||||
*/
|
||||
#endif // !defined(RAPIDJSON_HAS_STDSTRING)
|
||||
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
#include <string>
|
||||
#endif // RAPIDJSON_HAS_STDSTRING
|
||||
|
||||
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
|
||||
#include <iterator> // std::iterator, std::random_access_iterator_tag
|
||||
#endif
|
||||
@@ -158,6 +142,7 @@ public:
|
||||
Otherwise, the copy constructor is implicitly defined.
|
||||
*/
|
||||
GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
|
||||
Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
|
||||
|
||||
//! @name stepping
|
||||
//@{
|
||||
@@ -260,6 +245,7 @@ struct GenericStringRef {
|
||||
typedef CharType Ch; //!< character type of the string
|
||||
|
||||
//! Create string reference from \c const character array
|
||||
#ifndef __clang__ // -Wdocumentation
|
||||
/*!
|
||||
This constructor implicitly creates a constant string reference from
|
||||
a \c const character array. It has better performance than
|
||||
@@ -282,11 +268,13 @@ struct GenericStringRef {
|
||||
In such cases, the referenced string should be \b copied to the
|
||||
GenericValue instead.
|
||||
*/
|
||||
#endif
|
||||
template<SizeType N>
|
||||
GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
|
||||
: s(str), length(N-1) {}
|
||||
|
||||
//! Explicitly create string reference from \c const character pointer
|
||||
#ifndef __clang__ // -Wdocumentation
|
||||
/*!
|
||||
This constructor can be used to \b explicitly create a reference to
|
||||
a constant string pointer.
|
||||
@@ -305,16 +293,19 @@ struct GenericStringRef {
|
||||
In such cases, the referenced string should be \b copied to the
|
||||
GenericValue instead.
|
||||
*/
|
||||
#endif
|
||||
explicit GenericStringRef(const CharType* str)
|
||||
: s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != NULL); }
|
||||
|
||||
//! Create constant string reference from pointer and length
|
||||
#ifndef __clang__ // -Wdocumentation
|
||||
/*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
|
||||
\param len length of the string, excluding the trailing NULL terminator
|
||||
|
||||
\post \ref s == str && \ref length == len
|
||||
\note Constant complexity.
|
||||
*/
|
||||
#endif
|
||||
GenericStringRef(const CharType* str, SizeType len)
|
||||
: s(str), length(len) { RAPIDJSON_ASSERT(s != NULL); }
|
||||
|
||||
@@ -325,8 +316,6 @@ struct GenericStringRef {
|
||||
const SizeType length; //!< length of the string (excluding the trailing NULL terminator)
|
||||
|
||||
private:
|
||||
//! Disallow copy-assignment
|
||||
GenericStringRef operator=(const GenericStringRef&);
|
||||
//! Disallow construction from non-const array
|
||||
template<SizeType N>
|
||||
GenericStringRef(CharType (&str)[N]) /* = delete */;
|
||||
@@ -654,7 +643,7 @@ public:
|
||||
*/
|
||||
template <typename SourceAllocator>
|
||||
GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) {
|
||||
RAPIDJSON_ASSERT((void*)this != (void const*)&rhs);
|
||||
RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
|
||||
this->~GenericValue();
|
||||
new (this) GenericValue(rhs, allocator);
|
||||
return *this;
|
||||
@@ -736,7 +725,7 @@ public:
|
||||
else
|
||||
return data_.n.u64 == rhs.data_.n.u64;
|
||||
|
||||
default: // kTrueType, kFalseType, kNullType
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -864,8 +853,14 @@ public:
|
||||
return member->value;
|
||||
else {
|
||||
RAPIDJSON_ASSERT(false); // see above note
|
||||
static GenericValue NullValue;
|
||||
return NullValue;
|
||||
|
||||
// This will generate -Wexit-time-destructors in clang
|
||||
// static GenericValue NullValue;
|
||||
// return NullValue;
|
||||
|
||||
// Use static buffer and placement-new to prevent destruction
|
||||
static char buffer[sizeof(GenericValue)];
|
||||
return *new (buffer) GenericValue();
|
||||
}
|
||||
}
|
||||
template <typename SourceAllocator>
|
||||
@@ -1235,8 +1230,8 @@ public:
|
||||
MemberIterator pos = MemberBegin() + (first - MemberBegin());
|
||||
for (MemberIterator itr = pos; itr != last; ++itr)
|
||||
itr->~Member();
|
||||
std::memmove(&*pos, &*last, (MemberEnd() - last) * sizeof(Member));
|
||||
data_.o.size -= (last - first);
|
||||
std::memmove(&*pos, &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
|
||||
data_.o.size -= static_cast<SizeType>(last - first);
|
||||
return pos;
|
||||
}
|
||||
|
||||
@@ -1328,7 +1323,7 @@ public:
|
||||
GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
|
||||
RAPIDJSON_ASSERT(IsArray());
|
||||
if (newCapacity > data_.a.capacity) {
|
||||
data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue));
|
||||
data_.a.elements = static_cast<GenericValue*>(allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)));
|
||||
data_.a.capacity = newCapacity;
|
||||
}
|
||||
return *this;
|
||||
@@ -1435,8 +1430,8 @@ public:
|
||||
ValueIterator pos = Begin() + (first - Begin());
|
||||
for (ValueIterator itr = pos; itr != last; ++itr)
|
||||
itr->~GenericValue();
|
||||
std::memmove(pos, last, (End() - last) * sizeof(GenericValue));
|
||||
data_.a.size -= (last - first);
|
||||
std::memmove(pos, last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
|
||||
data_.a.size -= static_cast<SizeType>(last - first);
|
||||
return pos;
|
||||
}
|
||||
|
||||
@@ -1455,8 +1450,8 @@ public:
|
||||
if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
|
||||
if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double
|
||||
if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
|
||||
if ((flags_ & kInt64Flag) != 0) return (double)data_.n.i64; // int64_t -> double (may lose precision)
|
||||
RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return (double)data_.n.u64; // uint64_t -> double (may lose precision)
|
||||
if ((flags_ & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
|
||||
RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
|
||||
}
|
||||
|
||||
GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
|
||||
@@ -1629,8 +1624,8 @@ private:
|
||||
Ch str[MaxChars];
|
||||
|
||||
inline static bool Usable(SizeType len) { return (MaxSize >= len); }
|
||||
inline void SetLength(SizeType len) { str[LenPos] = (Ch)(MaxSize - len); }
|
||||
inline SizeType GetLength() const { return (SizeType)(MaxSize - str[LenPos]); }
|
||||
inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
|
||||
inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
|
||||
}; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
|
||||
|
||||
// By using proper binary layout, retrieval of different integer types do not need conversions.
|
||||
@@ -1683,7 +1678,7 @@ private:
|
||||
void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
|
||||
flags_ = kArrayFlag;
|
||||
if (count) {
|
||||
data_.a.elements = (GenericValue*)allocator.Malloc(count * sizeof(GenericValue));
|
||||
data_.a.elements = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
|
||||
std::memcpy(data_.a.elements, values, count * sizeof(GenericValue));
|
||||
}
|
||||
else
|
||||
@@ -1695,7 +1690,7 @@ private:
|
||||
void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
|
||||
flags_ = kObjectFlag;
|
||||
if (count) {
|
||||
data_.o.members = (Member*)allocator.Malloc(count * sizeof(Member));
|
||||
data_.o.members = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
|
||||
std::memcpy(data_.o.members, members, count * sizeof(Member));
|
||||
}
|
||||
else
|
||||
@@ -1720,7 +1715,7 @@ private:
|
||||
} else {
|
||||
flags_ = kCopyStringFlag;
|
||||
data_.s.length = s.length;
|
||||
str = (Ch *)allocator.Malloc((s.length + 1) * sizeof(Ch));
|
||||
str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
|
||||
data_.s.str = str;
|
||||
}
|
||||
std::memcpy(str, s, s.length * sizeof(Ch));
|
||||
@@ -1847,7 +1842,7 @@ public:
|
||||
|
||||
//! Exchange the contents of this document with those of another.
|
||||
/*!
|
||||
\param other Another document.
|
||||
\param rhs Another document.
|
||||
\note Constant complexity.
|
||||
\see GenericValue::Swap
|
||||
*/
|
||||
@@ -1886,13 +1881,13 @@ public:
|
||||
*/
|
||||
template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
|
||||
GenericDocument& ParseStream(InputStream& is) {
|
||||
ValueType::SetNull(); // Remove existing root if exist
|
||||
GenericReader<SourceEncoding, Encoding, StackAllocator> reader(&stack_.GetAllocator());
|
||||
GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
|
||||
stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
|
||||
ClearStackOnExit scope(*this);
|
||||
parseResult_ = reader.template Parse<parseFlags>(is, *this);
|
||||
if (parseResult_) {
|
||||
RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
|
||||
this->RawAssign(*stack_.template Pop<ValueType>(1)); // Add this-> to prevent issue 13.
|
||||
ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -1951,7 +1946,7 @@ public:
|
||||
\param str Read-only zero-terminated string to be parsed.
|
||||
*/
|
||||
template <unsigned parseFlags, typename SourceEncoding>
|
||||
GenericDocument& Parse(const Ch* str) {
|
||||
GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
|
||||
RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
|
||||
GenericStringStream<SourceEncoding> s(str);
|
||||
return ParseStream<parseFlags, SourceEncoding>(s);
|
||||
@@ -1986,10 +1981,26 @@ public:
|
||||
//! Get the position of last parsing error in input, 0 otherwise.
|
||||
size_t GetErrorOffset() const { return parseResult_.Offset(); }
|
||||
|
||||
//! Implicit conversion to get the last parse result
|
||||
#ifndef __clang // -Wdocumentation
|
||||
/*! \return \ref ParseResult of the last parse operation
|
||||
|
||||
\code
|
||||
Document doc;
|
||||
ParseResult ok = doc.Parse(json);
|
||||
if (!ok)
|
||||
printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset());
|
||||
\endcode
|
||||
*/
|
||||
#endif
|
||||
operator ParseResult() const { return parseResult_; }
|
||||
//!@}
|
||||
|
||||
//! Get the allocator of this document.
|
||||
Allocator& GetAllocator() { return *allocator_; }
|
||||
Allocator& GetAllocator() {
|
||||
RAPIDJSON_ASSERT(allocator_);
|
||||
return *allocator_;
|
||||
}
|
||||
|
||||
//! Get the capacity of stack in bytes.
|
||||
size_t GetStackCapacity() const { return stack_.GetCapacity(); }
|
||||
@@ -2032,7 +2043,7 @@ private:
|
||||
|
||||
bool EndObject(SizeType memberCount) {
|
||||
typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
|
||||
stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator());
|
||||
stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2095,15 +2106,24 @@ GenericValue<Encoding,Allocator>::GenericValue(const GenericValue<Encoding,Sourc
|
||||
SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
|
||||
}
|
||||
break;
|
||||
default: // kNumberType, kTrueType, kFalseType, kNullType
|
||||
default:
|
||||
flags_ = rhs.flags_;
|
||||
data_ = *reinterpret_cast<const Data*>(&rhs.data_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#if defined(_MSC_VER) || defined(__GNUC__)
|
||||
#ifdef _MSC_VER
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
|
||||
@@ -22,6 +22,11 @@ RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(padded)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
//! Input byte stream wrapper with a statically bound encoding.
|
||||
@@ -60,7 +65,7 @@ private:
|
||||
//! Output byte stream wrapper with statically bound encoding.
|
||||
/*!
|
||||
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
|
||||
\tparam InputByteStream Type of input byte stream. For example, FileWriteStream.
|
||||
\tparam OutputByteStream Type of input byte stream. For example, FileWriteStream.
|
||||
*/
|
||||
template <typename Encoding, typename OutputByteStream>
|
||||
class EncodedOutputStream {
|
||||
@@ -77,8 +82,8 @@ public:
|
||||
void Flush() { os_.Flush(); }
|
||||
|
||||
// Not implemented
|
||||
Ch Peek() const { RAPIDJSON_ASSERT(false); }
|
||||
Ch Take() { RAPIDJSON_ASSERT(false); }
|
||||
Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
|
||||
Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
|
||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||
@@ -142,7 +147,7 @@ private:
|
||||
// FF FE UTF-16LE
|
||||
// EF BB BF UTF-8
|
||||
|
||||
const unsigned char* c = (const unsigned char *)is_->Peek4();
|
||||
const unsigned char* c = reinterpret_cast<const unsigned char *>(is_->Peek4());
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
@@ -193,7 +198,7 @@ private:
|
||||
//! Output stream wrapper with dynamically bound encoding and automatic encoding detection.
|
||||
/*!
|
||||
\tparam CharType Type of character for writing.
|
||||
\tparam InputByteStream type of output byte stream to be wrapped.
|
||||
\tparam OutputByteStream type of output byte stream to be wrapped.
|
||||
*/
|
||||
template <typename CharType, typename OutputByteStream>
|
||||
class AutoUTFOutputStream {
|
||||
@@ -227,8 +232,8 @@ public:
|
||||
void Flush() { os_->Flush(); }
|
||||
|
||||
// Not implemented
|
||||
Ch Peek() const { RAPIDJSON_ASSERT(false); }
|
||||
Ch Take() { RAPIDJSON_ASSERT(false); }
|
||||
Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
|
||||
Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
|
||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||
@@ -254,6 +259,10 @@ private:
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
@@ -120,19 +120,41 @@ struct UTF8 {
|
||||
}
|
||||
}
|
||||
|
||||
template<typename OutputStream>
|
||||
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
|
||||
if (codepoint <= 0x7F)
|
||||
PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));
|
||||
else if (codepoint <= 0x7FF) {
|
||||
PutUnsafe(os, static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
|
||||
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint & 0x3F))));
|
||||
}
|
||||
else if (codepoint <= 0xFFFF) {
|
||||
PutUnsafe(os, static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
|
||||
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
|
||||
PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));
|
||||
}
|
||||
else {
|
||||
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
||||
PutUnsafe(os, static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
|
||||
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
|
||||
PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
|
||||
PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename InputStream>
|
||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||
#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | ((unsigned char)c & 0x3Fu)
|
||||
#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0)
|
||||
#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
|
||||
#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
|
||||
#define TAIL() COPY(); TRANS(0x70)
|
||||
Ch c = is.Take();
|
||||
typename InputStream::Ch c = is.Take();
|
||||
if (!(c & 0x80)) {
|
||||
*codepoint = (unsigned char)c;
|
||||
*codepoint = static_cast<unsigned char>(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char type = GetRange((unsigned char)c);
|
||||
*codepoint = (0xFF >> type) & (unsigned char)c;
|
||||
unsigned char type = GetRange(static_cast<unsigned char>(c));
|
||||
*codepoint = (0xFF >> type) & static_cast<unsigned char>(c);
|
||||
bool result = true;
|
||||
switch (type) {
|
||||
case 2: TAIL(); return result;
|
||||
@@ -152,7 +174,7 @@ struct UTF8 {
|
||||
template <typename InputStream, typename OutputStream>
|
||||
static bool Validate(InputStream& is, OutputStream& os) {
|
||||
#define COPY() os.Put(c = is.Take())
|
||||
#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0)
|
||||
#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
|
||||
#define TAIL() COPY(); TRANS(0x70)
|
||||
Ch c;
|
||||
COPY();
|
||||
@@ -160,7 +182,7 @@ struct UTF8 {
|
||||
return true;
|
||||
|
||||
bool result = true;
|
||||
switch (GetRange((unsigned char)c)) {
|
||||
switch (GetRange(static_cast<unsigned char>(c))) {
|
||||
case 2: TAIL(); return result;
|
||||
case 3: TAIL(); TAIL(); return result;
|
||||
case 4: COPY(); TRANS(0x50); TAIL(); return result;
|
||||
@@ -196,12 +218,12 @@ struct UTF8 {
|
||||
template <typename InputByteStream>
|
||||
static CharType TakeBOM(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
Ch c = Take(is);
|
||||
if ((unsigned char)c != 0xEFu) return c;
|
||||
typename InputByteStream::Ch c = Take(is);
|
||||
if (static_cast<unsigned char>(c) != 0xEFu) return c;
|
||||
c = is.Take();
|
||||
if ((unsigned char)c != 0xBBu) return c;
|
||||
if (static_cast<unsigned char>(c) != 0xBBu) return c;
|
||||
c = is.Take();
|
||||
if ((unsigned char)c != 0xBFu) return c;
|
||||
if (static_cast<unsigned char>(c) != 0xBFu) return c;
|
||||
c = is.Take();
|
||||
return c;
|
||||
}
|
||||
@@ -209,13 +231,15 @@ struct UTF8 {
|
||||
template <typename InputByteStream>
|
||||
static Ch Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
return is.Take();
|
||||
return static_cast<Ch>(is.Take());
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0xEFu); os.Put(0xBBu); os.Put(0xBFu);
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xEFu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xBBu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xBFu));
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
@@ -259,18 +283,34 @@ struct UTF16 {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename OutputStream>
|
||||
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
|
||||
if (codepoint <= 0xFFFF) {
|
||||
RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair
|
||||
PutUnsafe(os, static_cast<typename OutputStream::Ch>(codepoint));
|
||||
}
|
||||
else {
|
||||
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
||||
unsigned v = codepoint - 0x10000;
|
||||
PutUnsafe(os, static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
|
||||
PutUnsafe(os, (v & 0x3FF) | 0xDC00);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename InputStream>
|
||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
|
||||
Ch c = is.Take();
|
||||
typename InputStream::Ch c = is.Take();
|
||||
if (c < 0xD800 || c > 0xDFFF) {
|
||||
*codepoint = c;
|
||||
*codepoint = static_cast<unsigned>(c);
|
||||
return true;
|
||||
}
|
||||
else if (c <= 0xDBFF) {
|
||||
*codepoint = (c & 0x3FF) << 10;
|
||||
*codepoint = (static_cast<unsigned>(c) & 0x3FF) << 10;
|
||||
c = is.Take();
|
||||
*codepoint |= (c & 0x3FF);
|
||||
*codepoint |= (static_cast<unsigned>(c) & 0x3FF);
|
||||
*codepoint += 0x10000;
|
||||
return c >= 0xDC00 && c <= 0xDFFF;
|
||||
}
|
||||
@@ -281,8 +321,8 @@ struct UTF16 {
|
||||
static bool Validate(InputStream& is, OutputStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
|
||||
Ch c;
|
||||
os.Put(c = is.Take());
|
||||
typename InputStream::Ch c;
|
||||
os.Put(static_cast<typename OutputStream::Ch>(c = is.Take()));
|
||||
if (c < 0xD800 || c > 0xDFFF)
|
||||
return true;
|
||||
else if (c <= 0xDBFF) {
|
||||
@@ -300,28 +340,29 @@ struct UTF16LE : UTF16<CharType> {
|
||||
static CharType TakeBOM(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = Take(is);
|
||||
return (unsigned short)c == 0xFEFFu ? Take(is) : c;
|
||||
return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = (unsigned char)is.Take();
|
||||
c |= (unsigned char)is.Take() << 8;
|
||||
return c;
|
||||
unsigned c = static_cast<uint8_t>(is.Take());
|
||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
|
||||
return static_cast<CharType>(c);
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0xFFu); os.Put(0xFEu);
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, CharType c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(c & 0xFFu);
|
||||
os.Put((c >> 8) & 0xFFu);
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -332,28 +373,29 @@ struct UTF16BE : UTF16<CharType> {
|
||||
static CharType TakeBOM(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = Take(is);
|
||||
return (unsigned short)c == 0xFEFFu ? Take(is) : c;
|
||||
return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = (unsigned char)is.Take() << 8;
|
||||
c |= (unsigned char)is.Take();
|
||||
return c;
|
||||
unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
|
||||
c |= static_cast<uint8_t>(is.Take());
|
||||
return static_cast<CharType>(c);
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0xFEu); os.Put(0xFFu);
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, CharType c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put((c >> 8) & 0xFFu);
|
||||
os.Put(c & 0xFFu);
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -382,6 +424,13 @@ struct UTF32 {
|
||||
os.Put(codepoint);
|
||||
}
|
||||
|
||||
template<typename OutputStream>
|
||||
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);
|
||||
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
||||
PutUnsafe(os, codepoint);
|
||||
}
|
||||
|
||||
template <typename InputStream>
|
||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
|
||||
@@ -406,32 +455,35 @@ struct UTF32LE : UTF32<CharType> {
|
||||
static CharType TakeBOM(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = Take(is);
|
||||
return (unsigned)c == 0x0000FEFFu ? Take(is) : c;
|
||||
return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = (unsigned char)is.Take();
|
||||
c |= (unsigned char)is.Take() << 8;
|
||||
c |= (unsigned char)is.Take() << 16;
|
||||
c |= (unsigned char)is.Take() << 24;
|
||||
return c;
|
||||
unsigned c = static_cast<uint8_t>(is.Take());
|
||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
|
||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
|
||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
|
||||
return static_cast<CharType>(c);
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0xFFu); os.Put(0xFEu); os.Put(0x00u); os.Put(0x00u);
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, CharType c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(c & 0xFFu);
|
||||
os.Put((c >> 8) & 0xFFu);
|
||||
os.Put((c >> 16) & 0xFFu);
|
||||
os.Put((c >> 24) & 0xFFu);
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -442,32 +494,35 @@ struct UTF32BE : UTF32<CharType> {
|
||||
static CharType TakeBOM(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = Take(is);
|
||||
return (unsigned)c == 0x0000FEFFu ? Take(is) : c;
|
||||
return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = (unsigned char)is.Take() << 24;
|
||||
c |= (unsigned char)is.Take() << 16;
|
||||
c |= (unsigned char)is.Take() << 8;
|
||||
c |= (unsigned char)is.Take();
|
||||
return c;
|
||||
unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
|
||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
|
||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
|
||||
c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));
|
||||
return static_cast<CharType>(c);
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0x00u); os.Put(0x00u); os.Put(0xFEu); os.Put(0xFFu);
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, CharType c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put((c >> 24) & 0xFFu);
|
||||
os.Put((c >> 16) & 0xFFu);
|
||||
os.Put((c >> 8) & 0xFFu);
|
||||
os.Put(c & 0xFFu);
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -491,31 +546,37 @@ struct ASCII {
|
||||
os.Put(static_cast<Ch>(codepoint & 0xFF));
|
||||
}
|
||||
|
||||
template<typename OutputStream>
|
||||
static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
|
||||
RAPIDJSON_ASSERT(codepoint <= 0x7F);
|
||||
PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));
|
||||
}
|
||||
|
||||
template <typename InputStream>
|
||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||
unsigned char c = static_cast<unsigned char>(is.Take());
|
||||
uint8_t c = static_cast<uint8_t>(is.Take());
|
||||
*codepoint = c;
|
||||
return c <= 0X7F;
|
||||
}
|
||||
|
||||
template <typename InputStream, typename OutputStream>
|
||||
static bool Validate(InputStream& is, OutputStream& os) {
|
||||
unsigned char c = is.Take();
|
||||
os.Put(c);
|
||||
uint8_t c = static_cast<uint8_t>(is.Take());
|
||||
os.Put(static_cast<typename OutputStream::Ch>(c));
|
||||
return c <= 0x7F;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType TakeBOM(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
Ch c = Take(is);
|
||||
return c;
|
||||
uint8_t c = static_cast<uint8_t>(Take(is));
|
||||
return static_cast<Ch>(c);
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static Ch Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
return is.Take();
|
||||
return static_cast<Ch>(is.Take());
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
@@ -561,6 +622,13 @@ struct AutoUTF {
|
||||
(*f[os.GetType()])(os, codepoint);
|
||||
}
|
||||
|
||||
template<typename OutputStream>
|
||||
RAPIDJSON_FORCEINLINE static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
|
||||
typedef void (*EncodeFunc)(OutputStream&, unsigned);
|
||||
static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) };
|
||||
(*f[os.GetType()])(os, codepoint);
|
||||
}
|
||||
|
||||
template <typename InputStream>
|
||||
RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||
typedef bool (*DecodeFunc)(InputStream&, unsigned*);
|
||||
@@ -594,6 +662,15 @@ struct Transcoder {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename InputStream, typename OutputStream>
|
||||
RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
|
||||
unsigned codepoint;
|
||||
if (!SourceEncoding::Decode(is, &codepoint))
|
||||
return false;
|
||||
TargetEncoding::EncodeUnsafe(os, codepoint);
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Validate one Unicode codepoint from an encoded stream.
|
||||
template<typename InputStream, typename OutputStream>
|
||||
RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
|
||||
@@ -601,6 +678,10 @@ struct Transcoder {
|
||||
}
|
||||
};
|
||||
|
||||
// Forward declaration.
|
||||
template<typename Stream>
|
||||
inline void PutUnsafe(Stream& stream, typename Stream::Ch c);
|
||||
|
||||
//! Specialization of Transcoder with same source and target encoding.
|
||||
template<typename Encoding>
|
||||
struct Transcoder<Encoding, Encoding> {
|
||||
@@ -610,6 +691,12 @@ struct Transcoder<Encoding, Encoding> {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename InputStream, typename OutputStream>
|
||||
RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
|
||||
PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class.
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename InputStream, typename OutputStream>
|
||||
RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
|
||||
return Encoding::Validate(is, os); // source/target encoding are the same
|
||||
@@ -618,7 +705,7 @@ struct Transcoder<Encoding, Encoding> {
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#if defined(__GNUC__) || defined(_MSV_VER)
|
||||
#if defined(__GNUC__) || defined(_MSC_VER)
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
|
||||
@@ -12,11 +12,17 @@
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifndef RAPIDJSON_ERROR_EN_H__
|
||||
#define RAPIDJSON_ERROR_EN_H__
|
||||
#ifndef RAPIDJSON_ERROR_EN_H_
|
||||
#define RAPIDJSON_ERROR_EN_H_
|
||||
|
||||
#include "error.h"
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||
RAPIDJSON_DIAG_OFF(covered-switch-default)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
//! Maps error code of parsing into error message.
|
||||
@@ -55,11 +61,14 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErro
|
||||
case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
|
||||
case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
|
||||
|
||||
default:
|
||||
return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||
}
|
||||
}
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#endif // RAPIDJSON_ERROR_EN_H__
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_ERROR_EN_H_
|
||||
|
||||
@@ -12,11 +12,16 @@
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
#ifndef RAPIDJSON_ERROR_ERROR_H__
|
||||
#define RAPIDJSON_ERROR_ERROR_H__
|
||||
#ifndef RAPIDJSON_ERROR_ERROR_H_
|
||||
#define RAPIDJSON_ERROR_ERROR_H_
|
||||
|
||||
#include "../rapidjson.h"
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(padded)
|
||||
#endif
|
||||
|
||||
/*! \file error.h */
|
||||
|
||||
/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */
|
||||
@@ -99,7 +104,7 @@ enum ParseErrorCode {
|
||||
\see GenericReader::Parse, GenericDocument::Parse
|
||||
*/
|
||||
struct ParseResult {
|
||||
|
||||
public:
|
||||
//! Default constructor, no error.
|
||||
ParseResult() : code_(kParseErrorNone), offset_(0) {}
|
||||
//! Constructor to set an error.
|
||||
@@ -143,4 +148,8 @@ typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#endif // RAPIDJSON_ERROR_ERROR_H__
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_ERROR_ERROR_H_
|
||||
|
||||
@@ -18,6 +18,13 @@
|
||||
#include "rapidjson.h"
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(padded)
|
||||
RAPIDJSON_DIAG_OFF(unreachable-code)
|
||||
RAPIDJSON_DIAG_OFF(missing-noreturn)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
//! File byte stream for input using fread().
|
||||
@@ -85,4 +92,8 @@ private:
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_FILESTREAM_H_
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
#include "rapidjson.h"
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(unreachable-code)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
//! Wrapper of C file stream for input using fread().
|
||||
@@ -57,7 +62,11 @@ public:
|
||||
|
||||
void Flush() {
|
||||
if (current_ != buffer_) {
|
||||
fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
|
||||
size_t result = fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
|
||||
if (result < static_cast<size_t>(current_ - buffer_)) {
|
||||
// failure deliberately ignored at this time
|
||||
// added to avoid warn_unused_result build errors
|
||||
}
|
||||
current_ = buffer_;
|
||||
}
|
||||
}
|
||||
@@ -88,4 +97,8 @@ inline void PutN(FileWriteStream& stream, char c, size_t n) {
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_FILESTREAM_H_
|
||||
|
||||
@@ -240,7 +240,7 @@ private:
|
||||
uint64_t r = 0;
|
||||
for (const char* p = begin; p != end; ++p) {
|
||||
RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');
|
||||
r = r * 10u + (unsigned)(*p - '0');
|
||||
r = r * 10u + static_cast<unsigned>(*p - '0');
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,11 @@ RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(padded)
|
||||
#endif
|
||||
|
||||
struct DiyFp {
|
||||
DiyFp() {}
|
||||
|
||||
@@ -242,6 +247,11 @@ inline DiyFp GetCachedPower10(int exp, int *outExp) {
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
RAPIDJSON_DIAG_OFF(padded)
|
||||
#endif
|
||||
|
||||
} // namespace internal
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
else if (order <= -1074)
|
||||
return 0;
|
||||
else
|
||||
return (unsigned)order + 1074;
|
||||
return static_cast<unsigned>(order) + 1074;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
#include "../rapidjson.h"
|
||||
#include "swap.h"
|
||||
|
||||
#if defined(__clang__)
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
namespace internal {
|
||||
|
||||
@@ -108,11 +113,21 @@ public:
|
||||
// Optimization note: try to minimize the size of this function for force inline.
|
||||
// Expansion is run very infrequently, so it is moved to another (probably non-inline) function.
|
||||
template<typename T>
|
||||
RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
|
||||
RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
|
||||
// Expand the stack if needed
|
||||
if (stackTop_ + sizeof(T) * count >= stackEnd_)
|
||||
if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_))
|
||||
Expand<T>(count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
|
||||
Reserve<T>(count);
|
||||
return PushUnsafe<T>(count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
|
||||
RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_);
|
||||
T* ret = reinterpret_cast<T*>(stackTop_);
|
||||
stackTop_ += sizeof(T) * count;
|
||||
return ret;
|
||||
@@ -132,6 +147,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
<<<<<<< HEAD
|
||||
const T* Top() const {
|
||||
RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
|
||||
return reinterpret_cast<T*>(stackTop_ - sizeof(T));
|
||||
@@ -150,6 +166,18 @@ public:
|
||||
const T* Bottom() const { return (T*)stack_; }
|
||||
|
||||
Allocator& GetAllocator() { return *allocator_; }
|
||||
=======
|
||||
T* Bottom() { return reinterpret_cast<T*>(stack_); }
|
||||
|
||||
bool HasAllocator() const {
|
||||
return allocator_ != 0;
|
||||
}
|
||||
|
||||
Allocator& GetAllocator() {
|
||||
RAPIDJSON_ASSERT(allocator_);
|
||||
return *allocator_;
|
||||
}
|
||||
>>>>>>> master
|
||||
bool Empty() const { return stackTop_ == stack_; }
|
||||
size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }
|
||||
size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }
|
||||
@@ -176,7 +204,7 @@ private:
|
||||
|
||||
void Resize(size_t newCapacity) {
|
||||
const size_t size = GetSize(); // Backup the current size
|
||||
stack_ = (char*)allocator_->Realloc(stack_, GetCapacity(), newCapacity);
|
||||
stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
|
||||
stackTop_ = stack_ + size;
|
||||
stackEnd_ = stack_ + newCapacity;
|
||||
}
|
||||
@@ -201,4 +229,8 @@ private:
|
||||
} // namespace internal
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#if defined(__clang__)
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_STACK_H_
|
||||
|
||||
@@ -149,7 +149,7 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
|
||||
v = v.Normalize();
|
||||
error <<= -v.e;
|
||||
|
||||
const int dExp = (int)decimalPosition - (int)i + exp;
|
||||
const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(i) + exp;
|
||||
|
||||
int actualExp;
|
||||
DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);
|
||||
@@ -206,7 +206,7 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
|
||||
|
||||
inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) {
|
||||
const BigInteger dInt(decimals, length);
|
||||
const int dExp = (int)decimalPosition - (int)length + exp;
|
||||
const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(length) + exp;
|
||||
Double a(approx);
|
||||
int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);
|
||||
if (cmp < 0)
|
||||
@@ -246,8 +246,8 @@ inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t
|
||||
|
||||
// Trim right-most digits
|
||||
const int kMaxDecimalDigit = 780;
|
||||
if ((int)length > kMaxDecimalDigit) {
|
||||
int delta = (int(length) - kMaxDecimalDigit);
|
||||
if (static_cast<int>(length) > kMaxDecimalDigit) {
|
||||
int delta = (static_cast<int>(length) - kMaxDecimalDigit);
|
||||
exp += delta;
|
||||
decimalPosition -= static_cast<unsigned>(delta);
|
||||
length = kMaxDecimalDigit;
|
||||
|
||||
@@ -17,10 +17,15 @@
|
||||
|
||||
#include "../rapidjson.h"
|
||||
|
||||
#if defined(__clang__)
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
namespace internal {
|
||||
|
||||
//! Custom swap() to avoid dependency on C++ <algorith> header
|
||||
//! Custom swap() to avoid dependency on C++ <algorithm> header
|
||||
/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only.
|
||||
\note This has the same semantics as std::swap().
|
||||
*/
|
||||
@@ -34,4 +39,8 @@ inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT {
|
||||
} // namespace internal
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#if defined(__clang__)
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_INTERNAL_SWAP_H_
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
|
||||
#include "rapidjson.h"
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(unreachable-code)
|
||||
RAPIDJSON_DIAG_OFF(missing-noreturn)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
//! Represents an in-memory input byte stream.
|
||||
@@ -58,4 +64,8 @@ struct MemoryStream {
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_MEMORYBUFFER_H_
|
||||
|
||||
@@ -89,14 +89,14 @@
|
||||
#include <limits.h>
|
||||
|
||||
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
|
||||
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
|
||||
// or compiler give many errors like this:
|
||||
// compiling for ARM we have to wrap <wchar.h> include with 'extern "C++" {}'
|
||||
// or compiler would give many errors like this:
|
||||
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
|
||||
#ifdef __cplusplus
|
||||
#if defined(__cplusplus) && !defined(_M_ARM)
|
||||
extern "C" {
|
||||
#endif
|
||||
# include <wchar.h>
|
||||
#ifdef __cplusplus
|
||||
#if defined(__cplusplus) && !defined(_M_ARM)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
#include "document.h"
|
||||
#include "internal/itoa.h"
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token
|
||||
@@ -71,7 +76,7 @@ template <typename ValueType, typename Allocator = CrtAllocator>
|
||||
class GenericPointer {
|
||||
public:
|
||||
typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value
|
||||
typedef typename EncodingType::Ch Ch; //!< Character type from Value
|
||||
typedef typename ValueType::Ch Ch; //!< Character type from Value
|
||||
|
||||
//! A token is the basic units of internal representation.
|
||||
/*!
|
||||
@@ -253,11 +258,12 @@ public:
|
||||
*/
|
||||
GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
|
||||
char buffer[21];
|
||||
SizeType length = (sizeof(SizeType) == 4 ? internal::u32toa(index, buffer): internal::u64toa(index, buffer)) - buffer;
|
||||
char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
|
||||
SizeType length = static_cast<SizeType>(end - buffer);
|
||||
buffer[length] = '\0';
|
||||
|
||||
if (sizeof(Ch) == 1) {
|
||||
Token token = { (Ch*)buffer, length, index };
|
||||
Token token = { reinterpret_cast<Ch*>(buffer), length, index };
|
||||
return Append(token, allocator);
|
||||
}
|
||||
else {
|
||||
@@ -271,7 +277,7 @@ public:
|
||||
|
||||
//! Append a token by value, and return a new Pointer
|
||||
/*!
|
||||
\param value Value (either Uint or String) to be appended.
|
||||
\param token token to be appended.
|
||||
\param allocator Allocator for the newly return Pointer.
|
||||
\return A new Pointer with appended token.
|
||||
*/
|
||||
@@ -393,7 +399,7 @@ public:
|
||||
bool exist = true;
|
||||
for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
|
||||
if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
|
||||
v->PushBack(Value().Move(), allocator);
|
||||
v->PushBack(ValueType().Move(), allocator);
|
||||
v = &((*v)[v->Size() - 1]);
|
||||
exist = false;
|
||||
}
|
||||
@@ -411,7 +417,7 @@ public:
|
||||
if (t->index >= v->Size()) {
|
||||
v->Reserve(t->index + 1, allocator);
|
||||
while (t->index >= v->Size())
|
||||
v->PushBack(Value().Move(), allocator);
|
||||
v->PushBack(ValueType().Move(), allocator);
|
||||
exist = false;
|
||||
}
|
||||
v = &((*v)[t->index]);
|
||||
@@ -419,7 +425,7 @@ public:
|
||||
else {
|
||||
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
|
||||
if (m == v->MemberEnd()) {
|
||||
v->AddMember(Value(t->name, t->length, allocator).Move(), Value().Move(), allocator);
|
||||
v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
|
||||
v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end
|
||||
exist = false;
|
||||
}
|
||||
@@ -438,7 +444,6 @@ public:
|
||||
//! Creates a value in a document.
|
||||
/*!
|
||||
\param document A document to be resolved.
|
||||
\param allocator Allocator for creating the values if the specified value or its parents are not exist.
|
||||
\param alreadyExist If non-null, it stores whether the resolved value is already exist.
|
||||
\return The resolved newly created, or already exists value.
|
||||
*/
|
||||
@@ -528,7 +533,7 @@ public:
|
||||
|
||||
//! Query a value in a subtree with default primitive value.
|
||||
/*!
|
||||
\tparam T \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
|
||||
\tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
|
||||
*/
|
||||
template <typename T>
|
||||
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
|
||||
@@ -558,7 +563,7 @@ public:
|
||||
|
||||
//! Query a value in a document with default primitive value.
|
||||
/*!
|
||||
\tparam T \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
|
||||
\tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
|
||||
*/
|
||||
template <typename T, typename stackAllocator>
|
||||
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
|
||||
@@ -604,7 +609,7 @@ public:
|
||||
|
||||
//! Set a primitive value in a subtree.
|
||||
/*!
|
||||
\tparam T \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
|
||||
\tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
|
||||
*/
|
||||
template <typename T>
|
||||
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
|
||||
@@ -640,7 +645,7 @@ public:
|
||||
|
||||
//! Set a primitive value in a document.
|
||||
/*!
|
||||
\tparam T \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
|
||||
\tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
|
||||
*/
|
||||
template <typename T, typename stackAllocator>
|
||||
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
|
||||
@@ -762,11 +767,13 @@ private:
|
||||
}
|
||||
|
||||
//! Parse a JSON String or its URI fragment representation into tokens.
|
||||
#ifndef __clang__ // -Wdocumentation
|
||||
/*!
|
||||
\param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated.
|
||||
\param length Length of the source string.
|
||||
\note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped.
|
||||
*/
|
||||
#endif
|
||||
void Parse(const Ch* source, size_t length) {
|
||||
RAPIDJSON_ASSERT(source != NULL);
|
||||
RAPIDJSON_ASSERT(nameBuffer_ == 0);
|
||||
@@ -860,7 +867,7 @@ private:
|
||||
|
||||
*name++ = c;
|
||||
}
|
||||
token->length = name - token->name;
|
||||
token->length = static_cast<SizeType>(name - token->name);
|
||||
if (token->length == 0)
|
||||
isNumber = false;
|
||||
*name++ = '\0'; // Null terminator
|
||||
@@ -947,6 +954,8 @@ private:
|
||||
*/
|
||||
class PercentDecodeStream {
|
||||
public:
|
||||
typedef typename ValueType::Ch Ch;
|
||||
|
||||
//! Constructor
|
||||
/*!
|
||||
\param source Start of the stream
|
||||
@@ -976,7 +985,7 @@ private:
|
||||
return c;
|
||||
}
|
||||
|
||||
size_t Tell() const { return src_ - head_; }
|
||||
size_t Tell() const { return static_cast<size_t>(src_ - head_); }
|
||||
bool IsValid() const { return valid_; }
|
||||
|
||||
private:
|
||||
@@ -1313,4 +1322,8 @@ bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_POINTER_H_
|
||||
|
||||
@@ -186,7 +186,7 @@ protected:
|
||||
|
||||
void WriteIndent() {
|
||||
size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
|
||||
PutN(*Base::os_, indentChar_, count);
|
||||
PutN(*Base::os_, static_cast<typename TargetEncoding::Ch>(indentChar_), count);
|
||||
}
|
||||
|
||||
Ch indentChar_;
|
||||
|
||||
@@ -119,6 +119,31 @@
|
||||
#define RAPIDJSON_NAMESPACE_END }
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_HAS_STDSTRING
|
||||
|
||||
#ifndef RAPIDJSON_HAS_STDSTRING
|
||||
#ifdef RAPIDJSON_DOXYGEN_RUNNING
|
||||
#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation
|
||||
#else
|
||||
#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default
|
||||
#endif
|
||||
/*! \def RAPIDJSON_HAS_STDSTRING
|
||||
\ingroup RAPIDJSON_CONFIG
|
||||
\brief Enable RapidJSON support for \c std::string
|
||||
|
||||
By defining this preprocessor symbol to \c 1, several convenience functions for using
|
||||
\ref rapidjson::GenericValue with \c std::string are enabled, especially
|
||||
for construction and comparison.
|
||||
|
||||
\hideinitializer
|
||||
*/
|
||||
#endif // !defined(RAPIDJSON_HAS_STDSTRING)
|
||||
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
#include <string>
|
||||
#endif // RAPIDJSON_HAS_STDSTRING
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_NO_INT64DEFINE
|
||||
|
||||
@@ -153,9 +178,9 @@
|
||||
|
||||
#ifndef RAPIDJSON_FORCEINLINE
|
||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||
#if defined(_MSC_VER) && !defined(NDEBUG)
|
||||
#if defined(_MSC_VER) && defined(NDEBUG)
|
||||
#define RAPIDJSON_FORCEINLINE __forceinline
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4 && !defined(NDEBUG)
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG)
|
||||
#define RAPIDJSON_FORCEINLINE __attribute__((always_inline))
|
||||
#else
|
||||
#define RAPIDJSON_FORCEINLINE
|
||||
@@ -211,6 +236,8 @@
|
||||
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
||||
# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
|
||||
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
|
||||
# elif defined(_MSC_VER) && defined(_M_ARM)
|
||||
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
|
||||
# elif defined(RAPIDJSON_DOXYGEN_RUNNING)
|
||||
# define RAPIDJSON_ENDIAN
|
||||
# else
|
||||
@@ -238,13 +265,13 @@
|
||||
\param x pointer to align
|
||||
|
||||
Some machines require strict data alignment. Currently the default uses 4 bytes
|
||||
alignment. User can customize by defining the RAPIDJSON_ALIGN function macro.,
|
||||
alignment. User can customize by defining the RAPIDJSON_ALIGN function macro.
|
||||
*/
|
||||
#ifndef RAPIDJSON_ALIGN
|
||||
#if RAPIDJSON_64BIT == 1
|
||||
#define RAPIDJSON_ALIGN(x) ((x + 7u) & ~7u)
|
||||
#define RAPIDJSON_ALIGN(x) (((x) + static_cast<uint64_t>(7u)) & ~static_cast<uint64_t>(7u))
|
||||
#else
|
||||
#define RAPIDJSON_ALIGN(x) ((x + 3u) & ~3u)
|
||||
#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -349,7 +376,9 @@ RAPIDJSON_NAMESPACE_END
|
||||
|
||||
// Adopt from boost
|
||||
#ifndef RAPIDJSON_STATIC_ASSERT
|
||||
#ifndef __clang__
|
||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||
#endif
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
template <bool x> struct STATIC_ASSERTION_FAILURE;
|
||||
template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
|
||||
@@ -365,7 +394,9 @@ RAPIDJSON_NAMESPACE_END
|
||||
#else
|
||||
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
|
||||
#endif
|
||||
#ifndef __clang__
|
||||
//!@endcond
|
||||
#endif
|
||||
|
||||
/*! \def RAPIDJSON_STATIC_ASSERT
|
||||
\brief (Internal) macro to check for conditions at compile-time
|
||||
@@ -378,6 +409,35 @@ RAPIDJSON_NAMESPACE_END
|
||||
RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY
|
||||
|
||||
//! Compiler branching hint for expression with high probability to be true.
|
||||
/*!
|
||||
\ingroup RAPIDJSON_CONFIG
|
||||
\param x Boolean expression likely to be true.
|
||||
*/
|
||||
#ifndef RAPIDJSON_LIKELY
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#else
|
||||
#define RAPIDJSON_LIKELY(x) x
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//! Compiler branching hint for expression with low probability to be true.
|
||||
/*!
|
||||
\ingroup RAPIDJSON_CONFIG
|
||||
\param x Boolean expression unlikely to be true.
|
||||
*/
|
||||
#ifndef RAPIDJSON_UNLIKELY
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
#define RAPIDJSON_UNLIKELY(x) x
|
||||
#endif
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
|
||||
@@ -554,11 +614,25 @@ struct StreamTraits {
|
||||
enum { copyOptimization = 0 };
|
||||
};
|
||||
|
||||
//! Reserve n characters for writing to a stream.
|
||||
template<typename Stream>
|
||||
inline void PutReserve(Stream& stream, size_t count) {
|
||||
(void)stream;
|
||||
(void)count;
|
||||
}
|
||||
|
||||
//! Write character to a stream, presuming buffer is reserved.
|
||||
template<typename Stream>
|
||||
inline void PutUnsafe(Stream& stream, typename Stream::Ch c) {
|
||||
stream.Put(c);
|
||||
}
|
||||
|
||||
//! Put N copies of a character to a stream.
|
||||
template<typename Stream, typename Ch>
|
||||
inline void PutN(Stream& stream, Ch c, size_t n) {
|
||||
PutReserve<Stream>(stream, n);
|
||||
for (size_t i = 0; i < n; i++)
|
||||
stream.Put(c);
|
||||
PutUnsafe(stream, c);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -39,6 +39,12 @@ RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
|
||||
RAPIDJSON_DIAG_OFF(4702) // unreachable code
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(padded)
|
||||
RAPIDJSON_DIAG_OFF(switch-enum)
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
@@ -49,7 +55,7 @@ RAPIDJSON_DIAG_OFF(effc++)
|
||||
#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN
|
||||
#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \
|
||||
RAPIDJSON_MULTILINEMACRO_BEGIN \
|
||||
if (HasParseError()) { return value; } \
|
||||
if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
|
||||
RAPIDJSON_MULTILINEMACRO_END
|
||||
#endif
|
||||
#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \
|
||||
@@ -140,6 +146,7 @@ enum ParseFlag {
|
||||
kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing.
|
||||
kParseStopWhenDoneFlag = 8, //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error.
|
||||
kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower).
|
||||
kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments.
|
||||
kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
|
||||
};
|
||||
|
||||
@@ -262,7 +269,7 @@ inline const char *SkipWhitespace_SIMD(const char* p) {
|
||||
return p;
|
||||
|
||||
// 16-byte align to the next boundary
|
||||
const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & ~15);
|
||||
const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
|
||||
while (p != nextAligned)
|
||||
if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
|
||||
++p;
|
||||
@@ -271,11 +278,11 @@ inline const char *SkipWhitespace_SIMD(const char* p) {
|
||||
|
||||
// The rest of string using SIMD
|
||||
static const char whitespace[16] = " \n\r\t";
|
||||
const __m128i w = _mm_loadu_si128((const __m128i *)&whitespace[0]);
|
||||
const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
|
||||
|
||||
for (;; p += 16) {
|
||||
const __m128i s = _mm_load_si128((const __m128i *)p);
|
||||
const unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
|
||||
const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
|
||||
const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
|
||||
if (r != 0) { // some of characters is non-whitespace
|
||||
#ifdef _MSC_VER // Find the index of first non-whitespace
|
||||
unsigned long offset;
|
||||
@@ -299,7 +306,7 @@ inline const char *SkipWhitespace_SIMD(const char* p) {
|
||||
return p;
|
||||
|
||||
// 16-byte align to the next boundary
|
||||
const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & ~15);
|
||||
const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
|
||||
while (p != nextAligned)
|
||||
if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
|
||||
++p;
|
||||
@@ -307,24 +314,22 @@ inline const char *SkipWhitespace_SIMD(const char* p) {
|
||||
return p;
|
||||
|
||||
// The rest of string
|
||||
static const char whitespaces[4][17] = {
|
||||
" ",
|
||||
"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
|
||||
"\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r",
|
||||
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"};
|
||||
#define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
|
||||
static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
|
||||
#undef C16
|
||||
|
||||
const __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]);
|
||||
const __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]);
|
||||
const __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]);
|
||||
const __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]);
|
||||
const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
|
||||
const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
|
||||
const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
|
||||
const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
|
||||
|
||||
for (;; p += 16) {
|
||||
const __m128i s = _mm_load_si128((const __m128i *)p);
|
||||
const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
|
||||
__m128i x = _mm_cmpeq_epi8(s, w0);
|
||||
x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
|
||||
x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
|
||||
x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
|
||||
unsigned short r = (unsigned short)~_mm_movemask_epi8(x);
|
||||
unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
|
||||
if (r != 0) { // some of characters may be non-whitespace
|
||||
#ifdef _MSC_VER // Find the index of first non-whitespace
|
||||
unsigned long offset;
|
||||
@@ -398,9 +403,10 @@ public:
|
||||
|
||||
ClearStackOnExit scope(*this);
|
||||
|
||||
SkipWhitespace(is);
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||
|
||||
if (is.Peek() == '\0') {
|
||||
if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) {
|
||||
RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||
}
|
||||
@@ -409,9 +415,10 @@ public:
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||
|
||||
if (!(parseFlags & kParseStopWhenDoneFlag)) {
|
||||
SkipWhitespace(is);
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||
|
||||
if (is.Peek() != '\0') {
|
||||
if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) {
|
||||
RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||
}
|
||||
@@ -462,52 +469,96 @@ private:
|
||||
ClearStackOnExit& operator=(const ClearStackOnExit&);
|
||||
};
|
||||
|
||||
template<unsigned parseFlags, typename InputStream>
|
||||
void SkipWhitespaceAndComments(InputStream& is) {
|
||||
SkipWhitespace(is);
|
||||
|
||||
if (parseFlags & kParseCommentsFlag) {
|
||||
while (RAPIDJSON_UNLIKELY(is.Peek() == '/')) {
|
||||
is.Take();
|
||||
|
||||
if (is.Peek() == '*') {
|
||||
is.Take();
|
||||
while (true) {
|
||||
if (RAPIDJSON_UNLIKELY(is.Peek() == '\0'))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
|
||||
|
||||
if (is.Take() == '*') {
|
||||
if (RAPIDJSON_UNLIKELY(is.Peek() == '\0'))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
|
||||
|
||||
if (is.Take() == '/')
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (RAPIDJSON_LIKELY(is.Peek() == '/')) {
|
||||
is.Take();
|
||||
while (is.Peek() != '\0' && is.Take() != '\n') { }
|
||||
}
|
||||
else
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
|
||||
|
||||
SkipWhitespace(is);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse object: { string : value, ... }
|
||||
template<unsigned parseFlags, typename InputStream, typename Handler>
|
||||
void ParseObject(InputStream& is, Handler& handler) {
|
||||
RAPIDJSON_ASSERT(is.Peek() == '{');
|
||||
is.Take(); // Skip '{'
|
||||
|
||||
if (!handler.StartObject())
|
||||
if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||
|
||||
SkipWhitespace(is);
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
|
||||
if (is.Peek() == '}') {
|
||||
is.Take();
|
||||
if (!handler.EndObject(0)) // empty object
|
||||
if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||
return;
|
||||
}
|
||||
|
||||
for (SizeType memberCount = 0;;) {
|
||||
if (is.Peek() != '"')
|
||||
if (RAPIDJSON_UNLIKELY(is.Peek() != '"'))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
|
||||
|
||||
ParseString<parseFlags>(is, handler, true);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
|
||||
SkipWhitespace(is);
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
|
||||
if (is.Take() != ':')
|
||||
if (RAPIDJSON_UNLIKELY(is.Take() != ':'))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
|
||||
|
||||
SkipWhitespace(is);
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
|
||||
ParseValue<parseFlags>(is, handler);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
|
||||
SkipWhitespace(is);
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
|
||||
++memberCount;
|
||||
|
||||
switch (is.Take()) {
|
||||
case ',': SkipWhitespace(is); break;
|
||||
case ',':
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
break;
|
||||
case '}':
|
||||
if (!handler.EndObject(memberCount))
|
||||
if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||
return;
|
||||
default: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
|
||||
default:
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -518,14 +569,15 @@ private:
|
||||
RAPIDJSON_ASSERT(is.Peek() == '[');
|
||||
is.Take(); // Skip '['
|
||||
|
||||
if (!handler.StartArray())
|
||||
if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||
|
||||
SkipWhitespace(is);
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
|
||||
if (is.Peek() == ']') {
|
||||
is.Take();
|
||||
if (!handler.EndArray(0)) // empty array
|
||||
if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||
return;
|
||||
}
|
||||
@@ -535,15 +587,21 @@ private:
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
|
||||
++elementCount;
|
||||
SkipWhitespace(is);
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
|
||||
switch (is.Take()) {
|
||||
case ',': SkipWhitespace(is); break;
|
||||
case ',':
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
break;
|
||||
case ']':
|
||||
if (!handler.EndArray(elementCount))
|
||||
if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||
return;
|
||||
default: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
|
||||
default:
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -553,8 +611,8 @@ private:
|
||||
RAPIDJSON_ASSERT(is.Peek() == 'n');
|
||||
is.Take();
|
||||
|
||||
if (is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l') {
|
||||
if (!handler.Null())
|
||||
if (RAPIDJSON_LIKELY(is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l')) {
|
||||
if (RAPIDJSON_UNLIKELY(!handler.Null()))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||
}
|
||||
else
|
||||
@@ -566,8 +624,8 @@ private:
|
||||
RAPIDJSON_ASSERT(is.Peek() == 't');
|
||||
is.Take();
|
||||
|
||||
if (is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e') {
|
||||
if (!handler.Bool(true))
|
||||
if (RAPIDJSON_LIKELY(is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e')) {
|
||||
if (RAPIDJSON_UNLIKELY(!handler.Bool(true)))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||
}
|
||||
else
|
||||
@@ -579,8 +637,8 @@ private:
|
||||
RAPIDJSON_ASSERT(is.Peek() == 'f');
|
||||
is.Take();
|
||||
|
||||
if (is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e') {
|
||||
if (!handler.Bool(false))
|
||||
if (RAPIDJSON_LIKELY(is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e')) {
|
||||
if (RAPIDJSON_UNLIKELY(!handler.Bool(false)))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||
}
|
||||
else
|
||||
@@ -619,7 +677,14 @@ private:
|
||||
*stack_.template Push<Ch>() = c;
|
||||
++length_;
|
||||
}
|
||||
|
||||
RAPIDJSON_FORCEINLINE void* Push(SizeType count) {
|
||||
length_ += count;
|
||||
return stack_.template Push<Ch>(count);
|
||||
}
|
||||
|
||||
size_t Length() const { return length_; }
|
||||
|
||||
Ch* Pop() {
|
||||
return stack_.template Pop<Ch>(length_);
|
||||
}
|
||||
@@ -638,6 +703,9 @@ private:
|
||||
internal::StreamLocalCopy<InputStream> copy(is);
|
||||
InputStream& s(copy.s);
|
||||
|
||||
RAPIDJSON_ASSERT(s.Peek() == '\"');
|
||||
s.Take(); // Skip '\"'
|
||||
|
||||
bool success = false;
|
||||
if (parseFlags & kParseInsituFlag) {
|
||||
typename InputStream::Ch *head = s.PutBegin();
|
||||
@@ -645,7 +713,7 @@ private:
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
size_t length = s.PutEnd(head) - 1;
|
||||
RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
|
||||
const typename TargetEncoding::Ch* const str = (typename TargetEncoding::Ch*)head;
|
||||
const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
|
||||
success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
|
||||
}
|
||||
else {
|
||||
@@ -656,7 +724,7 @@ private:
|
||||
const typename TargetEncoding::Ch* const str = stackStream.Pop();
|
||||
success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));
|
||||
}
|
||||
if (!success)
|
||||
if (RAPIDJSON_UNLIKELY(!success))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
|
||||
}
|
||||
|
||||
@@ -676,27 +744,27 @@ private:
|
||||
#undef Z16
|
||||
//!@endcond
|
||||
|
||||
RAPIDJSON_ASSERT(is.Peek() == '\"');
|
||||
is.Take(); // Skip '\"'
|
||||
|
||||
for (;;) {
|
||||
// Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation.
|
||||
if (!(parseFlags & kParseValidateEncodingFlag))
|
||||
ScanCopyUnescapedString(is, os);
|
||||
|
||||
Ch c = is.Peek();
|
||||
if (c == '\\') { // Escape
|
||||
if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape
|
||||
is.Take();
|
||||
Ch e = is.Take();
|
||||
if ((sizeof(Ch) == 1 || unsigned(e) < 256) && escape[(unsigned char)e]) {
|
||||
os.Put(escape[(unsigned char)e]);
|
||||
}
|
||||
else if (e == 'u') { // Unicode
|
||||
if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)]))
|
||||
os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
|
||||
else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode
|
||||
unsigned codepoint = ParseHex4(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
if (codepoint >= 0xD800 && codepoint <= 0xDBFF) {
|
||||
if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {
|
||||
// Handle UTF-16 surrogate pair
|
||||
if (is.Take() != '\\' || is.Take() != 'u')
|
||||
if (RAPIDJSON_UNLIKELY(is.Take() != '\\' || is.Take() != 'u'))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2);
|
||||
unsigned codepoint2 = ParseHex4(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)
|
||||
if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2);
|
||||
codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
|
||||
}
|
||||
@@ -705,24 +773,188 @@ private:
|
||||
else
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1);
|
||||
}
|
||||
else if (c == '"') { // Closing double quote
|
||||
else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote
|
||||
is.Take();
|
||||
os.Put('\0'); // null-terminate the string
|
||||
return;
|
||||
}
|
||||
else if (c == '\0')
|
||||
else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
|
||||
if (c == '\0')
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell() - 1);
|
||||
else if ((unsigned)c < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
|
||||
else
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1);
|
||||
}
|
||||
else {
|
||||
if (parseFlags & kParseValidateEncodingFlag ?
|
||||
if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?
|
||||
!Transcoder<SEncoding, TEncoding>::Validate(is, os) :
|
||||
!Transcoder<SEncoding, TEncoding>::Transcode(is, os))
|
||||
!Transcoder<SEncoding, TEncoding>::Transcode(is, os))))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename InputStream, typename OutputStream>
|
||||
static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) {
|
||||
// Do nothing for generic version
|
||||
}
|
||||
|
||||
#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
|
||||
// StringStream -> StackStream<char>
|
||||
static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {
|
||||
const char* p = is.src_;
|
||||
|
||||
// Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
|
||||
const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
|
||||
while (p != nextAligned)
|
||||
if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
|
||||
is.src_ = p;
|
||||
return;
|
||||
}
|
||||
else
|
||||
os.Put(*p++);
|
||||
|
||||
// The rest of string using SIMD
|
||||
static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
|
||||
static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
|
||||
static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
|
||||
const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
|
||||
const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
|
||||
const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
|
||||
|
||||
for (;; p += 16) {
|
||||
const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
|
||||
const __m128i t1 = _mm_cmpeq_epi8(s, dq);
|
||||
const __m128i t2 = _mm_cmpeq_epi8(s, bs);
|
||||
const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
|
||||
const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
|
||||
unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
|
||||
if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
|
||||
SizeType length;
|
||||
#ifdef _MSC_VER // Find the index of first escaped
|
||||
unsigned long offset;
|
||||
_BitScanForward(&offset, r);
|
||||
length = offset;
|
||||
#else
|
||||
length = static_cast<SizeType>(__builtin_ffs(r) - 1);
|
||||
#endif
|
||||
char* q = reinterpret_cast<char*>(os.Push(length));
|
||||
for (size_t i = 0; i < length; i++)
|
||||
q[i] = p[i];
|
||||
|
||||
p += length;
|
||||
break;
|
||||
}
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s);
|
||||
}
|
||||
|
||||
is.src_ = p;
|
||||
}
|
||||
|
||||
// InsituStringStream -> InsituStringStream
|
||||
static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {
|
||||
RAPIDJSON_ASSERT(&is == &os);
|
||||
(void)os;
|
||||
|
||||
if (is.src_ == is.dst_) {
|
||||
SkipUnescapedString(is);
|
||||
return;
|
||||
}
|
||||
|
||||
char* p = is.src_;
|
||||
char *q = is.dst_;
|
||||
|
||||
// Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
|
||||
const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
|
||||
while (p != nextAligned)
|
||||
if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
|
||||
is.src_ = p;
|
||||
is.dst_ = q;
|
||||
return;
|
||||
}
|
||||
else
|
||||
*q++ = *p++;
|
||||
|
||||
// The rest of string using SIMD
|
||||
static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
|
||||
static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
|
||||
static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
|
||||
const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
|
||||
const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
|
||||
const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
|
||||
|
||||
for (;; p += 16, q += 16) {
|
||||
const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
|
||||
const __m128i t1 = _mm_cmpeq_epi8(s, dq);
|
||||
const __m128i t2 = _mm_cmpeq_epi8(s, bs);
|
||||
const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
|
||||
const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
|
||||
unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
|
||||
if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
|
||||
size_t length;
|
||||
#ifdef _MSC_VER // Find the index of first escaped
|
||||
unsigned long offset;
|
||||
_BitScanForward(&offset, r);
|
||||
length = offset;
|
||||
#else
|
||||
length = static_cast<size_t>(__builtin_ffs(r) - 1);
|
||||
#endif
|
||||
for (const char* pend = p + length; p != pend; )
|
||||
*q++ = *p++;
|
||||
break;
|
||||
}
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(q), s);
|
||||
}
|
||||
|
||||
is.src_ = p;
|
||||
is.dst_ = q;
|
||||
}
|
||||
|
||||
// When read/write pointers are the same for insitu stream, just skip unescaped characters
|
||||
static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {
|
||||
RAPIDJSON_ASSERT(is.src_ == is.dst_);
|
||||
char* p = is.src_;
|
||||
|
||||
// Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
|
||||
const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
|
||||
for (; p != nextAligned; p++)
|
||||
if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
|
||||
is.src_ = is.dst_ = p;
|
||||
return;
|
||||
}
|
||||
|
||||
// The rest of string using SIMD
|
||||
static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
|
||||
static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
|
||||
static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
|
||||
const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
|
||||
const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
|
||||
const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
|
||||
|
||||
for (;; p += 16) {
|
||||
const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
|
||||
const __m128i t1 = _mm_cmpeq_epi8(s, dq);
|
||||
const __m128i t2 = _mm_cmpeq_epi8(s, bs);
|
||||
const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
|
||||
const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
|
||||
unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
|
||||
if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
|
||||
size_t length;
|
||||
#ifdef _MSC_VER // Find the index of first escaped
|
||||
unsigned long offset;
|
||||
_BitScanForward(&offset, r);
|
||||
length = offset;
|
||||
#else
|
||||
length = static_cast<size_t>(__builtin_ffs(r) - 1);
|
||||
#endif
|
||||
p += length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
is.src_ = is.dst_ = p;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename InputStream, bool backup>
|
||||
class NumberStream;
|
||||
|
||||
@@ -753,7 +985,7 @@ private:
|
||||
~NumberStream() {}
|
||||
|
||||
RAPIDJSON_FORCEINLINE Ch TakePush() {
|
||||
stackStream.Put((char)Base::is.Peek());
|
||||
stackStream.Put(static_cast<char>(Base::is.Peek()));
|
||||
return Base::is.Take();
|
||||
}
|
||||
|
||||
@@ -785,17 +1017,17 @@ private:
|
||||
uint64_t i64 = 0;
|
||||
bool use64bit = false;
|
||||
int significandDigit = 0;
|
||||
if (s.Peek() == '0') {
|
||||
if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) {
|
||||
i = 0;
|
||||
s.TakePush();
|
||||
}
|
||||
else if (s.Peek() >= '1' && s.Peek() <= '9') {
|
||||
else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) {
|
||||
i = static_cast<unsigned>(s.TakePush() - '0');
|
||||
|
||||
if (minus)
|
||||
while (s.Peek() >= '0' && s.Peek() <= '9') {
|
||||
if (i >= 214748364) { // 2^31 = 2147483648
|
||||
if (i != 214748364 || s.Peek() > '8') {
|
||||
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
||||
if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648
|
||||
if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) {
|
||||
i64 = i;
|
||||
use64bit = true;
|
||||
break;
|
||||
@@ -805,9 +1037,9 @@ private:
|
||||
significandDigit++;
|
||||
}
|
||||
else
|
||||
while (s.Peek() >= '0' && s.Peek() <= '9') {
|
||||
if (i >= 429496729) { // 2^32 - 1 = 4294967295
|
||||
if (i != 429496729 || s.Peek() > '5') {
|
||||
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
||||
if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295
|
||||
if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) {
|
||||
i64 = i;
|
||||
use64bit = true;
|
||||
break;
|
||||
@@ -825,10 +1057,10 @@ private:
|
||||
double d = 0.0;
|
||||
if (use64bit) {
|
||||
if (minus)
|
||||
while (s.Peek() >= '0' && s.Peek() <= '9') {
|
||||
if (i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC)) // 2^63 = 9223372036854775808
|
||||
if (i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8') {
|
||||
d = i64;
|
||||
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
||||
if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808
|
||||
if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) {
|
||||
d = static_cast<double>(i64);
|
||||
useDouble = true;
|
||||
break;
|
||||
}
|
||||
@@ -836,10 +1068,10 @@ private:
|
||||
significandDigit++;
|
||||
}
|
||||
else
|
||||
while (s.Peek() >= '0' && s.Peek() <= '9') {
|
||||
if (i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999)) // 2^64 - 1 = 18446744073709551615
|
||||
if (i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5') {
|
||||
d = i64;
|
||||
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
||||
if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615
|
||||
if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) {
|
||||
d = static_cast<double>(i64);
|
||||
useDouble = true;
|
||||
break;
|
||||
}
|
||||
@@ -850,8 +1082,8 @@ private:
|
||||
|
||||
// Force double for big integer
|
||||
if (useDouble) {
|
||||
while (s.Peek() >= '0' && s.Peek() <= '9') {
|
||||
if (d >= 1.7976931348623157e307) // DBL_MAX / 10.0
|
||||
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
||||
if (RAPIDJSON_UNLIKELY(d >= 1.7976931348623157e307)) // DBL_MAX / 10.0
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell());
|
||||
d = d * 10 + (s.TakePush() - '0');
|
||||
}
|
||||
@@ -864,7 +1096,7 @@ private:
|
||||
s.Take();
|
||||
decimalPosition = s.Length();
|
||||
|
||||
if (!(s.Peek() >= '0' && s.Peek() <= '9'))
|
||||
if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());
|
||||
|
||||
if (!useDouble) {
|
||||
@@ -873,7 +1105,7 @@ private:
|
||||
if (!use64bit)
|
||||
i64 = i;
|
||||
|
||||
while (s.Peek() >= '0' && s.Peek() <= '9') {
|
||||
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
||||
if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path
|
||||
break;
|
||||
else {
|
||||
@@ -884,19 +1116,19 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
d = (double)i64;
|
||||
d = static_cast<double>(i64);
|
||||
#else
|
||||
// Use double to store significand in 32-bit architecture
|
||||
d = use64bit ? (double)i64 : (double)i;
|
||||
d = static_cast<double>(use64bit ? i64 : i);
|
||||
#endif
|
||||
useDouble = true;
|
||||
}
|
||||
|
||||
while (s.Peek() >= '0' && s.Peek() <= '9') {
|
||||
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
||||
if (significandDigit < 17) {
|
||||
d = d * 10.0 + (s.TakePush() - '0');
|
||||
--expFrac;
|
||||
if (d > 0.0)
|
||||
if (RAPIDJSON_LIKELY(d > 0.0))
|
||||
significandDigit++;
|
||||
}
|
||||
else
|
||||
@@ -910,7 +1142,7 @@ private:
|
||||
int exp = 0;
|
||||
if (s.Peek() == 'e' || s.Peek() == 'E') {
|
||||
if (!useDouble) {
|
||||
d = use64bit ? i64 : i;
|
||||
d = static_cast<double>(use64bit ? i64 : i);
|
||||
useDouble = true;
|
||||
}
|
||||
s.Take();
|
||||
@@ -923,22 +1155,22 @@ private:
|
||||
expMinus = true;
|
||||
}
|
||||
|
||||
if (s.Peek() >= '0' && s.Peek() <= '9') {
|
||||
exp = s.Take() - '0';
|
||||
if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
||||
exp = static_cast<int>(s.Take() - '0');
|
||||
if (expMinus) {
|
||||
while (s.Peek() >= '0' && s.Peek() <= '9') {
|
||||
exp = exp * 10 + (s.Take() - '0');
|
||||
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
||||
exp = exp * 10 + static_cast<int>(s.Take() - '0');
|
||||
if (exp >= 214748364) { // Issue #313: prevent overflow exponent
|
||||
while (s.Peek() >= '0' && s.Peek() <= '9') // Consume the rest of exponent
|
||||
while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent
|
||||
s.Take();
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // positive exp
|
||||
int maxExp = 308 - expFrac;
|
||||
while (s.Peek() >= '0' && s.Peek() <= '9') {
|
||||
exp = exp * 10 + (s.Take() - '0');
|
||||
if (exp > maxExp)
|
||||
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
|
||||
exp = exp * 10 + static_cast<int>(s.Take() - '0');
|
||||
if (RAPIDJSON_UNLIKELY(exp > maxExp))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell());
|
||||
}
|
||||
}
|
||||
@@ -978,7 +1210,7 @@ private:
|
||||
cont = handler.Uint(i);
|
||||
}
|
||||
}
|
||||
if (!cont)
|
||||
if (RAPIDJSON_UNLIKELY(!cont))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
|
||||
}
|
||||
|
||||
@@ -992,7 +1224,10 @@ private:
|
||||
case '"': ParseString<parseFlags>(is, handler); break;
|
||||
case '{': ParseObject<parseFlags>(is, handler); break;
|
||||
case '[': ParseArray <parseFlags>(is, handler); break;
|
||||
default : ParseNumber<parseFlags>(is, handler);
|
||||
default :
|
||||
ParseNumber<parseFlags>(is, handler);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1019,11 +1254,11 @@ private:
|
||||
IterativeParsingArrayFinishState,
|
||||
|
||||
// Single value state
|
||||
IterativeParsingValueState,
|
||||
|
||||
cIterativeParsingStateCount
|
||||
IterativeParsingValueState
|
||||
};
|
||||
|
||||
enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 };
|
||||
|
||||
// Tokens
|
||||
enum Token {
|
||||
LeftBracketToken = 0,
|
||||
@@ -1065,8 +1300,8 @@ private:
|
||||
#undef N16
|
||||
//!@endcond
|
||||
|
||||
if (sizeof(Ch) == 1 || unsigned(c) < 256)
|
||||
return (Token)tokenMap[(unsigned char)c];
|
||||
if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)
|
||||
return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]);
|
||||
else
|
||||
return NumberToken;
|
||||
}
|
||||
@@ -1232,7 +1467,7 @@ private:
|
||||
}
|
||||
}; // End of G
|
||||
|
||||
return (IterativeParsingState)G[state][token];
|
||||
return static_cast<IterativeParsingState>(G[state][token]);
|
||||
}
|
||||
|
||||
// Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().
|
||||
@@ -1394,7 +1629,7 @@ private:
|
||||
case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;
|
||||
case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;
|
||||
case IterativeParsingElementState: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;
|
||||
default: RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
|
||||
default: RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1404,7 +1639,8 @@ private:
|
||||
ClearStackOnExit scope(*this);
|
||||
IterativeParsingState state = IterativeParsingStartState;
|
||||
|
||||
SkipWhitespace(is);
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||
while (is.Peek() != '\0') {
|
||||
Token t = Tokenize(is.Peek());
|
||||
IterativeParsingState n = Predict(state, t);
|
||||
@@ -1421,7 +1657,8 @@ private:
|
||||
if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
|
||||
break;
|
||||
|
||||
SkipWhitespace(is);
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||
}
|
||||
|
||||
// Handle the end of file.
|
||||
@@ -1441,6 +1678,11 @@ typedef GenericReader<UTF8<>, UTF8<> > Reader;
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
|
||||
#include "internal/stack.h"
|
||||
|
||||
#if defined(__clang__)
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
//! Represents an in-memory output stream.
|
||||
@@ -48,6 +53,7 @@ public:
|
||||
#endif
|
||||
|
||||
void Put(Ch c) { *stack_.template Push<Ch>() = c; }
|
||||
void PutUnsafe(Ch c) { *stack_.template PushUnsafe<Ch>() = c; }
|
||||
void Flush() {}
|
||||
|
||||
void Clear() { stack_.Clear(); }
|
||||
@@ -57,6 +63,8 @@ public:
|
||||
stack_.ShrinkToFit();
|
||||
stack_.template Pop<Ch>(1);
|
||||
}
|
||||
|
||||
void Reserve(size_t count) { stack_.template Reserve<Ch>(count); }
|
||||
Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }
|
||||
void Pop(size_t count) { stack_.template Pop<Ch>(count); }
|
||||
|
||||
@@ -82,6 +90,16 @@ private:
|
||||
//! String buffer with UTF8 encoding
|
||||
typedef GenericStringBuffer<UTF8<> > StringBuffer;
|
||||
|
||||
template<typename Encoding, typename Allocator>
|
||||
inline void PutReserve(GenericStringBuffer<Encoding, Allocator>& stream, size_t count) {
|
||||
stream.Reserve(count);
|
||||
}
|
||||
|
||||
template<typename Encoding, typename Allocator>
|
||||
inline void PutUnsafe(GenericStringBuffer<Encoding, Allocator>& stream, typename Encoding::Ch c) {
|
||||
stream.PutUnsafe(c);
|
||||
}
|
||||
|
||||
//! Implement specialized version of PutN() with memset() for better performance.
|
||||
template<>
|
||||
inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {
|
||||
@@ -90,4 +108,8 @@ inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {
|
||||
|
||||
RAPIDJSON_NAMESPACE_END
|
||||
|
||||
#if defined(__clang__)
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_STRINGBUFFER_H_
|
||||
|
||||
@@ -23,15 +23,16 @@
|
||||
#include "stringbuffer.h"
|
||||
#include <new> // placement new
|
||||
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(padded)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
||||
//! JSON writer
|
||||
@@ -145,7 +146,7 @@ public:
|
||||
RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray);
|
||||
level_stack_.template Pop<Level>(1);
|
||||
bool ret = WriteEndObject();
|
||||
if (level_stack_.Empty()) // end of json text
|
||||
if (RAPIDJSON_UNLIKELY(level_stack_.Empty())) // end of json text
|
||||
os_->Flush();
|
||||
return ret;
|
||||
}
|
||||
@@ -162,7 +163,7 @@ public:
|
||||
RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray);
|
||||
level_stack_.template Pop<Level>(1);
|
||||
bool ret = WriteEndArray();
|
||||
if (level_stack_.Empty()) // end of json text
|
||||
if (RAPIDJSON_UNLIKELY(level_stack_.Empty())) // end of json text
|
||||
os_->Flush();
|
||||
return ret;
|
||||
}
|
||||
@@ -188,15 +189,18 @@ protected:
|
||||
static const size_t kDefaultLevelDepth = 32;
|
||||
|
||||
bool WriteNull() {
|
||||
os_->Put('n'); os_->Put('u'); os_->Put('l'); os_->Put('l'); return true;
|
||||
PutReserve(*os_, 4);
|
||||
PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true;
|
||||
}
|
||||
|
||||
bool WriteBool(bool b) {
|
||||
if (b) {
|
||||
os_->Put('t'); os_->Put('r'); os_->Put('u'); os_->Put('e');
|
||||
PutReserve(*os_, 4);
|
||||
PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e');
|
||||
}
|
||||
else {
|
||||
os_->Put('f'); os_->Put('a'); os_->Put('l'); os_->Put('s'); os_->Put('e');
|
||||
PutReserve(*os_, 5);
|
||||
PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -204,45 +208,50 @@ protected:
|
||||
bool WriteInt(int i) {
|
||||
char buffer[11];
|
||||
const char* end = internal::i32toa(i, buffer);
|
||||
PutReserve(*os_, static_cast<size_t>(end - buffer));
|
||||
for (const char* p = buffer; p != end; ++p)
|
||||
os_->Put(*p);
|
||||
PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteUint(unsigned u) {
|
||||
char buffer[10];
|
||||
const char* end = internal::u32toa(u, buffer);
|
||||
PutReserve(*os_, static_cast<size_t>(end - buffer));
|
||||
for (const char* p = buffer; p != end; ++p)
|
||||
os_->Put(*p);
|
||||
PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteInt64(int64_t i64) {
|
||||
char buffer[21];
|
||||
const char* end = internal::i64toa(i64, buffer);
|
||||
PutReserve(*os_, static_cast<size_t>(end - buffer));
|
||||
for (const char* p = buffer; p != end; ++p)
|
||||
os_->Put(*p);
|
||||
PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteUint64(uint64_t u64) {
|
||||
char buffer[20];
|
||||
char* end = internal::u64toa(u64, buffer);
|
||||
PutReserve(*os_, static_cast<size_t>(end - buffer));
|
||||
for (char* p = buffer; p != end; ++p)
|
||||
os_->Put(*p);
|
||||
PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteDouble(double d) {
|
||||
char buffer[25];
|
||||
char* end = internal::dtoa(d, buffer);
|
||||
PutReserve(*os_, static_cast<size_t>(end - buffer));
|
||||
for (char* p = buffer; p != end; ++p)
|
||||
os_->Put(*p);
|
||||
PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteString(const Ch* str, SizeType length) {
|
||||
static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
static const typename TargetEncoding::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
static const char escape[256] = {
|
||||
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
@@ -255,22 +264,27 @@ protected:
|
||||
#undef Z16
|
||||
};
|
||||
|
||||
os_->Put('\"');
|
||||
if (TargetEncoding::supportUnicode)
|
||||
PutReserve(*os_, 2 + length * 6); // "\uxxxx..."
|
||||
else
|
||||
PutReserve(*os_, 2 + length * 12); // "\uxxxx\uyyyy..."
|
||||
|
||||
PutUnsafe(*os_, '\"');
|
||||
GenericStringStream<SourceEncoding> is(str);
|
||||
while (is.Tell() < length) {
|
||||
while (RAPIDJSON_LIKELY(is.Tell() < length)) {
|
||||
const Ch c = is.Peek();
|
||||
if (!TargetEncoding::supportUnicode && (unsigned)c >= 0x80) {
|
||||
if (!TargetEncoding::supportUnicode && static_cast<unsigned>(c) >= 0x80) {
|
||||
// Unicode escaping
|
||||
unsigned codepoint;
|
||||
if (!SourceEncoding::Decode(is, &codepoint))
|
||||
if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint)))
|
||||
return false;
|
||||
os_->Put('\\');
|
||||
os_->Put('u');
|
||||
PutUnsafe(*os_, '\\');
|
||||
PutUnsafe(*os_, 'u');
|
||||
if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
|
||||
os_->Put(hexDigits[(codepoint >> 12) & 15]);
|
||||
os_->Put(hexDigits[(codepoint >> 8) & 15]);
|
||||
os_->Put(hexDigits[(codepoint >> 4) & 15]);
|
||||
os_->Put(hexDigits[(codepoint ) & 15]);
|
||||
PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]);
|
||||
PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]);
|
||||
PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]);
|
||||
PutUnsafe(*os_, hexDigits[(codepoint ) & 15]);
|
||||
}
|
||||
else {
|
||||
RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF);
|
||||
@@ -278,34 +292,34 @@ protected:
|
||||
unsigned s = codepoint - 0x010000;
|
||||
unsigned lead = (s >> 10) + 0xD800;
|
||||
unsigned trail = (s & 0x3FF) + 0xDC00;
|
||||
os_->Put(hexDigits[(lead >> 12) & 15]);
|
||||
os_->Put(hexDigits[(lead >> 8) & 15]);
|
||||
os_->Put(hexDigits[(lead >> 4) & 15]);
|
||||
os_->Put(hexDigits[(lead ) & 15]);
|
||||
os_->Put('\\');
|
||||
os_->Put('u');
|
||||
os_->Put(hexDigits[(trail >> 12) & 15]);
|
||||
os_->Put(hexDigits[(trail >> 8) & 15]);
|
||||
os_->Put(hexDigits[(trail >> 4) & 15]);
|
||||
os_->Put(hexDigits[(trail ) & 15]);
|
||||
PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]);
|
||||
PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]);
|
||||
PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]);
|
||||
PutUnsafe(*os_, hexDigits[(lead ) & 15]);
|
||||
PutUnsafe(*os_, '\\');
|
||||
PutUnsafe(*os_, 'u');
|
||||
PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]);
|
||||
PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]);
|
||||
PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]);
|
||||
PutUnsafe(*os_, hexDigits[(trail ) & 15]);
|
||||
}
|
||||
}
|
||||
else if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c]) {
|
||||
else if ((sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast<unsigned char>(c)])) {
|
||||
is.Take();
|
||||
os_->Put('\\');
|
||||
os_->Put(escape[(unsigned char)c]);
|
||||
if (escape[(unsigned char)c] == 'u') {
|
||||
os_->Put('0');
|
||||
os_->Put('0');
|
||||
os_->Put(hexDigits[(unsigned char)c >> 4]);
|
||||
os_->Put(hexDigits[(unsigned char)c & 0xF]);
|
||||
PutUnsafe(*os_, '\\');
|
||||
PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(escape[static_cast<unsigned char>(c)]));
|
||||
if (escape[static_cast<unsigned char>(c)] == 'u') {
|
||||
PutUnsafe(*os_, '0');
|
||||
PutUnsafe(*os_, '0');
|
||||
PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) >> 4]);
|
||||
PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) & 0xF]);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!Transcoder<SourceEncoding, TargetEncoding>::Transcode(is, *os_))
|
||||
if (RAPIDJSON_UNLIKELY(!(Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
|
||||
return false;
|
||||
}
|
||||
os_->Put('\"');
|
||||
PutUnsafe(*os_, '\"');
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -316,7 +330,7 @@ protected:
|
||||
|
||||
void Prefix(Type type) {
|
||||
(void)type;
|
||||
if (level_stack_.GetSize() != 0) { // this value is not at root
|
||||
if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root
|
||||
Level* level = level_stack_.template Top<Level>();
|
||||
if (level->valueCount > 0) {
|
||||
if (level->inArray)
|
||||
@@ -392,4 +406,8 @@ RAPIDJSON_NAMESPACE_END
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_RAPIDJSON_H_
|
||||
|
||||
75
rapidjson.autopkg
Normal file
75
rapidjson.autopkg
Normal file
@@ -0,0 +1,75 @@
|
||||
nuget {
|
||||
//Usage: Write-NuGetPackage rapidjson.autopkg -defines:MYVERSION=1.0.2
|
||||
//Be sure you are running Powershell 3.0 and have the CoApp powershell extensions installed properly.
|
||||
nuspec {
|
||||
id = rapidjson;
|
||||
version : ${MYVERSION};
|
||||
title: "rapidjson";
|
||||
authors: {"https://github.com/miloyip/rapidjson/releases/tag/v1.0.2"};
|
||||
owners: {"@lsantos (github)"};
|
||||
licenseUrl: "https://github.com/miloyip/rapidjson/blob/master/license.txt";
|
||||
projectUrl: "https://github.com/miloyip/rapidjson/";
|
||||
iconUrl: "https://cdn1.iconfinder.com/data/icons/fatcow/32x32/json.png";
|
||||
requireLicenseAcceptance:false;
|
||||
summary: @"A fast JSON parser/generator for C++ with both SAX/DOM style API";
|
||||
|
||||
// if you need to span several lines you can prefix a string with an @ symbol (exactly like c# does).
|
||||
description: @"Rapidjson is an attempt to create the fastest JSON parser and generator.
|
||||
|
||||
- Small but complete. Supports both SAX and DOM style API. SAX parser only a few hundred lines of code.
|
||||
- Fast. In the order of magnitude of strlen(). Optionally supports SSE2/SSE4.2 for acceleration.
|
||||
- Self-contained. Minimal dependency on standard libraries. No BOOST, not even STL.
|
||||
- Compact. Each JSON value is 16 or 20 bytes for 32 or 64-bit machines respectively (excluding text string storage). With the custom memory allocator, parser allocates memory compactly during parsing.
|
||||
- Full RFC4627 compliance. Supports UTF-8, UTF-16 and UTF-32.
|
||||
- Support both in-situ parsing (directly decode strings into the source JSON text) and non-destructive parsing (decode strings into new buffers).
|
||||
- Parse number to int/unsigned/int64_t/uint64_t/double depending on input
|
||||
- Support custom memory allocation. Also, the default memory pool allocator can also be supplied with a user buffer (such as a buffer allocated on user's heap or - programme stack) to minimize allocation.
|
||||
|
||||
As the name implies, rapidjson is inspired by rapidxml.";
|
||||
|
||||
releaseNotes: @"
|
||||
Added
|
||||
Add Value::XXXMember(...) overloads for std::string (#335)
|
||||
|
||||
Fixed
|
||||
Include rapidjson.h for all internal/error headers.
|
||||
Parsing some numbers incorrectly in full-precision mode (kFullPrecisionParseFlag) (#342)
|
||||
Fix alignment of 64bit platforms (#328)
|
||||
Fix MemoryPoolAllocator::Clear() to clear user-buffer (0691502)
|
||||
|
||||
Changed
|
||||
CMakeLists for include as a thirdparty in projects (#334, #337)
|
||||
Change Document::ParseStream() to use stack allocator for Reader (ffbe386)";
|
||||
|
||||
copyright: "Copyright 2015";
|
||||
tags: { native, coapp, JSON, nativepackage };
|
||||
language: en-US;
|
||||
};
|
||||
|
||||
dependencies {
|
||||
packages : {
|
||||
//TODO: Add dependecies here in [pkg.name]/[version] form per newline
|
||||
//zlib/[1.2.8],
|
||||
};
|
||||
}
|
||||
|
||||
// the files that go into the content folders
|
||||
files {
|
||||
#defines {
|
||||
SDK_ROOT = .\;
|
||||
}
|
||||
|
||||
// grab all the files in the include folder
|
||||
// the folder that contains all the .h files will
|
||||
// automatically get added to the Includes path.
|
||||
nestedinclude += {
|
||||
#destination = ${d_include}rapidjson;
|
||||
"${SDK_ROOT}include\rapidjson\**\*.h"
|
||||
};
|
||||
};
|
||||
|
||||
targets {
|
||||
// We're trying to be standard about these sorts of thing. (Will help with config.h later :D)
|
||||
//Defines += HAS_EQCORE;
|
||||
};
|
||||
}
|
||||
14
readme.md
14
readme.md
@@ -31,15 +31,15 @@ Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights
|
||||
|
||||
RapidJSON is a JSON parser and generator for C++. It was inspired by [RapidXml](http://rapidxml.sourceforge.net/).
|
||||
|
||||
* RapidJSON is small but complete. It supports both SAX and DOM style API. The SAX parser is only a half thousand lines of code.
|
||||
* RapidJSON is **small** but **complete**. It supports both SAX and DOM style API. The SAX parser is only a half thousand lines of code.
|
||||
|
||||
* RapidJSON is fast. Its performance can be comparable to `strlen()`. It also optionally supports SSE2/SSE4.2 for acceleration.
|
||||
* RapidJSON is **fast**. Its performance can be comparable to `strlen()`. It also optionally supports SSE2/SSE4.2 for acceleration.
|
||||
|
||||
* RapidJSON is self-contained. It does not depend on external libraries such as BOOST. It even does not depend on STL.
|
||||
* RapidJSON is **self-contained** and **header-only**. It does not depend on external libraries such as BOOST. It even does not depend on STL.
|
||||
|
||||
* RapidJSON is memory friendly. Each JSON value occupies exactly 16/20 bytes for most 32/64-bit machines (excluding text string). By default it uses a fast memory allocator, and the parser allocates memory compactly during parsing.
|
||||
* RapidJSON is **memory-friendly**. Each JSON value occupies exactly 16/20 bytes for most 32/64-bit machines (excluding text string). By default it uses a fast memory allocator, and the parser allocates memory compactly during parsing.
|
||||
|
||||
* RapidJSON is Unicode friendly. It supports UTF-8, UTF-16, UTF-32 (LE & BE), and their detection, validation and transcoding internally. For example, you can read a UTF-8 file and let RapidJSON transcode the JSON strings into UTF-16 in the DOM. It also supports surrogates and "\u0000" (null character).
|
||||
* RapidJSON is **Unicode-friendly**. It supports UTF-8, UTF-16, UTF-32 (LE & BE), and their detection, validation and transcoding internally. For example, you can read a UTF-8 file and let RapidJSON transcode the JSON strings into UTF-16 in the DOM. It also supports surrogates and "\u0000" (null character).
|
||||
|
||||
More features can be read [here](doc/features.md).
|
||||
|
||||
@@ -63,9 +63,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 uses following software as its dependencies:
|
||||
* [CMake](http://www.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)[googletest](https://code.google.com/p/googletest/) for unit and performance testing
|
||||
* (optional)[googletest](https://github.com/google/googletest) for unit and performance testing
|
||||
|
||||
To generate user documentation and run tests please proceed with the steps below:
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ IF(GTESTSRC_FOUND)
|
||||
endif()
|
||||
|
||||
add_subdirectory(${GTEST_SOURCE_DIR} ${CMAKE_BINARY_DIR}/googletest)
|
||||
include_directories(${GTEST_INCLUDE_DIR})
|
||||
include_directories(SYSTEM ${GTEST_INCLUDE_DIR})
|
||||
|
||||
set(TEST_LIBRARIES gtest gtest_main)
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
PerfTest() : filename_(), json_(), length_(), whitespace_(), whitespace_length_() {}
|
||||
|
||||
virtual void SetUp() {
|
||||
|
||||
{
|
||||
const char *paths[] = {
|
||||
"data/sample.json",
|
||||
"bin/data/sample.json",
|
||||
@@ -73,6 +73,7 @@ public:
|
||||
"../../bin/data/sample.json",
|
||||
"../../../bin/data/sample.json"
|
||||
};
|
||||
|
||||
FILE *fp = 0;
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
|
||||
fp = fopen(filename_ = paths[i], "rb");
|
||||
@@ -88,8 +89,10 @@ public:
|
||||
ASSERT_EQ(length_, fread(json_, 1, length_, fp));
|
||||
json_[length_] = '\0';
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
// whitespace test
|
||||
{
|
||||
whitespace_length_ = 1024 * 1024;
|
||||
whitespace_ = (char *)malloc(whitespace_length_ + 4);
|
||||
char *p = whitespace_;
|
||||
@@ -105,11 +108,55 @@ public:
|
||||
*p++ = '\0';
|
||||
}
|
||||
|
||||
// types test
|
||||
{
|
||||
const char *typespaths[] = {
|
||||
"data/types",
|
||||
"bin/types",
|
||||
"../bin/types",
|
||||
"../../bin/types/",
|
||||
"../../../bin/types"
|
||||
};
|
||||
|
||||
const char* typesfilenames[] = {
|
||||
"booleans.json",
|
||||
"floats.json",
|
||||
"guids.json",
|
||||
"integers.json",
|
||||
"mixed.json",
|
||||
"nulls.json",
|
||||
"paragraphs.json"
|
||||
};
|
||||
|
||||
for (size_t j = 0; j < sizeof(typesfilenames) / sizeof(typesfilenames[0]); j++) {
|
||||
types_[j] = 0;
|
||||
for (size_t i = 0; i < sizeof(typespaths) / sizeof(typespaths[0]); i++) {
|
||||
char filename[256];
|
||||
sprintf(filename, "%s/%s", typespaths[i], typesfilenames[j]);
|
||||
if (FILE* fp = fopen(filename, "rb")) {
|
||||
fseek(fp, 0, SEEK_END);
|
||||
typesLength_[j] = (size_t)ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
types_[j] = (char*)malloc(typesLength_[j] + 1);
|
||||
ASSERT_EQ(typesLength_[j], fread(types_[j], 1, typesLength_[j], fp));
|
||||
types_[j][typesLength_[j]] = '\0';
|
||||
fclose(fp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
free(json_);
|
||||
free(whitespace_);
|
||||
json_ = 0;
|
||||
whitespace_ = 0;
|
||||
for (size_t i = 0; i < 7; i++) {
|
||||
free(types_[i]);
|
||||
types_[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -122,6 +169,8 @@ protected:
|
||||
size_t length_;
|
||||
char *whitespace_;
|
||||
size_t whitespace_length_;
|
||||
char *types_[7];
|
||||
size_t typesLength_[7];
|
||||
|
||||
static const size_t kTrialCount = 1000;
|
||||
};
|
||||
|
||||
@@ -45,7 +45,10 @@ public:
|
||||
temp_ = (char *)malloc(length_ + 1);
|
||||
|
||||
// Parse as a document
|
||||
EXPECT_FALSE(doc_.Parse(json_).IsNull());
|
||||
EXPECT_FALSE(doc_.Parse(json_).HasParseError());
|
||||
|
||||
for (size_t i = 0; i < 7; i++)
|
||||
EXPECT_FALSE(typesDoc_[i].Parse(types_[i]).HasParseError());
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
@@ -60,6 +63,7 @@ private:
|
||||
protected:
|
||||
char *temp_;
|
||||
Document doc_;
|
||||
Document typesDoc_[7];
|
||||
};
|
||||
|
||||
TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler)) {
|
||||
@@ -91,6 +95,35 @@ TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler)) {
|
||||
}
|
||||
}
|
||||
|
||||
#define TEST_TYPED(index, Name)\
|
||||
TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_##Name)) {\
|
||||
for (size_t i = 0; i < kTrialCount * 10; i++) {\
|
||||
StringStream s(types_[index]);\
|
||||
BaseReaderHandler<> h;\
|
||||
Reader reader;\
|
||||
EXPECT_TRUE(reader.Parse(s, h));\
|
||||
}\
|
||||
}\
|
||||
TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler_##Name)) {\
|
||||
for (size_t i = 0; i < kTrialCount * 10; i++) {\
|
||||
memcpy(temp_, types_[index], typesLength_[index] + 1);\
|
||||
InsituStringStream s(temp_);\
|
||||
BaseReaderHandler<> h;\
|
||||
Reader reader;\
|
||||
EXPECT_TRUE(reader.Parse<kParseInsituFlag>(s, h));\
|
||||
}\
|
||||
}
|
||||
|
||||
TEST_TYPED(0, Booleans)
|
||||
TEST_TYPED(1, Floats)
|
||||
TEST_TYPED(2, Guids)
|
||||
TEST_TYPED(3, Integers)
|
||||
TEST_TYPED(4, Mixed)
|
||||
TEST_TYPED(5, Nulls)
|
||||
TEST_TYPED(6, Paragraphs)
|
||||
|
||||
#undef TEST_TYPED
|
||||
|
||||
TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_FullPrecision)) {
|
||||
for (size_t i = 0; i < kTrialCount; i++) {
|
||||
StringStream s(json_);
|
||||
@@ -250,8 +283,10 @@ TEST_F(RapidJson, DocumentAccept) {
|
||||
}
|
||||
|
||||
struct NullStream {
|
||||
typedef char Ch;
|
||||
|
||||
NullStream() /*: length_(0)*/ {}
|
||||
void Put(char) { /*++length_;*/ }
|
||||
void Put(Ch) { /*++length_;*/ }
|
||||
void Flush() {}
|
||||
//size_t length_;
|
||||
};
|
||||
@@ -278,6 +313,27 @@ TEST_F(RapidJson, Writer_StringBuffer) {
|
||||
}
|
||||
}
|
||||
|
||||
#define TEST_TYPED(index, Name)\
|
||||
TEST_F(RapidJson, Writer_StringBuffer_##Name) {\
|
||||
for (size_t i = 0; i < kTrialCount * 10; i++) {\
|
||||
StringBuffer s(0, 1024 * 1024);\
|
||||
Writer<StringBuffer> writer(s);\
|
||||
typesDoc_[index].Accept(writer);\
|
||||
const char* str = s.GetString();\
|
||||
(void)str;\
|
||||
}\
|
||||
}
|
||||
|
||||
TEST_TYPED(0, Booleans)
|
||||
TEST_TYPED(1, Floats)
|
||||
TEST_TYPED(2, Guids)
|
||||
TEST_TYPED(3, Integers)
|
||||
TEST_TYPED(4, Mixed)
|
||||
TEST_TYPED(5, Nulls)
|
||||
TEST_TYPED(6, Paragraphs)
|
||||
|
||||
#undef TEST_TYPED
|
||||
|
||||
TEST_F(RapidJson, PrettyWriter_StringBuffer) {
|
||||
for (size_t i = 0; i < kTrialCount; i++) {
|
||||
StringBuffer s(0, 2048 * 1024);
|
||||
@@ -357,4 +413,10 @@ TEST_F(RapidJson, SIMD_SUFFIX(ReaderParse_DummyHandler_FileReadStream)) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(RapidJson, StringBuffer) {
|
||||
StringBuffer sb;
|
||||
for (int i = 0; i < 32 * 1024 * 1024; i++)
|
||||
sb.Put(i & 0x7f);
|
||||
}
|
||||
|
||||
#endif // TEST_RAPIDJSON
|
||||
|
||||
@@ -24,7 +24,7 @@ set(UNITTEST_SOURCES
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal")
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough -Weverything")
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
|
||||
endif()
|
||||
|
||||
@@ -22,21 +22,21 @@ template <typename Allocator>
|
||||
void TestAllocator(Allocator& a) {
|
||||
EXPECT_TRUE(a.Malloc(0) == 0);
|
||||
|
||||
uint8_t* p = (uint8_t*)a.Malloc(100);
|
||||
uint8_t* p = static_cast<uint8_t*>(a.Malloc(100));
|
||||
EXPECT_TRUE(p != 0);
|
||||
for (size_t i = 0; i < 100; i++)
|
||||
p[i] = (uint8_t)i;
|
||||
p[i] = static_cast<uint8_t>(i);
|
||||
|
||||
// Expand
|
||||
uint8_t* q = (uint8_t*)a.Realloc(p, 100, 200);
|
||||
uint8_t* q = static_cast<uint8_t*>(a.Realloc(p, 100, 200));
|
||||
EXPECT_TRUE(q != 0);
|
||||
for (size_t i = 0; i < 100; i++)
|
||||
EXPECT_EQ(i, q[i]);
|
||||
for (size_t i = 100; i < 200; i++)
|
||||
q[i] = (uint8_t)i;
|
||||
q[i] = static_cast<uint8_t>(i);
|
||||
|
||||
// Shrink
|
||||
uint8_t *r = (uint8_t*)a.Realloc(q, 200, 150);
|
||||
uint8_t *r = static_cast<uint8_t*>(a.Realloc(q, 200, 150));
|
||||
EXPECT_TRUE(r != 0);
|
||||
for (size_t i = 0; i < 150; i++)
|
||||
EXPECT_EQ(i, r[i]);
|
||||
@@ -56,8 +56,28 @@ TEST(Allocator, MemoryPoolAllocator) {
|
||||
MemoryPoolAllocator<> a;
|
||||
TestAllocator(a);
|
||||
|
||||
for (int i = 1; i < 1000; i++) {
|
||||
for (size_t i = 1; i < 1000; i++) {
|
||||
EXPECT_TRUE(a.Malloc(i) != 0);
|
||||
EXPECT_LE(a.Size(), a.Capacity());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Allocator, Alignment) {
|
||||
#if RAPIDJSON_64BIT == 1
|
||||
EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000000, 0x00000000), RAPIDJSON_ALIGN(0));
|
||||
for (uint64_t i = 1; i < 8; i++) {
|
||||
EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000000, 0x00000008), RAPIDJSON_ALIGN(i));
|
||||
EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000000, 0x00000010), RAPIDJSON_ALIGN(RAPIDJSON_UINT64_C2(0x00000000, 0x00000008) + i));
|
||||
EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000001, 0x00000000), RAPIDJSON_ALIGN(RAPIDJSON_UINT64_C2(0x00000000, 0xFFFFFFF8) + i));
|
||||
EXPECT_EQ(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFF8), RAPIDJSON_ALIGN(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFF0) + i));
|
||||
}
|
||||
#else
|
||||
EXPECT_EQ(0u, RAPIDJSON_ALIGN(0u));
|
||||
for (uint32_t i = 1; i < 4; i++) {
|
||||
EXPECT_EQ(4u, RAPIDJSON_ALIGN(i));
|
||||
EXPECT_EQ(8u, RAPIDJSON_ALIGN(4u + i));
|
||||
EXPECT_EQ(0xFFFFFFF8u, RAPIDJSON_ALIGN(0xFFFFFFF4u + i));
|
||||
EXPECT_EQ(0xFFFFFFFCu, RAPIDJSON_ALIGN(0xFFFFFFF8u + i));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -21,6 +21,12 @@
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
||||
RAPIDJSON_DIAG_OFF(missing-variable-declarations)
|
||||
#endif
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
template <typename DocumentType>
|
||||
@@ -28,6 +34,7 @@ void ParseCheck(DocumentType& doc) {
|
||||
typedef typename DocumentType::ValueType ValueType;
|
||||
|
||||
EXPECT_FALSE(doc.HasParseError());
|
||||
EXPECT_TRUE(static_cast<ParseResult>(doc));
|
||||
|
||||
EXPECT_TRUE(doc.IsObject());
|
||||
|
||||
@@ -62,8 +69,8 @@ void ParseCheck(DocumentType& doc) {
|
||||
const ValueType& a = doc["a"];
|
||||
EXPECT_TRUE(a.IsArray());
|
||||
EXPECT_EQ(4u, a.Size());
|
||||
for (SizeType i = 0; i < 4; i++)
|
||||
EXPECT_EQ(i + 1, a[i].GetUint());
|
||||
for (SizeType j = 0; j < 4; j++)
|
||||
EXPECT_EQ(j + 1, a[j].GetUint());
|
||||
}
|
||||
|
||||
template <typename Allocator, typename StackAllocator>
|
||||
@@ -95,17 +102,37 @@ TEST(Document, Parse) {
|
||||
ParseTest<CrtAllocator, CrtAllocator>();
|
||||
}
|
||||
|
||||
TEST(Document, UnchangedOnParseError) {
|
||||
Document doc;
|
||||
doc.SetArray().PushBack(0, doc.GetAllocator());
|
||||
|
||||
ParseResult err = doc.Parse("{]");
|
||||
EXPECT_TRUE(doc.HasParseError());
|
||||
EXPECT_EQ(err.Code(), doc.GetParseError());
|
||||
EXPECT_EQ(err.Offset(), doc.GetErrorOffset());
|
||||
EXPECT_TRUE(doc.IsArray());
|
||||
EXPECT_EQ(doc.Size(), 1u);
|
||||
|
||||
err = doc.Parse("{}");
|
||||
EXPECT_FALSE(doc.HasParseError());
|
||||
EXPECT_FALSE(err.IsError());
|
||||
EXPECT_EQ(err.Code(), doc.GetParseError());
|
||||
EXPECT_EQ(err.Offset(), doc.GetErrorOffset());
|
||||
EXPECT_TRUE(doc.IsObject());
|
||||
EXPECT_EQ(doc.MemberCount(), 0u);
|
||||
}
|
||||
|
||||
static FILE* OpenEncodedFile(const char* filename) {
|
||||
const char *paths[] = {
|
||||
"encodings/%s",
|
||||
"bin/encodings/%s",
|
||||
"../bin/encodings/%s",
|
||||
"../../bin/encodings/%s",
|
||||
"../../../bin/encodings/%s"
|
||||
"encodings",
|
||||
"bin/encodings",
|
||||
"../bin/encodings",
|
||||
"../../bin/encodings",
|
||||
"../../../bin/encodings"
|
||||
};
|
||||
char buffer[1024];
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
|
||||
sprintf(buffer, paths[i], filename);
|
||||
sprintf(buffer, "%s/%s", paths[i], filename);
|
||||
FILE *fp = fopen(buffer, "rb");
|
||||
if (fp)
|
||||
return fp;
|
||||
@@ -136,22 +163,22 @@ TEST(Document, ParseStream_EncodedInputStream) {
|
||||
StringBuffer bos;
|
||||
typedef EncodedOutputStream<UTF8<>, StringBuffer> OutputStream;
|
||||
OutputStream eos(bos, false); // Not writing BOM
|
||||
{
|
||||
Writer<OutputStream, UTF16<>, UTF8<> > writer(eos);
|
||||
d.Accept(writer);
|
||||
}
|
||||
|
||||
{
|
||||
// Condense the original file and compare.
|
||||
FILE *fp = OpenEncodedFile("utf8.json");
|
||||
fp = OpenEncodedFile("utf8.json");
|
||||
FileReadStream is(fp, buffer, sizeof(buffer));
|
||||
Reader reader;
|
||||
StringBuffer bos2;
|
||||
Writer<StringBuffer> writer(bos2);
|
||||
reader.Parse(is, writer);
|
||||
Writer<StringBuffer> writer2(bos2);
|
||||
reader.Parse(is, writer2);
|
||||
fclose(fp);
|
||||
|
||||
EXPECT_EQ(bos.GetSize(), bos2.GetSize());
|
||||
EXPECT_EQ(0, memcmp(bos.GetString(), bos2.GetString(), bos2.GetSize()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Document, ParseStream_AutoUTFInputStream) {
|
||||
@@ -178,19 +205,17 @@ TEST(Document, ParseStream_AutoUTFInputStream) {
|
||||
Writer<StringBuffer> writer(bos);
|
||||
d.Accept(writer);
|
||||
|
||||
{
|
||||
// Condense the original file and compare.
|
||||
FILE *fp = OpenEncodedFile("utf8.json");
|
||||
fp = OpenEncodedFile("utf8.json");
|
||||
FileReadStream is(fp, buffer, sizeof(buffer));
|
||||
Reader reader;
|
||||
StringBuffer bos2;
|
||||
Writer<StringBuffer> writer(bos2);
|
||||
reader.Parse(is, writer);
|
||||
Writer<StringBuffer> writer2(bos2);
|
||||
reader.Parse(is, writer2);
|
||||
fclose(fp);
|
||||
|
||||
EXPECT_EQ(bos.GetSize(), bos2.GetSize());
|
||||
EXPECT_EQ(0, memcmp(bos.GetString(), bos2.GetString(), bos2.GetSize()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Document, Swap) {
|
||||
@@ -242,12 +267,16 @@ TEST(Document, Swap) {
|
||||
struct OutputStringStream : public std::ostringstream {
|
||||
typedef char Ch;
|
||||
|
||||
virtual ~OutputStringStream();
|
||||
|
||||
void Put(char c) {
|
||||
put(c);
|
||||
}
|
||||
void Flush() {}
|
||||
};
|
||||
|
||||
OutputStringStream::~OutputStringStream() {}
|
||||
|
||||
TEST(Document, AcceptWriter) {
|
||||
Document doc;
|
||||
doc.Parse(" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ");
|
||||
@@ -305,6 +334,8 @@ TEST(Document, UTF16_Document) {
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
|
||||
#if 0 // Many old compiler does not support these. Turn it off temporaily.
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
TEST(Document, Traits) {
|
||||
@@ -342,6 +373,8 @@ TEST(Document, Traits) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <typename Allocator>
|
||||
struct DocumentMove: public ::testing::Test {
|
||||
};
|
||||
@@ -366,7 +399,7 @@ TYPED_TEST(DocumentMove, MoveConstructor) {
|
||||
EXPECT_TRUE(a.IsNull());
|
||||
EXPECT_TRUE(b.IsArray());
|
||||
EXPECT_EQ(3u, b.Size());
|
||||
EXPECT_EQ(&a.GetAllocator(), (void*)0);
|
||||
EXPECT_THROW(a.GetAllocator(), AssertException);
|
||||
EXPECT_EQ(&b.GetAllocator(), &allocator);
|
||||
|
||||
b.Parse("{\"Foo\": \"Bar\", \"Baz\": 42}");
|
||||
@@ -379,7 +412,7 @@ TYPED_TEST(DocumentMove, MoveConstructor) {
|
||||
EXPECT_TRUE(b.IsNull());
|
||||
EXPECT_TRUE(c.IsObject());
|
||||
EXPECT_EQ(2u, c.MemberCount());
|
||||
EXPECT_EQ(&b.GetAllocator(), (void*)0);
|
||||
EXPECT_THROW(b.GetAllocator(), AssertException);
|
||||
EXPECT_EQ(&c.GetAllocator(), &allocator);
|
||||
}
|
||||
|
||||
@@ -460,7 +493,7 @@ TYPED_TEST(DocumentMove, MoveAssignment) {
|
||||
EXPECT_TRUE(a.IsNull());
|
||||
EXPECT_TRUE(b.IsArray());
|
||||
EXPECT_EQ(3u, b.Size());
|
||||
EXPECT_EQ(&a.GetAllocator(), (void*)0);
|
||||
EXPECT_THROW(a.GetAllocator(), AssertException);
|
||||
EXPECT_EQ(&b.GetAllocator(), &allocator);
|
||||
|
||||
b.Parse("{\"Foo\": \"Bar\", \"Baz\": 42}");
|
||||
@@ -474,7 +507,7 @@ TYPED_TEST(DocumentMove, MoveAssignment) {
|
||||
EXPECT_TRUE(b.IsNull());
|
||||
EXPECT_TRUE(c.IsObject());
|
||||
EXPECT_EQ(2u, c.MemberCount());
|
||||
EXPECT_EQ(&b.GetAllocator(), (void*)0);
|
||||
EXPECT_THROW(b.GetAllocator(), AssertException);
|
||||
EXPECT_EQ(&c.GetAllocator(), &allocator);
|
||||
}
|
||||
|
||||
@@ -550,3 +583,7 @@ TYPED_TEST(DocumentMove, MoveAssignmentStack) {
|
||||
// Document d2;
|
||||
// d1 = d2;
|
||||
//}
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,7 @@ using namespace rapidjson;
|
||||
class EncodedStreamTest : public ::testing::Test {
|
||||
public:
|
||||
EncodedStreamTest() : json_(), length_() {}
|
||||
virtual ~EncodedStreamTest();
|
||||
|
||||
virtual void SetUp() {
|
||||
json_ = ReadFile("utf8.json", true, &length_);
|
||||
@@ -42,15 +43,15 @@ private:
|
||||
protected:
|
||||
static FILE* Open(const char* filename) {
|
||||
const char *paths[] = {
|
||||
"encodings/%s",
|
||||
"bin/encodings/%s",
|
||||
"../bin/encodings/%s",
|
||||
"../../bin/encodings/%s",
|
||||
"../../../bin/encodings/%s"
|
||||
"encodings",
|
||||
"bin/encodings",
|
||||
"../bin/encodings",
|
||||
"../../bin/encodings",
|
||||
"../../../bin/encodings"
|
||||
};
|
||||
char buffer[1024];
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
|
||||
sprintf(buffer, paths[i], filename);
|
||||
sprintf(buffer, "%s/%s", paths[i], filename);
|
||||
FILE *fp = fopen(buffer, "rb");
|
||||
if (fp)
|
||||
return fp;
|
||||
@@ -67,9 +68,9 @@ protected:
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
*outLength = (size_t)ftell(fp);
|
||||
*outLength = static_cast<size_t>(ftell(fp));
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char* buffer = (char*)malloc(*outLength + 1);
|
||||
char* buffer = static_cast<char*>(malloc(*outLength + 1));
|
||||
size_t readLength = fread(buffer, 1, *outLength, fp);
|
||||
buffer[readLength] = '\0';
|
||||
fclose(fp);
|
||||
@@ -248,6 +249,8 @@ protected:
|
||||
size_t length_;
|
||||
};
|
||||
|
||||
EncodedStreamTest::~EncodedStreamTest() {}
|
||||
|
||||
TEST_F(EncodedStreamTest, EncodedInputStream) {
|
||||
TestEncodedInputStream<UTF8<>, UTF8<> >("utf8.json");
|
||||
TestEncodedInputStream<UTF8<>, UTF8<> >("utf8bom.json");
|
||||
|
||||
@@ -240,7 +240,6 @@ static const unsigned kCodepointRanges[] = {
|
||||
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
||||
|
||||
#define UTF8_ACCEPT 0u
|
||||
#define UTF8_REJECT 12u
|
||||
|
||||
static const unsigned char utf8d[] = {
|
||||
// The first part of the table maps bytes to character classes that
|
||||
@@ -298,7 +297,7 @@ TEST(EncodingsTest, UTF8) {
|
||||
|
||||
unsigned decodedCount = 0;
|
||||
for (const char* s = encodedStr; *s; ++s)
|
||||
if (!decode(&state, &decodedCodepoint, (unsigned char)*s)) {
|
||||
if (!decode(&state, &decodedCodepoint, static_cast<unsigned char>(*s))) {
|
||||
EXPECT_EQ(codepoint, decodedCodepoint);
|
||||
decodedCount++;
|
||||
}
|
||||
@@ -355,7 +354,7 @@ TEST(EncodingsTest, UTF16) {
|
||||
unsigned state = 0;
|
||||
UTF16<>::Ch buffer[3], *p = &buffer[0];
|
||||
for (const char* s = utf8os.GetString(); *s; ++s) {
|
||||
if (!decode(&state, &decodedCodepoint, (unsigned char)*s))
|
||||
if (!decode(&state, &decodedCodepoint, static_cast<unsigned char>(*s)))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ using namespace rapidjson;
|
||||
class FileStreamTest : public ::testing::Test {
|
||||
public:
|
||||
FileStreamTest() : filename_(), json_(), length_() {}
|
||||
virtual ~FileStreamTest();
|
||||
|
||||
virtual void SetUp() {
|
||||
const char *paths[] = {
|
||||
@@ -42,9 +43,9 @@ public:
|
||||
ASSERT_TRUE(fp != 0);
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
length_ = (size_t)ftell(fp);
|
||||
length_ = static_cast<size_t>(ftell(fp));
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
json_ = (char*)malloc(length_ + 1);
|
||||
json_ = static_cast<char*>(malloc(length_ + 1));
|
||||
size_t readLength = fread(json_, 1, length_, fp);
|
||||
json_[readLength] = '\0';
|
||||
fclose(fp);
|
||||
@@ -65,6 +66,8 @@ protected:
|
||||
size_t length_;
|
||||
};
|
||||
|
||||
FileStreamTest::~FileStreamTest() {}
|
||||
|
||||
TEST_F(FileStreamTest, FileReadStream) {
|
||||
FILE *fp = fopen(filename_, "rb");
|
||||
ASSERT_TRUE(fp != 0);
|
||||
|
||||
@@ -30,28 +30,28 @@ template <>
|
||||
struct Traits<uint32_t> {
|
||||
enum { kBufferSize = 11 };
|
||||
enum { kMaxDigit = 10 };
|
||||
static uint32_t Negate(uint32_t x) { return x; };
|
||||
static uint32_t Negate(uint32_t x) { return x; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Traits<int32_t> {
|
||||
enum { kBufferSize = 12 };
|
||||
enum { kMaxDigit = 10 };
|
||||
static int32_t Negate(int32_t x) { return -x; };
|
||||
static int32_t Negate(int32_t x) { return -x; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Traits<uint64_t> {
|
||||
enum { kBufferSize = 21 };
|
||||
enum { kMaxDigit = 20 };
|
||||
static uint64_t Negate(uint64_t x) { return x; };
|
||||
static uint64_t Negate(uint64_t x) { return x; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Traits<int64_t> {
|
||||
enum { kBufferSize = 22 };
|
||||
enum { kMaxDigit = 20 };
|
||||
static int64_t Negate(int64_t x) { return -x; };
|
||||
static int64_t Negate(int64_t x) { return -x; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
||||
@@ -20,16 +20,16 @@ using namespace rapidjson;
|
||||
|
||||
static char* ReadFile(const char* filename, size_t& length) {
|
||||
const char *paths[] = {
|
||||
"jsonchecker/%s",
|
||||
"bin/jsonchecker/%s",
|
||||
"../bin/jsonchecker/%s",
|
||||
"../../bin/jsonchecker/%s",
|
||||
"../../../bin/jsonchecker/%s"
|
||||
"jsonchecker",
|
||||
"bin/jsonchecker",
|
||||
"../bin/jsonchecker",
|
||||
"../../bin/jsonchecker",
|
||||
"../../../bin/jsonchecker"
|
||||
};
|
||||
char buffer[1024];
|
||||
FILE *fp = 0;
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
|
||||
sprintf(buffer, paths[i], filename);
|
||||
sprintf(buffer, "%s/%s", paths[i], filename);
|
||||
fp = fopen(buffer, "rb");
|
||||
if (fp)
|
||||
break;
|
||||
@@ -39,9 +39,9 @@ static char* ReadFile(const char* filename, size_t& length) {
|
||||
return 0;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
length = (size_t)ftell(fp);
|
||||
length = static_cast<size_t>(ftell(fp));
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char* json = (char*)malloc(length + 1);
|
||||
char* json = static_cast<char*>(malloc(length + 1));
|
||||
size_t readLength = fread(json, 1, length, fp);
|
||||
json[readLength] = '\0';
|
||||
fclose(fp);
|
||||
@@ -68,10 +68,10 @@ TEST(JsonChecker, Reader) {
|
||||
}
|
||||
|
||||
GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak)
|
||||
document.Parse((const char*)json);
|
||||
document.Parse(json);
|
||||
EXPECT_TRUE(document.HasParseError());
|
||||
|
||||
document.Parse<kParseIterativeFlag>((const char*)json);
|
||||
document.Parse<kParseIterativeFlag>(json);
|
||||
EXPECT_TRUE(document.HasParseError());
|
||||
|
||||
free(json);
|
||||
@@ -88,10 +88,10 @@ TEST(JsonChecker, Reader) {
|
||||
}
|
||||
|
||||
GenericDocument<UTF8<>, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak)
|
||||
document.Parse((const char*)json);
|
||||
document.Parse(json);
|
||||
EXPECT_FALSE(document.HasParseError());
|
||||
|
||||
document.Parse<kParseIterativeFlag>((const char*)json);
|
||||
document.Parse<kParseIterativeFlag>(json);
|
||||
EXPECT_FALSE(document.HasParseError());
|
||||
|
||||
free(json);
|
||||
|
||||
@@ -312,7 +312,7 @@ TEST(Pointer, Parse_URIFragment) {
|
||||
GenericPointer<GenericValue<UTF16<> > > p(L"#/%C2%A2");
|
||||
EXPECT_TRUE(p.IsValid());
|
||||
EXPECT_EQ(1u, p.GetTokenCount());
|
||||
EXPECT_EQ(0x00A2, p.GetTokens()[0].name[0]);
|
||||
EXPECT_EQ(static_cast<UTF16<>::Ch>(0x00A2), p.GetTokens()[0].name[0]);
|
||||
EXPECT_EQ(1u, p.GetTokens()[0].length);
|
||||
}
|
||||
|
||||
@@ -321,7 +321,7 @@ TEST(Pointer, Parse_URIFragment) {
|
||||
GenericPointer<GenericValue<UTF16<> > > p(L"#/%E2%82%AC");
|
||||
EXPECT_TRUE(p.IsValid());
|
||||
EXPECT_EQ(1u, p.GetTokenCount());
|
||||
EXPECT_EQ(0x20AC, p.GetTokens()[0].name[0]);
|
||||
EXPECT_EQ(static_cast<UTF16<>::Ch>(0x20AC), p.GetTokens()[0].name[0]);
|
||||
EXPECT_EQ(1u, p.GetTokens()[0].length);
|
||||
}
|
||||
|
||||
@@ -1462,3 +1462,38 @@ TEST(Pointer, Ambiguity) {
|
||||
EXPECT_EQ(456, Pointer("/0/1").Get(d)->GetInt());
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/miloyip/rapidjson/issues/483
|
||||
namespace myjson {
|
||||
|
||||
class MyAllocator
|
||||
{
|
||||
public:
|
||||
static const bool kNeedFree = true;
|
||||
void * Malloc(size_t _size) { return malloc(_size); }
|
||||
void * Realloc(void *_org_p, size_t _org_size, size_t _new_size) { (void)_org_size; return realloc(_org_p, _new_size); }
|
||||
static void Free(void *_p) { return free(_p); }
|
||||
};
|
||||
|
||||
typedef rapidjson::GenericDocument<
|
||||
rapidjson::UTF8<>,
|
||||
rapidjson::MemoryPoolAllocator< MyAllocator >,
|
||||
MyAllocator
|
||||
> Document;
|
||||
|
||||
typedef rapidjson::GenericPointer<
|
||||
::myjson::Document::ValueType,
|
||||
MyAllocator
|
||||
> Pointer;
|
||||
|
||||
typedef ::myjson::Document::ValueType Value;
|
||||
|
||||
}
|
||||
|
||||
TEST(Pointer, Issue483) {
|
||||
std::string mystr, path;
|
||||
myjson::Document document;
|
||||
myjson::Value value(rapidjson::kStringType);
|
||||
value.SetString(mystr.c_str(), static_cast<SizeType>(mystr.length()), document.GetAllocator());
|
||||
myjson::Pointer(path.c_str()).Set(document, value, document.GetAllocator());
|
||||
}
|
||||
|
||||
@@ -149,9 +149,9 @@ TEST(PrettyWriter, FileWriteStream) {
|
||||
|
||||
fp = fopen(filename, "rb");
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size_t size = (size_t)ftell(fp);
|
||||
size_t size = static_cast<size_t>(ftell(fp));
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char* json = (char*)malloc(size + 1);
|
||||
char* json = static_cast<char*>(malloc(size + 1));
|
||||
size_t readLength = fread(json, 1, size, fp);
|
||||
json[readLength] = '\0';
|
||||
fclose(fp);
|
||||
|
||||
@@ -25,6 +25,13 @@ using namespace rapidjson;
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
RAPIDJSON_DIAG_OFF(float-equal)
|
||||
RAPIDJSON_DIAG_OFF(missing-noreturn)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(variadic-macros)
|
||||
RAPIDJSON_DIAG_OFF(c++98-compat-pedantic)
|
||||
#endif
|
||||
|
||||
template<bool expect>
|
||||
@@ -159,12 +166,12 @@ TEST(Reader, ParseNumber_Integer) {
|
||||
u.u |= r();
|
||||
|
||||
char buffer[32];
|
||||
if (u.u >= 4294967296ULL) {
|
||||
if (u.u > uint64_t(4294967295u)) {
|
||||
*internal::u64toa(u.u, buffer) = '\0';
|
||||
TEST_INTEGER(ParseUint64Handler, buffer, u.u);
|
||||
}
|
||||
|
||||
if (u.i <= -2147483649LL) {
|
||||
if (u.i < -int64_t(2147483648u)) {
|
||||
*internal::i64toa(u.i, buffer) = '\0';
|
||||
TEST_INTEGER(ParseInt64Handler, buffer, u.i);
|
||||
}
|
||||
@@ -403,7 +410,7 @@ TEST(Reader, ParseNumber_NormalPrecisionError) {
|
||||
a = h.actual_;
|
||||
uint64_t bias1 = e.ToBias();
|
||||
uint64_t bias2 = a.ToBias();
|
||||
double ulp = bias1 >= bias2 ? bias1 - bias2 : bias2 - bias1;
|
||||
double ulp = static_cast<double>(bias1 >= bias2 ? bias1 - bias2 : bias2 - bias1);
|
||||
ulpMax = std::max(ulpMax, ulp);
|
||||
ulpSum += ulp;
|
||||
}
|
||||
@@ -456,7 +463,7 @@ struct ParseStringHandler : BaseReaderHandler<Encoding, ParseStringHandler<Encod
|
||||
bool String(const typename Encoding::Ch* str, size_t length, bool copy) {
|
||||
EXPECT_EQ(0, str_);
|
||||
if (copy) {
|
||||
str_ = (typename Encoding::Ch*)malloc((length + 1) * sizeof(typename Encoding::Ch));
|
||||
str_ = static_cast<typename Encoding::Ch*>(malloc((length + 1) * sizeof(typename Encoding::Ch)));
|
||||
memcpy(const_cast<typename Encoding::Ch*>(str_), str, (length + 1) * sizeof(typename Encoding::Ch));
|
||||
}
|
||||
else
|
||||
@@ -639,11 +646,11 @@ TEST(Reader, ParseString_Error) {
|
||||
{
|
||||
char e[] = { '[', '\"', 0, '\"', ']', '\0' };
|
||||
for (unsigned char c = 0x80u; c <= 0xBFu; c++) {
|
||||
e[2] = c;
|
||||
e[2] = static_cast<char>(c);
|
||||
ParseErrorCode error = TestString<UTF8<> >(e);
|
||||
EXPECT_EQ(kParseErrorStringInvalidEncoding, error);
|
||||
if (error != kParseErrorStringInvalidEncoding)
|
||||
std::cout << (unsigned)(unsigned char)c << std::endl;
|
||||
std::cout << static_cast<unsigned>(c) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,7 +658,7 @@ TEST(Reader, ParseString_Error) {
|
||||
{
|
||||
char e[] = { '[', '\"', 0, ' ', '\"', ']', '\0' };
|
||||
for (unsigned c = 0xC0u; c <= 0xFFu; c++) {
|
||||
e[2] = (char)c;
|
||||
e[2] = static_cast<char>(c);
|
||||
TEST_STRING_ERROR(kParseErrorStringInvalidEncoding, e);
|
||||
}
|
||||
}
|
||||
@@ -771,7 +778,7 @@ struct ParseObjectHandler : BaseReaderHandler<UTF8<>, ParseObjectHandler> {
|
||||
default: ADD_FAILURE(); return false;
|
||||
}
|
||||
}
|
||||
bool Uint(unsigned i) { return Int(i); }
|
||||
bool Uint(unsigned i) { return Int(static_cast<int>(i)); }
|
||||
bool Double(double d) { EXPECT_EQ(12u, step_); EXPECT_DOUBLE_EQ(3.1416, d); step_++; return true; }
|
||||
bool String(const char* str, size_t, bool) {
|
||||
switch(step_) {
|
||||
@@ -1024,15 +1031,15 @@ public:
|
||||
|
||||
Ch Peek() const {
|
||||
int c = is_.peek();
|
||||
return c == std::char_traits<char>::eof() ? '\0' : (Ch)c;
|
||||
return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
|
||||
}
|
||||
|
||||
Ch Take() {
|
||||
int c = is_.get();
|
||||
return c == std::char_traits<char>::eof() ? '\0' : (Ch)c;
|
||||
return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
|
||||
}
|
||||
|
||||
size_t Tell() const { return (size_t)is_.tellg(); }
|
||||
size_t Tell() const { return static_cast<size_t>(is_.tellg()); }
|
||||
|
||||
Ch* PutBegin() { assert(false); return 0; }
|
||||
void Put(Ch) { assert(false); }
|
||||
@@ -1143,7 +1150,7 @@ struct IterativeParsingReaderHandler {
|
||||
bool EndObject(SizeType c) {
|
||||
RAPIDJSON_ASSERT(LogCount < LogCapacity);
|
||||
Logs[LogCount++] = LOG_ENDOBJECT;
|
||||
Logs[LogCount++] = (int)c;
|
||||
Logs[LogCount++] = static_cast<int>(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1152,7 +1159,7 @@ struct IterativeParsingReaderHandler {
|
||||
bool EndArray(SizeType c) {
|
||||
RAPIDJSON_ASSERT(LogCount < LogCapacity);
|
||||
Logs[LogCount++] = LOG_ENDARRAY;
|
||||
Logs[LogCount++] = (int)c;
|
||||
Logs[LogCount++] = static_cast<int>(c);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -1349,6 +1356,113 @@ TEST(Reader, ParseTerminationByHandler) {
|
||||
TEST_TERMINATION(12, "{\"a\":[1]"); // non-empty array
|
||||
}
|
||||
|
||||
TEST(Reader, ParseComments) {
|
||||
const char* json =
|
||||
"// Here is a one-line comment.\n"
|
||||
"{// And here's another one\n"
|
||||
" /*And here's an in-line one.*/\"hello\" : \"world\","
|
||||
" \"t\" :/* And one with '*' symbol*/true ,"
|
||||
"/* A multiline comment\n"
|
||||
" goes here*/"
|
||||
" \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3]"
|
||||
"}/*And the last one to be sure */";
|
||||
|
||||
StringStream s(json);
|
||||
ParseObjectHandler h;
|
||||
Reader reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
|
||||
EXPECT_EQ(20u, h.step_);
|
||||
}
|
||||
|
||||
TEST(Reader, ParseEmptyInlineComment) {
|
||||
const char* json = "{/**/\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
|
||||
|
||||
StringStream s(json);
|
||||
ParseObjectHandler h;
|
||||
Reader reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
|
||||
EXPECT_EQ(20u, h.step_);
|
||||
}
|
||||
|
||||
TEST(Reader, ParseEmptyOnelineComment) {
|
||||
const char* json = "{//\n\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
|
||||
|
||||
StringStream s(json);
|
||||
ParseObjectHandler h;
|
||||
Reader reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
|
||||
EXPECT_EQ(20u, h.step_);
|
||||
}
|
||||
|
||||
TEST(Reader, ParseMultipleCommentsInARow) {
|
||||
const char* json =
|
||||
"{/* first comment *//* second */\n"
|
||||
"/* third */ /*fourth*/// last one\n"
|
||||
"\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
|
||||
|
||||
StringStream s(json);
|
||||
ParseObjectHandler h;
|
||||
Reader reader;
|
||||
EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
|
||||
EXPECT_EQ(20u, h.step_);
|
||||
}
|
||||
|
||||
TEST(Reader, InlineCommentsAreDisabledByDefault) {
|
||||
{
|
||||
const char* json = "{/* Inline comment. */\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
|
||||
|
||||
StringStream s(json);
|
||||
ParseObjectHandler h;
|
||||
Reader reader;
|
||||
EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
|
||||
}
|
||||
|
||||
{
|
||||
const char* json =
|
||||
"{\"hello\" : /* Multiline comment starts here\n"
|
||||
" continues here\n"
|
||||
" and ends here */\"world\", \"t\" :true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
|
||||
|
||||
StringStream s(json);
|
||||
ParseObjectHandler h;
|
||||
Reader reader;
|
||||
EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Reader, OnelineCommentsAreDisabledByDefault) {
|
||||
const char* json = "{// One-line comment\n\"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
|
||||
|
||||
StringStream s(json);
|
||||
ParseObjectHandler h;
|
||||
Reader reader;
|
||||
EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
|
||||
}
|
||||
|
||||
TEST(Reader, EofAfterOneLineComment) {
|
||||
const char* json = "{\"hello\" : \"world\" // EOF is here -->\0 \n}";
|
||||
|
||||
StringStream s(json);
|
||||
ParseObjectHandler h;
|
||||
Reader reader;
|
||||
EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
|
||||
EXPECT_EQ(kParseErrorObjectMissCommaOrCurlyBracket, reader.GetParseErrorCode());
|
||||
}
|
||||
|
||||
TEST(Reader, IncompleteMultilineComment) {
|
||||
const char* json = "{\"hello\" : \"world\" /* EOF is here -->\0 */}";
|
||||
|
||||
StringStream s(json);
|
||||
ParseObjectHandler h;
|
||||
Reader reader;
|
||||
EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
|
||||
EXPECT_EQ(kParseErrorUnspecificSyntaxError, reader.GetParseErrorCode());
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
@@ -41,7 +41,7 @@ using namespace rapidjson_simd;
|
||||
|
||||
template <typename StreamType>
|
||||
void TestSkipWhitespace() {
|
||||
for (int step = 1; step < 32; step++) {
|
||||
for (size_t step = 1; step < 32; step++) {
|
||||
char buffer[1025];
|
||||
for (size_t i = 0; i < 1024; i++)
|
||||
buffer[i] = " \t\r\n"[i % 4];
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include "rapidjson/writer.h"
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
||||
#endif
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
TEST(StringBuffer, InitialSize) {
|
||||
@@ -69,6 +74,8 @@ TEST(StringBuffer, Pop) {
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
|
||||
#if 0 // Many old compiler does not support these. Turn it off temporaily.
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
TEST(StringBuffer, Traits) {
|
||||
@@ -106,6 +113,8 @@ TEST(StringBuffer, Traits) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TEST(StringBuffer, MoveConstructor) {
|
||||
StringBuffer x;
|
||||
x.Put('A');
|
||||
@@ -148,3 +157,7 @@ TEST(StringBuffer, MoveAssignment) {
|
||||
}
|
||||
|
||||
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
#include "rapidjson/internal/strtod.h"
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(unreachable-code)
|
||||
#endif
|
||||
|
||||
#define BIGINTEGER_LITERAL(s) BigInteger(s, sizeof(s) - 1)
|
||||
|
||||
using namespace rapidjson::internal;
|
||||
@@ -99,13 +104,13 @@ TEST(Strtod, CheckApproximationCase) {
|
||||
EXPECT_EQ(49, hS_Exp5);
|
||||
|
||||
BigInteger dS = BIGINTEGER_LITERAL(dInt);
|
||||
dS.MultiplyPow5(dS_Exp5) <<= dS_Exp2;
|
||||
dS.MultiplyPow5(static_cast<unsigned>(dS_Exp5)) <<= static_cast<size_t>(dS_Exp2);
|
||||
|
||||
BigInteger bS(bInt);
|
||||
bS.MultiplyPow5(bS_Exp5) <<= bS_Exp2;
|
||||
bS.MultiplyPow5(static_cast<unsigned>(bS_Exp5)) <<= static_cast<size_t>(bS_Exp2);
|
||||
|
||||
BigInteger hS(1);
|
||||
hS.MultiplyPow5(hS_Exp5) <<= hS_Exp2;
|
||||
hS.MultiplyPow5(static_cast<unsigned>(hS_Exp5)) <<= static_cast<size_t>(hS_Exp2);
|
||||
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("203970822259994138521801764465966248930731085529088") == dS);
|
||||
EXPECT_TRUE(BIGINTEGER_LITERAL("203970822259994122305215569213032722473144531250000") == bS);
|
||||
@@ -121,3 +126,7 @@ TEST(Strtod, CheckApproximationCase) {
|
||||
|
||||
EXPECT_EQ(-1, delta.Compare(hS));
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
@@ -15,12 +15,25 @@
|
||||
#include "unittest.h"
|
||||
#include "rapidjson/rapidjson.h"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic push
|
||||
#if __has_warning("-Wdeprecated")
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
AssertException::~AssertException() throw() {}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
std::cout << "RapidJSON v" << RAPIDJSON_VERSION_STRING << std::endl;
|
||||
|
||||
#if _MSC_VER
|
||||
#ifdef _MSC_VER
|
||||
_CrtMemState memoryState = { 0 };
|
||||
_CrtMemCheckpoint(&memoryState);
|
||||
//_CrtSetBreakAlloc(X);
|
||||
@@ -29,7 +42,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
int ret = RUN_ALL_TESTS();
|
||||
|
||||
#if _MSC_VER
|
||||
#ifdef _MSC_VER
|
||||
// Current gtest constantly leak 2 blocks at exit
|
||||
_CrtMemDumpAllObjectsSince(&memoryState);
|
||||
#endif
|
||||
|
||||
@@ -15,10 +15,20 @@
|
||||
#ifndef UNITTEST_H_
|
||||
#define UNITTEST_H_
|
||||
|
||||
|
||||
// gtest indirectly included inttypes.h, without __STDC_CONSTANT_MACROS.
|
||||
#ifndef __STDC_CONSTANT_MACROS
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic push
|
||||
#if __has_warning("-Wreserved-id-macro")
|
||||
#pragma GCC diagnostic ignored "-Wreserved-id-macro"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
# define __STDC_CONSTANT_MACROS 1 // required by C++ standard
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -41,6 +51,11 @@
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
// All TEST() macro generated this warning, disable globally
|
||||
#pragma GCC diagnostic ignored "-Wglobal-constructors"
|
||||
#endif
|
||||
|
||||
template <typename Ch>
|
||||
inline unsigned StrLen(const Ch* s) {
|
||||
const Ch* p = s;
|
||||
@@ -51,19 +66,19 @@ inline unsigned StrLen(const Ch* s) {
|
||||
template<typename Ch>
|
||||
inline int StrCmp(const Ch* s1, const Ch* s2) {
|
||||
while(*s1 && (*s1 == *s2)) { s1++; s2++; }
|
||||
return (unsigned)*s1 < (unsigned)*s2 ? -1 : (unsigned)*s1 > (unsigned)*s2;
|
||||
return static_cast<unsigned>(*s1) < static_cast<unsigned>(*s2) ? -1 : static_cast<unsigned>(*s1) > static_cast<unsigned>(*s2);
|
||||
}
|
||||
|
||||
template <typename Ch>
|
||||
inline Ch* StrDup(const Ch* str) {
|
||||
size_t bufferSize = sizeof(Ch) * (StrLen(str) + 1);
|
||||
Ch* buffer = (Ch*)malloc(bufferSize);
|
||||
Ch* buffer = static_cast<Ch*>(malloc(bufferSize));
|
||||
memcpy(buffer, str, bufferSize);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
inline FILE* TempFile(char *filename) {
|
||||
#if _MSC_VER
|
||||
#ifdef _MSC_VER
|
||||
filename = tmpnam(filename);
|
||||
|
||||
// For Visual Studio, tmpnam() adds a backslash in front. Remove it.
|
||||
@@ -80,15 +95,28 @@ inline FILE* TempFile(char *filename) {
|
||||
}
|
||||
|
||||
// Use exception for catching assert
|
||||
#if _MSC_VER
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4127)
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic push
|
||||
#if __has_warning("-Wdeprecated")
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class AssertException : public std::logic_error {
|
||||
public:
|
||||
AssertException(const char* w) : std::logic_error(w) {}
|
||||
AssertException(const AssertException& rhs) : std::logic_error(rhs) {}
|
||||
virtual ~AssertException() throw();
|
||||
};
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#define RAPIDJSON_ASSERT(x) if (!(x)) throw AssertException(RAPIDJSON_STRINGIFY(x))
|
||||
|
||||
class Random {
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
#include "rapidjson/document.h"
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(c++98-compat)
|
||||
#endif
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
TEST(Value, DefaultConstructor) {
|
||||
@@ -34,6 +39,8 @@ TEST(Value, DefaultConstructor) {
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
|
||||
#if 0 // Many old compiler does not support these. Turn it off temporaily.
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
TEST(Value, Traits) {
|
||||
@@ -72,6 +79,8 @@ TEST(Value, Traits) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TEST(Value, MoveConstructor) {
|
||||
typedef GenericValue<UTF8<>, CrtAllocator> Value;
|
||||
Value::AllocatorType allocator;
|
||||
@@ -448,7 +457,7 @@ TEST(Value, Uint) {
|
||||
|
||||
TEST(Value, Int64) {
|
||||
// Constructor with int
|
||||
Value x(int64_t(1234LL));
|
||||
Value x(int64_t(1234));
|
||||
EXPECT_EQ(kNumberType, x.GetType());
|
||||
EXPECT_EQ(1234, x.GetInt());
|
||||
EXPECT_EQ(1234u, x.GetUint());
|
||||
@@ -469,7 +478,7 @@ TEST(Value, Int64) {
|
||||
EXPECT_FALSE(x.IsObject());
|
||||
EXPECT_FALSE(x.IsArray());
|
||||
|
||||
Value nx(int64_t(-1234LL));
|
||||
Value nx(int64_t(-1234));
|
||||
EXPECT_EQ(-1234, nx.GetInt());
|
||||
EXPECT_EQ(-1234, nx.GetInt64());
|
||||
EXPECT_TRUE(nx.IsInt());
|
||||
@@ -482,17 +491,17 @@ TEST(Value, Int64) {
|
||||
z.SetInt64(1234);
|
||||
EXPECT_EQ(1234, z.GetInt64());
|
||||
|
||||
z.SetInt64(2147483648LL); // 2^31, cannot cast as int
|
||||
z.SetInt64(2147483648u); // 2^31, cannot cast as int
|
||||
EXPECT_FALSE(z.IsInt());
|
||||
EXPECT_TRUE(z.IsUint());
|
||||
EXPECT_NEAR(2147483648.0, z.GetDouble(), 0.0);
|
||||
|
||||
z.SetInt64(4294967296LL); // 2^32, cannot cast as uint
|
||||
z.SetInt64(int64_t(4294967295u) + 1); // 2^32, cannot cast as uint
|
||||
EXPECT_FALSE(z.IsInt());
|
||||
EXPECT_FALSE(z.IsUint());
|
||||
EXPECT_NEAR(4294967296.0, z.GetDouble(), 0.0);
|
||||
|
||||
z.SetInt64(-2147483649LL); // -2^31-1, cannot cast as int
|
||||
z.SetInt64(-int64_t(2147483648u) - 1); // -2^31-1, cannot cast as int
|
||||
EXPECT_FALSE(z.IsInt());
|
||||
EXPECT_NEAR(-2147483649.0, z.GetDouble(), 0.0);
|
||||
|
||||
@@ -502,7 +511,7 @@ TEST(Value, Int64) {
|
||||
|
||||
TEST(Value, Uint64) {
|
||||
// Constructor with int
|
||||
Value x(uint64_t(1234LL));
|
||||
Value x(uint64_t(1234));
|
||||
EXPECT_EQ(kNumberType, x.GetType());
|
||||
EXPECT_EQ(1234, x.GetInt());
|
||||
EXPECT_EQ(1234u, x.GetUint());
|
||||
@@ -528,19 +537,19 @@ TEST(Value, Uint64) {
|
||||
z.SetUint64(1234);
|
||||
EXPECT_EQ(1234u, z.GetUint64());
|
||||
|
||||
z.SetUint64(2147483648LL); // 2^31, cannot cast as int
|
||||
z.SetUint64(uint64_t(2147483648u)); // 2^31, cannot cast as int
|
||||
EXPECT_FALSE(z.IsInt());
|
||||
EXPECT_TRUE(z.IsUint());
|
||||
EXPECT_TRUE(z.IsInt64());
|
||||
|
||||
z.SetUint64(4294967296LL); // 2^32, cannot cast as uint
|
||||
z.SetUint64(uint64_t(4294967295u) + 1); // 2^32, cannot cast as uint
|
||||
EXPECT_FALSE(z.IsInt());
|
||||
EXPECT_FALSE(z.IsUint());
|
||||
EXPECT_TRUE(z.IsInt64());
|
||||
|
||||
z.SetUint64(9223372036854775808uLL); // 2^63 cannot cast as int64
|
||||
z.SetUint64(RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)); // 2^63 cannot cast as int64
|
||||
EXPECT_FALSE(z.IsInt64());
|
||||
EXPECT_EQ(9223372036854775808uLL, z.GetUint64()); // Issue 48
|
||||
EXPECT_EQ(RAPIDJSON_UINT64_C2(0x80000000, 0x00000000), z.GetUint64()); // Issue 48
|
||||
EXPECT_DOUBLE_EQ(9223372036854775808.0, z.GetDouble());
|
||||
}
|
||||
|
||||
@@ -662,7 +671,7 @@ TEST(Value, String) {
|
||||
// SetString()
|
||||
char s[] = "World";
|
||||
Value w;
|
||||
w.SetString(s, (SizeType)strlen(s), allocator);
|
||||
w.SetString(s, static_cast<SizeType>(strlen(s)), allocator);
|
||||
s[0] = '\0';
|
||||
EXPECT_STREQ("World", w.GetString());
|
||||
EXPECT_EQ(5u, w.GetStringLength());
|
||||
@@ -764,15 +773,15 @@ TEST(Value, Array) {
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
// PushBack(GenericValue&&, Allocator&);
|
||||
{
|
||||
Value y(kArrayType);
|
||||
y.PushBack(Value(true), allocator);
|
||||
y.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator);
|
||||
EXPECT_EQ(2u, y.Size());
|
||||
EXPECT_TRUE(y[0].IsTrue());
|
||||
EXPECT_TRUE(y[1].IsArray());
|
||||
EXPECT_EQ(2u, y[1].Size());
|
||||
EXPECT_TRUE(y[1][0].IsInt());
|
||||
EXPECT_TRUE(y[1][1].IsString());
|
||||
Value y2(kArrayType);
|
||||
y2.PushBack(Value(true), allocator);
|
||||
y2.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator);
|
||||
EXPECT_EQ(2u, y2.Size());
|
||||
EXPECT_TRUE(y2[0].IsTrue());
|
||||
EXPECT_TRUE(y2[1].IsArray());
|
||||
EXPECT_EQ(2u, y2[1].Size());
|
||||
EXPECT_TRUE(y2[1][0].IsInt());
|
||||
EXPECT_TRUE(y2[1][1].IsString());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -841,23 +850,23 @@ TEST(Value, Array) {
|
||||
EXPECT_EQ(x.Begin(), itr);
|
||||
EXPECT_EQ(9u, x.Size());
|
||||
for (int i = 0; i < 9; i++)
|
||||
EXPECT_EQ(i + 1, x[i][0].GetInt());
|
||||
EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
|
||||
|
||||
// Ease the last
|
||||
itr = x.Erase(x.End() - 1);
|
||||
EXPECT_EQ(x.End(), itr);
|
||||
EXPECT_EQ(8u, x.Size());
|
||||
for (int i = 0; i < 8; i++)
|
||||
EXPECT_EQ(i + 1, x[i][0].GetInt());
|
||||
EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
|
||||
|
||||
// Erase the middle
|
||||
itr = x.Erase(x.Begin() + 4);
|
||||
EXPECT_EQ(x.Begin() + 4, itr);
|
||||
EXPECT_EQ(7u, x.Size());
|
||||
for (int i = 0; i < 4; i++)
|
||||
EXPECT_EQ(i + 1, x[i][0].GetInt());
|
||||
EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
|
||||
for (int i = 4; i < 7; i++)
|
||||
EXPECT_EQ(i + 2, x[i][0].GetInt());
|
||||
EXPECT_EQ(i + 2, x[static_cast<SizeType>(i)][0].GetInt());
|
||||
|
||||
// Erase(ValueIterator, ValueIterator)
|
||||
// Exhaustive test with all 0 <= first < n, first <= last <= n cases
|
||||
@@ -879,7 +888,7 @@ TEST(Value, Array) {
|
||||
for (unsigned i = 0; i < first; i++)
|
||||
EXPECT_EQ(i, x[i][0].GetUint());
|
||||
for (unsigned i = first; i < n - removeCount; i++)
|
||||
EXPECT_EQ(i + removeCount, x[i][0].GetUint());
|
||||
EXPECT_EQ(i + removeCount, x[static_cast<SizeType>(i)][0].GetUint());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -896,7 +905,7 @@ TEST(Value, Array) {
|
||||
x.Erase(std::remove(x.Begin(), x.End(), null), x.End());
|
||||
EXPECT_EQ(5u, x.Size());
|
||||
for (int i = 0; i < 5; i++)
|
||||
EXPECT_EQ(i * 2, x[i]);
|
||||
EXPECT_EQ(i * 2, x[static_cast<SizeType>(i)]);
|
||||
|
||||
// SetArray()
|
||||
Value z;
|
||||
@@ -935,8 +944,8 @@ TEST(Value, Object) {
|
||||
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("int64", int64_t(-4294967296), allocator);
|
||||
o.AddMember("uint64", uint64_t(4294967296), allocator);
|
||||
o.AddMember("double", 3.14, allocator);
|
||||
o.AddMember("string", "Jelly", allocator);
|
||||
|
||||
@@ -944,8 +953,8 @@ TEST(Value, Object) {
|
||||
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_EQ(int64_t(-4294967296), o["int64"].GetInt64());
|
||||
EXPECT_EQ(uint64_t(4294967296), o["uint64"].GetUint64());
|
||||
EXPECT_STREQ("Jelly",o["string"].GetString());
|
||||
EXPECT_EQ(8u, o.MemberCount());
|
||||
}
|
||||
@@ -1125,7 +1134,7 @@ TEST(Value, Object) {
|
||||
EXPECT_EQ(x.MemberBegin(), itr);
|
||||
EXPECT_EQ(9u, x.MemberCount());
|
||||
for (; itr != x.MemberEnd(); ++itr) {
|
||||
int i = (itr - x.MemberBegin()) + 1;
|
||||
size_t i = static_cast<size_t>((itr - x.MemberBegin())) + 1;
|
||||
EXPECT_STREQ(itr->name.GetString(), keys[i]);
|
||||
EXPECT_EQ(i, itr->value[0].GetInt());
|
||||
}
|
||||
@@ -1136,7 +1145,7 @@ TEST(Value, Object) {
|
||||
EXPECT_EQ(x.MemberEnd(), itr);
|
||||
EXPECT_EQ(8u, x.MemberCount());
|
||||
for (; itr != x.MemberEnd(); ++itr) {
|
||||
int i = (itr - x.MemberBegin()) + 1;
|
||||
size_t i = static_cast<size_t>(itr - x.MemberBegin()) + 1;
|
||||
EXPECT_STREQ(itr->name.GetString(), keys[i]);
|
||||
EXPECT_EQ(i, itr->value[0].GetInt());
|
||||
}
|
||||
@@ -1147,8 +1156,8 @@ TEST(Value, Object) {
|
||||
EXPECT_EQ(x.MemberBegin() + 4, itr);
|
||||
EXPECT_EQ(7u, x.MemberCount());
|
||||
for (; itr != x.MemberEnd(); ++itr) {
|
||||
int i = (itr - x.MemberBegin());
|
||||
i += (i<4) ? 1 : 2;
|
||||
size_t i = static_cast<size_t>(itr - x.MemberBegin());
|
||||
i += (i < 4) ? 1 : 2;
|
||||
EXPECT_STREQ(itr->name.GetString(), keys[i]);
|
||||
EXPECT_EQ(i, itr->value[0].GetInt());
|
||||
}
|
||||
@@ -1162,11 +1171,11 @@ TEST(Value, Object) {
|
||||
for (unsigned i = 0; i < n; i++)
|
||||
x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
|
||||
|
||||
itr = x.EraseMember(x.MemberBegin() + first, x.MemberBegin() + last);
|
||||
itr = x.EraseMember(x.MemberBegin() + static_cast<int>(first), x.MemberBegin() + static_cast<int>(last));
|
||||
if (last == n)
|
||||
EXPECT_EQ(x.MemberEnd(), itr);
|
||||
else
|
||||
EXPECT_EQ(x.MemberBegin() + first, itr);
|
||||
EXPECT_EQ(x.MemberBegin() + static_cast<int>(first), itr);
|
||||
|
||||
size_t removeCount = last - first;
|
||||
EXPECT_EQ(n - removeCount, x.MemberCount());
|
||||
@@ -1214,7 +1223,7 @@ TEST(Value, BigNestedArray) {
|
||||
for (SizeType i = 0; i < n; i++) {
|
||||
Value y(kArrayType);
|
||||
for (SizeType j = 0; j < n; j++) {
|
||||
Value number((int)(i * n + j));
|
||||
Value number(static_cast<int>(i * n + j));
|
||||
y.PushBack(number, allocator);
|
||||
}
|
||||
x.PushBack(y, allocator);
|
||||
@@ -1223,7 +1232,7 @@ TEST(Value, BigNestedArray) {
|
||||
for (SizeType i = 0; i < n; i++)
|
||||
for (SizeType j = 0; j < n; j++) {
|
||||
EXPECT_TRUE(x[i][j].IsInt());
|
||||
EXPECT_EQ((int)(i * n + j), x[i][j].GetInt());
|
||||
EXPECT_EQ(static_cast<int>(i * n + j), x[i][j].GetInt());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1237,16 +1246,16 @@ TEST(Value, BigNestedObject) {
|
||||
sprintf(name1, "%d", i);
|
||||
|
||||
// Value name(name1); // should not compile
|
||||
Value name(name1, (SizeType)strlen(name1), allocator);
|
||||
Value name(name1, static_cast<SizeType>(strlen(name1)), allocator);
|
||||
Value object(kObjectType);
|
||||
|
||||
for (SizeType j = 0; j < n; j++) {
|
||||
char name2[10];
|
||||
sprintf(name2, "%d", j);
|
||||
|
||||
Value name(name2, (SizeType)strlen(name2), allocator);
|
||||
Value number((int)(i * n + j));
|
||||
object.AddMember(name, number, allocator);
|
||||
Value name3(name2, static_cast<SizeType>(strlen(name2)), allocator);
|
||||
Value number(static_cast<int>(i * n + j));
|
||||
object.AddMember(name3, number, allocator);
|
||||
}
|
||||
|
||||
// x.AddMember(name1, object, allocator); // should not compile
|
||||
@@ -1261,7 +1270,7 @@ TEST(Value, BigNestedObject) {
|
||||
char name2[10];
|
||||
sprintf(name2, "%d", j);
|
||||
x[name1];
|
||||
EXPECT_EQ((int)(i * n + j), x[name1][name2].GetInt());
|
||||
EXPECT_EQ(static_cast<int>(i * n + j), x[name1][name2].GetInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1293,7 +1302,7 @@ TEST(Document, CrtAllocator) {
|
||||
}
|
||||
|
||||
static void TestShortStringOptimization(const char* str) {
|
||||
const rapidjson::SizeType len = (rapidjson::SizeType)strlen(str);
|
||||
const rapidjson::SizeType len = static_cast<rapidjson::SizeType>(strlen(str));
|
||||
|
||||
rapidjson::Document doc;
|
||||
rapidjson::Value val;
|
||||
@@ -1354,3 +1363,27 @@ TEST(Value, AcceptTerminationByHandler) {
|
||||
TEST_TERMINATION(11, "{\"a\":[]}");
|
||||
TEST_TERMINATION(12, "{\"a\":[]}");
|
||||
}
|
||||
|
||||
struct ValueIntComparer {
|
||||
bool operator()(const Value& lhs, const Value& rhs) const {
|
||||
return lhs.GetInt() < rhs.GetInt();
|
||||
}
|
||||
};
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
TEST(Value, Sorting) {
|
||||
Value::AllocatorType allocator;
|
||||
Value a(kArrayType);
|
||||
a.PushBack(5, allocator);
|
||||
a.PushBack(1, allocator);
|
||||
a.PushBack(3, allocator);
|
||||
std::sort(a.Begin(), a.End(), ValueIntComparer());
|
||||
EXPECT_EQ(1, a[0].GetInt());
|
||||
EXPECT_EQ(3, a[1].GetInt());
|
||||
EXPECT_EQ(5, a[2].GetInt());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
@@ -66,7 +66,7 @@ gh_pages_prepare()
|
||||
[ ! -d "html" ] || \
|
||||
abort "Doxygen target directory already exists."
|
||||
git --version
|
||||
git clone --single-branch -b gh-pages "${GITHUB_CLONE}" html
|
||||
git clone -b gh-pages "${GITHUB_CLONE}" html
|
||||
cd html
|
||||
# setup git config (with defaults)
|
||||
git config user.name "${GIT_NAME-travis}"
|
||||
|
||||
Reference in New Issue
Block a user