rj_schema 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (299) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +18 -0
  3. data/ext/rj_schema/extconf.rb +7 -0
  4. data/ext/rj_schema/rapidjson/CHANGELOG.md +158 -0
  5. data/ext/rj_schema/rapidjson/CMakeLists.txt +221 -0
  6. data/ext/rj_schema/rapidjson/CMakeModules/FindGTestSrc.cmake +30 -0
  7. data/ext/rj_schema/rapidjson/RapidJSON.pc.in +7 -0
  8. data/ext/rj_schema/rapidjson/RapidJSONConfig.cmake.in +15 -0
  9. data/ext/rj_schema/rapidjson/RapidJSONConfigVersion.cmake.in +10 -0
  10. data/ext/rj_schema/rapidjson/appveyor.yml +41 -0
  11. data/ext/rj_schema/rapidjson/bin/data/glossary.json +22 -0
  12. data/ext/rj_schema/rapidjson/bin/data/menu.json +27 -0
  13. data/ext/rj_schema/rapidjson/bin/data/readme.txt +1 -0
  14. data/ext/rj_schema/rapidjson/bin/data/sample.json +3315 -0
  15. data/ext/rj_schema/rapidjson/bin/data/webapp.json +88 -0
  16. data/ext/rj_schema/rapidjson/bin/data/widget.json +26 -0
  17. data/ext/rj_schema/rapidjson/bin/draft-04/schema +150 -0
  18. data/ext/rj_schema/rapidjson/bin/encodings/utf16be.json +0 -0
  19. data/ext/rj_schema/rapidjson/bin/encodings/utf16bebom.json +0 -0
  20. data/ext/rj_schema/rapidjson/bin/encodings/utf16le.json +0 -0
  21. data/ext/rj_schema/rapidjson/bin/encodings/utf16lebom.json +0 -0
  22. data/ext/rj_schema/rapidjson/bin/encodings/utf32be.json +0 -0
  23. data/ext/rj_schema/rapidjson/bin/encodings/utf32bebom.json +0 -0
  24. data/ext/rj_schema/rapidjson/bin/encodings/utf32le.json +0 -0
  25. data/ext/rj_schema/rapidjson/bin/encodings/utf32lebom.json +0 -0
  26. data/ext/rj_schema/rapidjson/bin/encodings/utf8.json +7 -0
  27. data/ext/rj_schema/rapidjson/bin/encodings/utf8bom.json +7 -0
  28. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail1.json +1 -0
  29. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail10.json +1 -0
  30. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail11.json +1 -0
  31. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail12.json +1 -0
  32. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail13.json +1 -0
  33. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail14.json +1 -0
  34. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail15.json +1 -0
  35. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail16.json +1 -0
  36. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail17.json +1 -0
  37. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail18.json +1 -0
  38. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail19.json +1 -0
  39. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail2.json +1 -0
  40. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail20.json +1 -0
  41. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail21.json +1 -0
  42. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail22.json +1 -0
  43. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail23.json +1 -0
  44. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail24.json +1 -0
  45. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail25.json +1 -0
  46. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail26.json +1 -0
  47. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail27.json +2 -0
  48. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail28.json +2 -0
  49. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail29.json +1 -0
  50. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail3.json +1 -0
  51. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail30.json +1 -0
  52. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail31.json +1 -0
  53. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail32.json +1 -0
  54. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail33.json +1 -0
  55. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail4.json +1 -0
  56. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail5.json +1 -0
  57. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail6.json +1 -0
  58. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail7.json +1 -0
  59. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail8.json +1 -0
  60. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail9.json +1 -0
  61. data/ext/rj_schema/rapidjson/bin/jsonchecker/pass1.json +58 -0
  62. data/ext/rj_schema/rapidjson/bin/jsonchecker/pass2.json +1 -0
  63. data/ext/rj_schema/rapidjson/bin/jsonchecker/pass3.json +6 -0
  64. data/ext/rj_schema/rapidjson/bin/jsonchecker/readme.txt +3 -0
  65. data/ext/rj_schema/rapidjson/bin/jsonschema/LICENSE +19 -0
  66. data/ext/rj_schema/rapidjson/bin/jsonschema/README.md +148 -0
  67. data/ext/rj_schema/rapidjson/bin/jsonschema/bin/jsonschema_suite +283 -0
  68. data/ext/rj_schema/rapidjson/bin/jsonschema/remotes/folder/folderInteger.json +3 -0
  69. data/ext/rj_schema/rapidjson/bin/jsonschema/remotes/integer.json +3 -0
  70. data/ext/rj_schema/rapidjson/bin/jsonschema/remotes/subSchemas.json +8 -0
  71. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/additionalItems.json +82 -0
  72. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/additionalProperties.json +88 -0
  73. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/default.json +49 -0
  74. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/dependencies.json +108 -0
  75. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/disallow.json +80 -0
  76. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/divisibleBy.json +60 -0
  77. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/enum.json +71 -0
  78. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/extends.json +94 -0
  79. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/items.json +46 -0
  80. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/maxItems.json +28 -0
  81. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/maxLength.json +33 -0
  82. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/maximum.json +42 -0
  83. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/minItems.json +28 -0
  84. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/minLength.json +33 -0
  85. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/minimum.json +42 -0
  86. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/optional/bignum.json +107 -0
  87. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/optional/format.json +222 -0
  88. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/optional/jsregex.json +18 -0
  89. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/optional/zeroTerminatedFloats.json +15 -0
  90. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/pattern.json +34 -0
  91. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/patternProperties.json +110 -0
  92. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/properties.json +92 -0
  93. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/ref.json +159 -0
  94. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/refRemote.json +74 -0
  95. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/required.json +53 -0
  96. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/type.json +474 -0
  97. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/uniqueItems.json +79 -0
  98. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/additionalItems.json +82 -0
  99. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/additionalProperties.json +88 -0
  100. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/allOf.json +112 -0
  101. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/anyOf.json +68 -0
  102. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/default.json +49 -0
  103. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/definitions.json +32 -0
  104. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/dependencies.json +113 -0
  105. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/enum.json +72 -0
  106. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/items.json +46 -0
  107. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/maxItems.json +28 -0
  108. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/maxLength.json +33 -0
  109. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/maxProperties.json +28 -0
  110. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/maximum.json +42 -0
  111. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/minItems.json +28 -0
  112. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/minLength.json +33 -0
  113. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/minProperties.json +28 -0
  114. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/minimum.json +42 -0
  115. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/multipleOf.json +60 -0
  116. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/not.json +96 -0
  117. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/oneOf.json +68 -0
  118. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/optional/bignum.json +107 -0
  119. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/optional/format.json +148 -0
  120. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/optional/zeroTerminatedFloats.json +15 -0
  121. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/pattern.json +34 -0
  122. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/patternProperties.json +110 -0
  123. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/properties.json +92 -0
  124. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/ref.json +159 -0
  125. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/refRemote.json +74 -0
  126. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/required.json +39 -0
  127. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/type.json +330 -0
  128. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/uniqueItems.json +79 -0
  129. data/ext/rj_schema/rapidjson/bin/jsonschema/tox.ini +8 -0
  130. data/ext/rj_schema/rapidjson/bin/types/booleans.json +102 -0
  131. data/ext/rj_schema/rapidjson/bin/types/floats.json +102 -0
  132. data/ext/rj_schema/rapidjson/bin/types/guids.json +102 -0
  133. data/ext/rj_schema/rapidjson/bin/types/integers.json +102 -0
  134. data/ext/rj_schema/rapidjson/bin/types/mixed.json +592 -0
  135. data/ext/rj_schema/rapidjson/bin/types/nulls.json +102 -0
  136. data/ext/rj_schema/rapidjson/bin/types/paragraphs.json +102 -0
  137. data/ext/rj_schema/rapidjson/bin/types/readme.txt +1 -0
  138. data/ext/rj_schema/rapidjson/contrib/natvis/LICENSE +45 -0
  139. data/ext/rj_schema/rapidjson/contrib/natvis/README.md +7 -0
  140. data/ext/rj_schema/rapidjson/contrib/natvis/rapidjson.natvis +38 -0
  141. data/ext/rj_schema/rapidjson/doc/CMakeLists.txt +27 -0
  142. data/ext/rj_schema/rapidjson/doc/Doxyfile.in +2369 -0
  143. data/ext/rj_schema/rapidjson/doc/Doxyfile.zh-cn.in +2369 -0
  144. data/ext/rj_schema/rapidjson/doc/diagram/architecture.dot +50 -0
  145. data/ext/rj_schema/rapidjson/doc/diagram/architecture.png +0 -0
  146. data/ext/rj_schema/rapidjson/doc/diagram/insituparsing.dot +65 -0
  147. data/ext/rj_schema/rapidjson/doc/diagram/insituparsing.png +0 -0
  148. data/ext/rj_schema/rapidjson/doc/diagram/iterative-parser-states-diagram.dot +62 -0
  149. data/ext/rj_schema/rapidjson/doc/diagram/iterative-parser-states-diagram.png +0 -0
  150. data/ext/rj_schema/rapidjson/doc/diagram/makefile +8 -0
  151. data/ext/rj_schema/rapidjson/doc/diagram/move1.dot +47 -0
  152. data/ext/rj_schema/rapidjson/doc/diagram/move1.png +0 -0
  153. data/ext/rj_schema/rapidjson/doc/diagram/move2.dot +62 -0
  154. data/ext/rj_schema/rapidjson/doc/diagram/move2.png +0 -0
  155. data/ext/rj_schema/rapidjson/doc/diagram/move3.dot +60 -0
  156. data/ext/rj_schema/rapidjson/doc/diagram/move3.png +0 -0
  157. data/ext/rj_schema/rapidjson/doc/diagram/normalparsing.dot +56 -0
  158. data/ext/rj_schema/rapidjson/doc/diagram/normalparsing.png +0 -0
  159. data/ext/rj_schema/rapidjson/doc/diagram/simpledom.dot +54 -0
  160. data/ext/rj_schema/rapidjson/doc/diagram/simpledom.png +0 -0
  161. data/ext/rj_schema/rapidjson/doc/diagram/tutorial.dot +58 -0
  162. data/ext/rj_schema/rapidjson/doc/diagram/tutorial.png +0 -0
  163. data/ext/rj_schema/rapidjson/doc/diagram/utilityclass.dot +73 -0
  164. data/ext/rj_schema/rapidjson/doc/diagram/utilityclass.png +0 -0
  165. data/ext/rj_schema/rapidjson/doc/dom.md +280 -0
  166. data/ext/rj_schema/rapidjson/doc/dom.zh-cn.md +284 -0
  167. data/ext/rj_schema/rapidjson/doc/encoding.md +146 -0
  168. data/ext/rj_schema/rapidjson/doc/encoding.zh-cn.md +152 -0
  169. data/ext/rj_schema/rapidjson/doc/faq.md +289 -0
  170. data/ext/rj_schema/rapidjson/doc/faq.zh-cn.md +290 -0
  171. data/ext/rj_schema/rapidjson/doc/features.md +104 -0
  172. data/ext/rj_schema/rapidjson/doc/features.zh-cn.md +103 -0
  173. data/ext/rj_schema/rapidjson/doc/internals.md +368 -0
  174. data/ext/rj_schema/rapidjson/doc/internals.zh-cn.md +363 -0
  175. data/ext/rj_schema/rapidjson/doc/logo/rapidjson.png +0 -0
  176. data/ext/rj_schema/rapidjson/doc/logo/rapidjson.svg +119 -0
  177. data/ext/rj_schema/rapidjson/doc/misc/DoxygenLayout.xml +194 -0
  178. data/ext/rj_schema/rapidjson/doc/misc/doxygenextra.css +274 -0
  179. data/ext/rj_schema/rapidjson/doc/misc/footer.html +11 -0
  180. data/ext/rj_schema/rapidjson/doc/misc/header.html +24 -0
  181. data/ext/rj_schema/rapidjson/doc/npm.md +31 -0
  182. data/ext/rj_schema/rapidjson/doc/performance.md +26 -0
  183. data/ext/rj_schema/rapidjson/doc/performance.zh-cn.md +26 -0
  184. data/ext/rj_schema/rapidjson/doc/pointer.md +234 -0
  185. data/ext/rj_schema/rapidjson/doc/pointer.zh-cn.md +234 -0
  186. data/ext/rj_schema/rapidjson/doc/sax.md +509 -0
  187. data/ext/rj_schema/rapidjson/doc/sax.zh-cn.md +487 -0
  188. data/ext/rj_schema/rapidjson/doc/schema.md +505 -0
  189. data/ext/rj_schema/rapidjson/doc/schema.zh-cn.md +237 -0
  190. data/ext/rj_schema/rapidjson/doc/stream.md +426 -0
  191. data/ext/rj_schema/rapidjson/doc/stream.zh-cn.md +426 -0
  192. data/ext/rj_schema/rapidjson/doc/tutorial.md +536 -0
  193. data/ext/rj_schema/rapidjson/doc/tutorial.zh-cn.md +534 -0
  194. data/ext/rj_schema/rapidjson/docker/debian/Dockerfile +8 -0
  195. data/ext/rj_schema/rapidjson/example/CMakeLists.txt +45 -0
  196. data/ext/rj_schema/rapidjson/example/archiver/archiver.cpp +292 -0
  197. data/ext/rj_schema/rapidjson/example/archiver/archiver.h +145 -0
  198. data/ext/rj_schema/rapidjson/example/archiver/archivertest.cpp +287 -0
  199. data/ext/rj_schema/rapidjson/example/capitalize/capitalize.cpp +67 -0
  200. data/ext/rj_schema/rapidjson/example/condense/condense.cpp +32 -0
  201. data/ext/rj_schema/rapidjson/example/filterkey/filterkey.cpp +135 -0
  202. data/ext/rj_schema/rapidjson/example/filterkeydom/filterkeydom.cpp +170 -0
  203. data/ext/rj_schema/rapidjson/example/jsonx/jsonx.cpp +207 -0
  204. data/ext/rj_schema/rapidjson/example/lookaheadparser/lookaheadparser.cpp +350 -0
  205. data/ext/rj_schema/rapidjson/example/messagereader/messagereader.cpp +105 -0
  206. data/ext/rj_schema/rapidjson/example/parsebyparts/parsebyparts.cpp +176 -0
  207. data/ext/rj_schema/rapidjson/example/pretty/pretty.cpp +30 -0
  208. data/ext/rj_schema/rapidjson/example/prettyauto/prettyauto.cpp +56 -0
  209. data/ext/rj_schema/rapidjson/example/schemavalidator/schemavalidator.cpp +78 -0
  210. data/ext/rj_schema/rapidjson/example/serialize/serialize.cpp +173 -0
  211. data/ext/rj_schema/rapidjson/example/simpledom/simpledom.cpp +29 -0
  212. data/ext/rj_schema/rapidjson/example/simplepullreader/simplepullreader.cpp +53 -0
  213. data/ext/rj_schema/rapidjson/example/simplereader/simplereader.cpp +42 -0
  214. data/ext/rj_schema/rapidjson/example/simplewriter/simplewriter.cpp +36 -0
  215. data/ext/rj_schema/rapidjson/example/tutorial/tutorial.cpp +151 -0
  216. data/ext/rj_schema/rapidjson/include/rapidjson/allocators.h +271 -0
  217. data/ext/rj_schema/rapidjson/include/rapidjson/cursorstreamwrapper.h +78 -0
  218. data/ext/rj_schema/rapidjson/include/rapidjson/document.h +2630 -0
  219. data/ext/rj_schema/rapidjson/include/rapidjson/encodedstream.h +299 -0
  220. data/ext/rj_schema/rapidjson/include/rapidjson/encodings.h +716 -0
  221. data/ext/rj_schema/rapidjson/include/rapidjson/error/en.h +74 -0
  222. data/ext/rj_schema/rapidjson/include/rapidjson/error/error.h +161 -0
  223. data/ext/rj_schema/rapidjson/include/rapidjson/filereadstream.h +99 -0
  224. data/ext/rj_schema/rapidjson/include/rapidjson/filewritestream.h +104 -0
  225. data/ext/rj_schema/rapidjson/include/rapidjson/fwd.h +151 -0
  226. data/ext/rj_schema/rapidjson/include/rapidjson/internal/biginteger.h +290 -0
  227. data/ext/rj_schema/rapidjson/include/rapidjson/internal/diyfp.h +258 -0
  228. data/ext/rj_schema/rapidjson/include/rapidjson/internal/dtoa.h +245 -0
  229. data/ext/rj_schema/rapidjson/include/rapidjson/internal/ieee754.h +78 -0
  230. data/ext/rj_schema/rapidjson/include/rapidjson/internal/itoa.h +304 -0
  231. data/ext/rj_schema/rapidjson/include/rapidjson/internal/meta.h +181 -0
  232. data/ext/rj_schema/rapidjson/include/rapidjson/internal/pow10.h +55 -0
  233. data/ext/rj_schema/rapidjson/include/rapidjson/internal/regex.h +734 -0
  234. data/ext/rj_schema/rapidjson/include/rapidjson/internal/stack.h +231 -0
  235. data/ext/rj_schema/rapidjson/include/rapidjson/internal/strfunc.h +69 -0
  236. data/ext/rj_schema/rapidjson/include/rapidjson/internal/strtod.h +269 -0
  237. data/ext/rj_schema/rapidjson/include/rapidjson/internal/swap.h +46 -0
  238. data/ext/rj_schema/rapidjson/include/rapidjson/istreamwrapper.h +115 -0
  239. data/ext/rj_schema/rapidjson/include/rapidjson/memorybuffer.h +70 -0
  240. data/ext/rj_schema/rapidjson/include/rapidjson/memorystream.h +71 -0
  241. data/ext/rj_schema/rapidjson/include/rapidjson/msinttypes/inttypes.h +316 -0
  242. data/ext/rj_schema/rapidjson/include/rapidjson/msinttypes/stdint.h +300 -0
  243. data/ext/rj_schema/rapidjson/include/rapidjson/ostreamwrapper.h +81 -0
  244. data/ext/rj_schema/rapidjson/include/rapidjson/pointer.h +1363 -0
  245. data/ext/rj_schema/rapidjson/include/rapidjson/prettywriter.h +277 -0
  246. data/ext/rj_schema/rapidjson/include/rapidjson/rapidjson.h +628 -0
  247. data/ext/rj_schema/rapidjson/include/rapidjson/reader.h +2222 -0
  248. data/ext/rj_schema/rapidjson/include/rapidjson/schema.h +2479 -0
  249. data/ext/rj_schema/rapidjson/include/rapidjson/stream.h +223 -0
  250. data/ext/rj_schema/rapidjson/include/rapidjson/stringbuffer.h +121 -0
  251. data/ext/rj_schema/rapidjson/include/rapidjson/writer.h +716 -0
  252. data/ext/rj_schema/rapidjson/include_dirs.js +2 -0
  253. data/ext/rj_schema/rapidjson/library.json +15 -0
  254. data/ext/rj_schema/rapidjson/license.txt +57 -0
  255. data/ext/rj_schema/rapidjson/package.json +24 -0
  256. data/ext/rj_schema/rapidjson/rapidjson.autopkg +77 -0
  257. data/ext/rj_schema/rapidjson/readme.md +160 -0
  258. data/ext/rj_schema/rapidjson/readme.zh-cn.md +152 -0
  259. data/ext/rj_schema/rapidjson/test/CMakeLists.txt +20 -0
  260. data/ext/rj_schema/rapidjson/test/perftest/CMakeLists.txt +28 -0
  261. data/ext/rj_schema/rapidjson/test/perftest/misctest.cpp +974 -0
  262. data/ext/rj_schema/rapidjson/test/perftest/perftest.cpp +24 -0
  263. data/ext/rj_schema/rapidjson/test/perftest/perftest.h +185 -0
  264. data/ext/rj_schema/rapidjson/test/perftest/platformtest.cpp +166 -0
  265. data/ext/rj_schema/rapidjson/test/perftest/rapidjsontest.cpp +472 -0
  266. data/ext/rj_schema/rapidjson/test/perftest/schematest.cpp +216 -0
  267. data/ext/rj_schema/rapidjson/test/unittest/CMakeLists.txt +92 -0
  268. data/ext/rj_schema/rapidjson/test/unittest/allocatorstest.cpp +102 -0
  269. data/ext/rj_schema/rapidjson/test/unittest/bigintegertest.cpp +133 -0
  270. data/ext/rj_schema/rapidjson/test/unittest/cursorstreamwrappertest.cpp +115 -0
  271. data/ext/rj_schema/rapidjson/test/unittest/documenttest.cpp +672 -0
  272. data/ext/rj_schema/rapidjson/test/unittest/dtoatest.cpp +98 -0
  273. data/ext/rj_schema/rapidjson/test/unittest/encodedstreamtest.cpp +313 -0
  274. data/ext/rj_schema/rapidjson/test/unittest/encodingstest.cpp +451 -0
  275. data/ext/rj_schema/rapidjson/test/unittest/filestreamtest.cpp +112 -0
  276. data/ext/rj_schema/rapidjson/test/unittest/fwdtest.cpp +230 -0
  277. data/ext/rj_schema/rapidjson/test/unittest/istreamwrappertest.cpp +181 -0
  278. data/ext/rj_schema/rapidjson/test/unittest/itoatest.cpp +160 -0
  279. data/ext/rj_schema/rapidjson/test/unittest/jsoncheckertest.cpp +143 -0
  280. data/ext/rj_schema/rapidjson/test/unittest/namespacetest.cpp +70 -0
  281. data/ext/rj_schema/rapidjson/test/unittest/ostreamwrappertest.cpp +92 -0
  282. data/ext/rj_schema/rapidjson/test/unittest/pointertest.cpp +1529 -0
  283. data/ext/rj_schema/rapidjson/test/unittest/prettywritertest.cpp +344 -0
  284. data/ext/rj_schema/rapidjson/test/unittest/readertest.cpp +1895 -0
  285. data/ext/rj_schema/rapidjson/test/unittest/regextest.cpp +638 -0
  286. data/ext/rj_schema/rapidjson/test/unittest/schematest.cpp +2009 -0
  287. data/ext/rj_schema/rapidjson/test/unittest/simdtest.cpp +219 -0
  288. data/ext/rj_schema/rapidjson/test/unittest/strfunctest.cpp +30 -0
  289. data/ext/rj_schema/rapidjson/test/unittest/stringbuffertest.cpp +192 -0
  290. data/ext/rj_schema/rapidjson/test/unittest/strtodtest.cpp +132 -0
  291. data/ext/rj_schema/rapidjson/test/unittest/unittest.cpp +51 -0
  292. data/ext/rj_schema/rapidjson/test/unittest/unittest.h +140 -0
  293. data/ext/rj_schema/rapidjson/test/unittest/valuetest.cpp +1829 -0
  294. data/ext/rj_schema/rapidjson/test/unittest/writertest.cpp +598 -0
  295. data/ext/rj_schema/rapidjson/test/valgrind.supp +17 -0
  296. data/ext/rj_schema/rapidjson/travis-doxygen.sh +121 -0
  297. data/ext/rj_schema/rj_schema.cpp +136 -0
  298. data/lib/rj_schema.rb +7 -0
  299. metadata +371 -0
@@ -0,0 +1,344 @@
1
+ // Tencent is pleased to support the open source community by making RapidJSON available.
2
+ //
3
+ // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4
+ //
5
+ // Licensed under the MIT License (the "License"); you may not use this file except
6
+ // in compliance with the License. You may obtain a copy of the License at
7
+ //
8
+ // http://opensource.org/licenses/MIT
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software distributed
11
+ // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12
+ // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13
+ // specific language governing permissions and limitations under the License.
14
+
15
+ #include "unittest.h"
16
+ #include "rapidjson/reader.h"
17
+ #include "rapidjson/prettywriter.h"
18
+ #include "rapidjson/stringbuffer.h"
19
+ #include "rapidjson/filewritestream.h"
20
+
21
+ #ifdef __clang__
22
+ RAPIDJSON_DIAG_PUSH
23
+ RAPIDJSON_DIAG_OFF(c++98-compat)
24
+ #endif
25
+
26
+ using namespace rapidjson;
27
+
28
+ static const char kJson[] = "{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3,-1],\"u64\":1234567890123456789,\"i64\":-1234567890123456789}";
29
+ static const char kPrettyJson[] =
30
+ "{\n"
31
+ " \"hello\": \"world\",\n"
32
+ " \"t\": true,\n"
33
+ " \"f\": false,\n"
34
+ " \"n\": null,\n"
35
+ " \"i\": 123,\n"
36
+ " \"pi\": 3.1416,\n"
37
+ " \"a\": [\n"
38
+ " 1,\n"
39
+ " 2,\n"
40
+ " 3,\n"
41
+ " -1\n"
42
+ " ],\n"
43
+ " \"u64\": 1234567890123456789,\n"
44
+ " \"i64\": -1234567890123456789\n"
45
+ "}";
46
+
47
+ static const char kPrettyJson_FormatOptions_SLA[] =
48
+ "{\n"
49
+ " \"hello\": \"world\",\n"
50
+ " \"t\": true,\n"
51
+ " \"f\": false,\n"
52
+ " \"n\": null,\n"
53
+ " \"i\": 123,\n"
54
+ " \"pi\": 3.1416,\n"
55
+ " \"a\": [1, 2, 3, -1],\n"
56
+ " \"u64\": 1234567890123456789,\n"
57
+ " \"i64\": -1234567890123456789\n"
58
+ "}";
59
+
60
+ TEST(PrettyWriter, Basic) {
61
+ StringBuffer buffer;
62
+ PrettyWriter<StringBuffer> writer(buffer);
63
+ Reader reader;
64
+ StringStream s(kJson);
65
+ reader.Parse(s, writer);
66
+ EXPECT_STREQ(kPrettyJson, buffer.GetString());
67
+ }
68
+
69
+ TEST(PrettyWriter, FormatOptions) {
70
+ StringBuffer buffer;
71
+ PrettyWriter<StringBuffer> writer(buffer);
72
+ writer.SetFormatOptions(kFormatSingleLineArray);
73
+ Reader reader;
74
+ StringStream s(kJson);
75
+ reader.Parse(s, writer);
76
+ EXPECT_STREQ(kPrettyJson_FormatOptions_SLA, buffer.GetString());
77
+ }
78
+
79
+ TEST(PrettyWriter, SetIndent) {
80
+ StringBuffer buffer;
81
+ PrettyWriter<StringBuffer> writer(buffer);
82
+ writer.SetIndent('\t', 1);
83
+ Reader reader;
84
+ StringStream s(kJson);
85
+ reader.Parse(s, writer);
86
+ EXPECT_STREQ(
87
+ "{\n"
88
+ "\t\"hello\": \"world\",\n"
89
+ "\t\"t\": true,\n"
90
+ "\t\"f\": false,\n"
91
+ "\t\"n\": null,\n"
92
+ "\t\"i\": 123,\n"
93
+ "\t\"pi\": 3.1416,\n"
94
+ "\t\"a\": [\n"
95
+ "\t\t1,\n"
96
+ "\t\t2,\n"
97
+ "\t\t3,\n"
98
+ "\t\t-1\n"
99
+ "\t],\n"
100
+ "\t\"u64\": 1234567890123456789,\n"
101
+ "\t\"i64\": -1234567890123456789\n"
102
+ "}",
103
+ buffer.GetString());
104
+ }
105
+
106
+ TEST(PrettyWriter, String) {
107
+ StringBuffer buffer;
108
+ PrettyWriter<StringBuffer> writer(buffer);
109
+ EXPECT_TRUE(writer.StartArray());
110
+ EXPECT_TRUE(writer.String("Hello\n"));
111
+ EXPECT_TRUE(writer.EndArray());
112
+ EXPECT_STREQ("[\n \"Hello\\n\"\n]", buffer.GetString());
113
+ }
114
+
115
+ #if RAPIDJSON_HAS_STDSTRING
116
+ TEST(PrettyWriter, String_STDSTRING) {
117
+ StringBuffer buffer;
118
+ PrettyWriter<StringBuffer> writer(buffer);
119
+ EXPECT_TRUE(writer.StartArray());
120
+ EXPECT_TRUE(writer.String(std::string("Hello\n")));
121
+ EXPECT_TRUE(writer.EndArray());
122
+ EXPECT_STREQ("[\n \"Hello\\n\"\n]", buffer.GetString());
123
+ }
124
+ #endif
125
+
126
+ #include <sstream>
127
+
128
+ class OStreamWrapper {
129
+ public:
130
+ typedef char Ch;
131
+
132
+ OStreamWrapper(std::ostream& os) : os_(os) {}
133
+
134
+ Ch Peek() const { assert(false); return '\0'; }
135
+ Ch Take() { assert(false); return '\0'; }
136
+ size_t Tell() const { return 0; }
137
+
138
+ Ch* PutBegin() { assert(false); return 0; }
139
+ void Put(Ch c) { os_.put(c); }
140
+ void Flush() { os_.flush(); }
141
+ size_t PutEnd(Ch*) { assert(false); return 0; }
142
+
143
+ private:
144
+ OStreamWrapper(const OStreamWrapper&);
145
+ OStreamWrapper& operator=(const OStreamWrapper&);
146
+
147
+ std::ostream& os_;
148
+ };
149
+
150
+ // For covering PutN() generic version
151
+ TEST(PrettyWriter, OStreamWrapper) {
152
+ StringStream s(kJson);
153
+
154
+ std::stringstream ss;
155
+ OStreamWrapper os(ss);
156
+
157
+ PrettyWriter<OStreamWrapper> writer(os);
158
+
159
+ Reader reader;
160
+ reader.Parse(s, writer);
161
+
162
+ std::string actual = ss.str();
163
+ EXPECT_STREQ(kPrettyJson, actual.c_str());
164
+ }
165
+
166
+ // For covering FileWriteStream::PutN()
167
+ TEST(PrettyWriter, FileWriteStream) {
168
+ char filename[L_tmpnam];
169
+ FILE* fp = TempFile(filename);
170
+ ASSERT_TRUE(fp!=NULL);
171
+ char buffer[16];
172
+ FileWriteStream os(fp, buffer, sizeof(buffer));
173
+ PrettyWriter<FileWriteStream> writer(os);
174
+ Reader reader;
175
+ StringStream s(kJson);
176
+ reader.Parse(s, writer);
177
+ fclose(fp);
178
+
179
+ fp = fopen(filename, "rb");
180
+ fseek(fp, 0, SEEK_END);
181
+ size_t size = static_cast<size_t>(ftell(fp));
182
+ fseek(fp, 0, SEEK_SET);
183
+ char* json = static_cast<char*>(malloc(size + 1));
184
+ size_t readLength = fread(json, 1, size, fp);
185
+ json[readLength] = '\0';
186
+ fclose(fp);
187
+ remove(filename);
188
+ EXPECT_STREQ(kPrettyJson, json);
189
+ free(json);
190
+ }
191
+
192
+ TEST(PrettyWriter, RawValue) {
193
+ StringBuffer buffer;
194
+ PrettyWriter<StringBuffer> writer(buffer);
195
+ writer.StartObject();
196
+ writer.Key("a");
197
+ writer.Int(1);
198
+ writer.Key("raw");
199
+ const char json[] = "[\"Hello\\nWorld\", 123.456]";
200
+ writer.RawValue(json, strlen(json), kArrayType);
201
+ writer.EndObject();
202
+ EXPECT_TRUE(writer.IsComplete());
203
+ EXPECT_STREQ(
204
+ "{\n"
205
+ " \"a\": 1,\n"
206
+ " \"raw\": [\"Hello\\nWorld\", 123.456]\n" // no indentation within raw value
207
+ "}",
208
+ buffer.GetString());
209
+ }
210
+
211
+ TEST(PrettyWriter, InvalidEventSequence) {
212
+ // {]
213
+ {
214
+ StringBuffer buffer;
215
+ PrettyWriter<StringBuffer> writer(buffer);
216
+ writer.StartObject();
217
+ EXPECT_THROW(writer.EndArray(), AssertException);
218
+ EXPECT_FALSE(writer.IsComplete());
219
+ }
220
+
221
+ // [}
222
+ {
223
+ StringBuffer buffer;
224
+ PrettyWriter<StringBuffer> writer(buffer);
225
+ writer.StartArray();
226
+ EXPECT_THROW(writer.EndObject(), AssertException);
227
+ EXPECT_FALSE(writer.IsComplete());
228
+ }
229
+
230
+ // { 1:
231
+ {
232
+ StringBuffer buffer;
233
+ PrettyWriter<StringBuffer> writer(buffer);
234
+ writer.StartObject();
235
+ EXPECT_THROW(writer.Int(1), AssertException);
236
+ EXPECT_FALSE(writer.IsComplete());
237
+ }
238
+
239
+ // { 'a' }
240
+ {
241
+ StringBuffer buffer;
242
+ PrettyWriter<StringBuffer> writer(buffer);
243
+ writer.StartObject();
244
+ writer.Key("a");
245
+ EXPECT_THROW(writer.EndObject(), AssertException);
246
+ EXPECT_FALSE(writer.IsComplete());
247
+ }
248
+
249
+ // { 'a':'b','c' }
250
+ {
251
+ StringBuffer buffer;
252
+ PrettyWriter<StringBuffer> writer(buffer);
253
+ writer.StartObject();
254
+ writer.Key("a");
255
+ writer.String("b");
256
+ writer.Key("c");
257
+ EXPECT_THROW(writer.EndObject(), AssertException);
258
+ EXPECT_FALSE(writer.IsComplete());
259
+ }
260
+ }
261
+
262
+ TEST(PrettyWriter, NaN) {
263
+ double nan = std::numeric_limits<double>::quiet_NaN();
264
+
265
+ EXPECT_TRUE(internal::Double(nan).IsNan());
266
+ StringBuffer buffer;
267
+ {
268
+ PrettyWriter<StringBuffer> writer(buffer);
269
+ EXPECT_FALSE(writer.Double(nan));
270
+ }
271
+ {
272
+ PrettyWriter<StringBuffer, UTF8<>, UTF8<>, CrtAllocator, kWriteNanAndInfFlag> writer(buffer);
273
+ EXPECT_TRUE(writer.Double(nan));
274
+ EXPECT_STREQ("NaN", buffer.GetString());
275
+ }
276
+ GenericStringBuffer<UTF16<> > buffer2;
277
+ PrettyWriter<GenericStringBuffer<UTF16<> > > writer2(buffer2);
278
+ EXPECT_FALSE(writer2.Double(nan));
279
+ }
280
+
281
+ TEST(PrettyWriter, Inf) {
282
+ double inf = std::numeric_limits<double>::infinity();
283
+
284
+ EXPECT_TRUE(internal::Double(inf).IsInf());
285
+ StringBuffer buffer;
286
+ {
287
+ PrettyWriter<StringBuffer> writer(buffer);
288
+ EXPECT_FALSE(writer.Double(inf));
289
+ }
290
+ {
291
+ PrettyWriter<StringBuffer> writer(buffer);
292
+ EXPECT_FALSE(writer.Double(-inf));
293
+ }
294
+ {
295
+ PrettyWriter<StringBuffer, UTF8<>, UTF8<>, CrtAllocator, kWriteNanAndInfFlag> writer(buffer);
296
+ EXPECT_TRUE(writer.Double(inf));
297
+ }
298
+ {
299
+ PrettyWriter<StringBuffer, UTF8<>, UTF8<>, CrtAllocator, kWriteNanAndInfFlag> writer(buffer);
300
+ EXPECT_TRUE(writer.Double(-inf));
301
+ }
302
+ EXPECT_STREQ("Infinity-Infinity", buffer.GetString());
303
+ }
304
+
305
+ TEST(PrettyWriter, Issue_889) {
306
+ char buf[100] = "Hello";
307
+
308
+ StringBuffer buffer;
309
+ PrettyWriter<StringBuffer> writer(buffer);
310
+ writer.StartArray();
311
+ writer.String(buf);
312
+ writer.EndArray();
313
+
314
+ EXPECT_STREQ("[\n \"Hello\"\n]", buffer.GetString());
315
+ EXPECT_TRUE(writer.IsComplete()); \
316
+ }
317
+
318
+
319
+ #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
320
+
321
+ static PrettyWriter<StringBuffer> WriterGen(StringBuffer &target) {
322
+ PrettyWriter<StringBuffer> writer(target);
323
+ writer.StartObject();
324
+ writer.Key("a");
325
+ writer.Int(1);
326
+ return writer;
327
+ }
328
+
329
+ TEST(PrettyWriter, MoveCtor) {
330
+ StringBuffer buffer;
331
+ PrettyWriter<StringBuffer> writer(WriterGen(buffer));
332
+ writer.EndObject();
333
+ EXPECT_TRUE(writer.IsComplete());
334
+ EXPECT_STREQ(
335
+ "{\n"
336
+ " \"a\": 1\n"
337
+ "}",
338
+ buffer.GetString());
339
+ }
340
+ #endif
341
+
342
+ #ifdef __clang__
343
+ RAPIDJSON_DIAG_POP
344
+ #endif
@@ -0,0 +1,1895 @@
1
+ // Tencent is pleased to support the open source community by making RapidJSON available.
2
+ //
3
+ // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4
+ //
5
+ // Licensed under the MIT License (the "License"); you may not use this file except
6
+ // in compliance with the License. You may obtain a copy of the License at
7
+ //
8
+ // http://opensource.org/licenses/MIT
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software distributed
11
+ // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12
+ // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13
+ // specific language governing permissions and limitations under the License.
14
+
15
+ #include "unittest.h"
16
+
17
+ #include "rapidjson/reader.h"
18
+ #include "rapidjson/internal/dtoa.h"
19
+ #include "rapidjson/internal/itoa.h"
20
+ #include "rapidjson/memorystream.h"
21
+
22
+ #include <limits>
23
+
24
+ using namespace rapidjson;
25
+
26
+ RAPIDJSON_DIAG_PUSH
27
+ #ifdef __GNUC__
28
+ RAPIDJSON_DIAG_OFF(effc++)
29
+ RAPIDJSON_DIAG_OFF(float-equal)
30
+ RAPIDJSON_DIAG_OFF(missing-noreturn)
31
+ #if __GNUC__ >= 7
32
+ RAPIDJSON_DIAG_OFF(dangling-else)
33
+ #endif
34
+ #endif // __GNUC__
35
+
36
+ #ifdef __clang__
37
+ RAPIDJSON_DIAG_OFF(variadic-macros)
38
+ RAPIDJSON_DIAG_OFF(c++98-compat-pedantic)
39
+ #endif
40
+
41
+ template<bool expect>
42
+ struct ParseBoolHandler : BaseReaderHandler<UTF8<>, ParseBoolHandler<expect> > {
43
+ ParseBoolHandler() : step_(0) {}
44
+ bool Default() { ADD_FAILURE(); return false; }
45
+ // gcc 4.8.x generates warning in EXPECT_EQ(bool, bool) on this gtest version.
46
+ // Workaround with EXPECT_TRUE().
47
+ bool Bool(bool b) { /*EXPECT_EQ(expect, b); */EXPECT_TRUE(expect == b); ++step_; return true; }
48
+
49
+ unsigned step_;
50
+ };
51
+
52
+ TEST(Reader, ParseTrue) {
53
+ StringStream s("true");
54
+ ParseBoolHandler<true> h;
55
+ Reader reader;
56
+ reader.Parse(s, h);
57
+ EXPECT_EQ(1u, h.step_);
58
+ }
59
+
60
+ TEST(Reader, ParseFalse) {
61
+ StringStream s("false");
62
+ ParseBoolHandler<false> h;
63
+ Reader reader;
64
+ reader.Parse(s, h);
65
+ EXPECT_EQ(1u, h.step_);
66
+ }
67
+
68
+ struct ParseIntHandler : BaseReaderHandler<UTF8<>, ParseIntHandler> {
69
+ ParseIntHandler() : step_(0), actual_() {}
70
+ bool Default() { ADD_FAILURE(); return false; }
71
+ bool Int(int i) { actual_ = i; step_++; return true; }
72
+
73
+ unsigned step_;
74
+ int actual_;
75
+ };
76
+
77
+ struct ParseUintHandler : BaseReaderHandler<UTF8<>, ParseUintHandler> {
78
+ ParseUintHandler() : step_(0), actual_() {}
79
+ bool Default() { ADD_FAILURE(); return false; }
80
+ bool Uint(unsigned i) { actual_ = i; step_++; return true; }
81
+
82
+ unsigned step_;
83
+ unsigned actual_;
84
+ };
85
+
86
+ struct ParseInt64Handler : BaseReaderHandler<UTF8<>, ParseInt64Handler> {
87
+ ParseInt64Handler() : step_(0), actual_() {}
88
+ bool Default() { ADD_FAILURE(); return false; }
89
+ bool Int64(int64_t i) { actual_ = i; step_++; return true; }
90
+
91
+ unsigned step_;
92
+ int64_t actual_;
93
+ };
94
+
95
+ struct ParseUint64Handler : BaseReaderHandler<UTF8<>, ParseUint64Handler> {
96
+ ParseUint64Handler() : step_(0), actual_() {}
97
+ bool Default() { ADD_FAILURE(); return false; }
98
+ bool Uint64(uint64_t i) { actual_ = i; step_++; return true; }
99
+
100
+ unsigned step_;
101
+ uint64_t actual_;
102
+ };
103
+
104
+ struct ParseDoubleHandler : BaseReaderHandler<UTF8<>, ParseDoubleHandler> {
105
+ ParseDoubleHandler() : step_(0), actual_() {}
106
+ bool Default() { ADD_FAILURE(); return false; }
107
+ bool Double(double d) { actual_ = d; step_++; return true; }
108
+
109
+ unsigned step_;
110
+ double actual_;
111
+ };
112
+
113
+ TEST(Reader, ParseNumber_Integer) {
114
+ #define TEST_INTEGER(Handler, str, x) \
115
+ { \
116
+ StringStream s(str); \
117
+ Handler h; \
118
+ Reader reader; \
119
+ reader.Parse(s, h); \
120
+ EXPECT_EQ(1u, h.step_); \
121
+ EXPECT_EQ(x, h.actual_); \
122
+ }
123
+
124
+ TEST_INTEGER(ParseUintHandler, "0", 0u);
125
+ TEST_INTEGER(ParseUintHandler, "123", 123u);
126
+ TEST_INTEGER(ParseUintHandler, "2147483648", 2147483648u); // 2^31 - 1 (cannot be stored in int)
127
+ TEST_INTEGER(ParseUintHandler, "4294967295", 4294967295u);
128
+
129
+ TEST_INTEGER(ParseIntHandler, "-123", -123);
130
+ TEST_INTEGER(ParseIntHandler, "-2147483648", static_cast<int32_t>(0x80000000)); // -2^31 (min of int)
131
+
132
+ TEST_INTEGER(ParseUint64Handler, "4294967296", RAPIDJSON_UINT64_C2(1, 0)); // 2^32 (max of unsigned + 1, force to use uint64_t)
133
+ TEST_INTEGER(ParseUint64Handler, "18446744073709551615", RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF)); // 2^64 - 1 (max of uint64_t)
134
+
135
+ TEST_INTEGER(ParseInt64Handler, "-2147483649", static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x7FFFFFFF))); // -2^31 -1 (min of int - 1, force to use int64_t)
136
+ TEST_INTEGER(ParseInt64Handler, "-9223372036854775808", static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))); // -2^63 (min of int64_t)
137
+
138
+ // Random test for uint32_t/int32_t
139
+ {
140
+ union {
141
+ uint32_t u;
142
+ int32_t i;
143
+ }u;
144
+ Random r;
145
+
146
+ for (unsigned i = 0; i < 100000; i++) {
147
+ u.u = r();
148
+
149
+ char buffer[32];
150
+ *internal::u32toa(u.u, buffer) = '\0';
151
+ TEST_INTEGER(ParseUintHandler, buffer, u.u);
152
+
153
+ if (u.i < 0) {
154
+ *internal::i32toa(u.i, buffer) = '\0';
155
+ TEST_INTEGER(ParseIntHandler, buffer, u.i);
156
+ }
157
+ }
158
+ }
159
+
160
+ // Random test for uint64_t/int64_t
161
+ {
162
+ union {
163
+ uint64_t u;
164
+ int64_t i;
165
+ }u;
166
+ Random r;
167
+
168
+ for (unsigned i = 0; i < 100000; i++) {
169
+ u.u = uint64_t(r()) << 32;
170
+ u.u |= r();
171
+
172
+ char buffer[32];
173
+ if (u.u > uint64_t(4294967295u)) {
174
+ *internal::u64toa(u.u, buffer) = '\0';
175
+ TEST_INTEGER(ParseUint64Handler, buffer, u.u);
176
+ }
177
+
178
+ if (u.i < -int64_t(2147483648u)) {
179
+ *internal::i64toa(u.i, buffer) = '\0';
180
+ TEST_INTEGER(ParseInt64Handler, buffer, u.i);
181
+ }
182
+ }
183
+ }
184
+ #undef TEST_INTEGER
185
+ }
186
+
187
+ template<bool fullPrecision>
188
+ static void TestParseDouble() {
189
+ #define TEST_DOUBLE(fullPrecision, str, x) \
190
+ { \
191
+ StringStream s(str); \
192
+ ParseDoubleHandler h; \
193
+ Reader reader; \
194
+ ASSERT_EQ(kParseErrorNone, reader.Parse<fullPrecision ? kParseFullPrecisionFlag : 0>(s, h).Code()); \
195
+ EXPECT_EQ(1u, h.step_); \
196
+ internal::Double e(x), a(h.actual_); \
197
+ if (fullPrecision) { \
198
+ EXPECT_EQ(e.Uint64Value(), a.Uint64Value()); \
199
+ if (e.Uint64Value() != a.Uint64Value()) \
200
+ printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", str, h.actual_, x); \
201
+ } \
202
+ else { \
203
+ EXPECT_EQ(e.Sign(), a.Sign()); /* for 0.0 != -0.0 */ \
204
+ EXPECT_DOUBLE_EQ(x, h.actual_); \
205
+ } \
206
+ }
207
+
208
+ TEST_DOUBLE(fullPrecision, "0.0", 0.0);
209
+ TEST_DOUBLE(fullPrecision, "-0.0", -0.0); // For checking issue #289
210
+ TEST_DOUBLE(fullPrecision, "1.0", 1.0);
211
+ TEST_DOUBLE(fullPrecision, "-1.0", -1.0);
212
+ TEST_DOUBLE(fullPrecision, "1.5", 1.5);
213
+ TEST_DOUBLE(fullPrecision, "-1.5", -1.5);
214
+ TEST_DOUBLE(fullPrecision, "3.1416", 3.1416);
215
+ TEST_DOUBLE(fullPrecision, "1E10", 1E10);
216
+ TEST_DOUBLE(fullPrecision, "1e10", 1e10);
217
+ TEST_DOUBLE(fullPrecision, "1E+10", 1E+10);
218
+ TEST_DOUBLE(fullPrecision, "1E-10", 1E-10);
219
+ TEST_DOUBLE(fullPrecision, "-1E10", -1E10);
220
+ TEST_DOUBLE(fullPrecision, "-1e10", -1e10);
221
+ TEST_DOUBLE(fullPrecision, "-1E+10", -1E+10);
222
+ TEST_DOUBLE(fullPrecision, "-1E-10", -1E-10);
223
+ TEST_DOUBLE(fullPrecision, "1.234E+10", 1.234E+10);
224
+ TEST_DOUBLE(fullPrecision, "1.234E-10", 1.234E-10);
225
+ TEST_DOUBLE(fullPrecision, "1.79769e+308", 1.79769e+308);
226
+ TEST_DOUBLE(fullPrecision, "2.22507e-308", 2.22507e-308);
227
+ TEST_DOUBLE(fullPrecision, "-1.79769e+308", -1.79769e+308);
228
+ TEST_DOUBLE(fullPrecision, "-2.22507e-308", -2.22507e-308);
229
+ TEST_DOUBLE(fullPrecision, "4.9406564584124654e-324", 4.9406564584124654e-324); // minimum denormal
230
+ TEST_DOUBLE(fullPrecision, "2.2250738585072009e-308", 2.2250738585072009e-308); // Max subnormal double
231
+ TEST_DOUBLE(fullPrecision, "2.2250738585072014e-308", 2.2250738585072014e-308); // Min normal positive double
232
+ TEST_DOUBLE(fullPrecision, "1.7976931348623157e+308", 1.7976931348623157e+308); // Max double
233
+ TEST_DOUBLE(fullPrecision, "1e-10000", 0.0); // must underflow
234
+ TEST_DOUBLE(fullPrecision, "18446744073709551616", 18446744073709551616.0); // 2^64 (max of uint64_t + 1, force to use double)
235
+ TEST_DOUBLE(fullPrecision, "-9223372036854775809", -9223372036854775809.0); // -2^63 - 1(min of int64_t + 1, force to use double)
236
+ TEST_DOUBLE(fullPrecision, "0.9868011474609375", 0.9868011474609375); // https://github.com/Tencent/rapidjson/issues/120
237
+ TEST_DOUBLE(fullPrecision, "123e34", 123e34); // Fast Path Cases In Disguise
238
+ TEST_DOUBLE(fullPrecision, "45913141877270640000.0", 45913141877270640000.0);
239
+ TEST_DOUBLE(fullPrecision, "2.2250738585072011e-308", 2.2250738585072011e-308); // http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
240
+ TEST_DOUBLE(fullPrecision, "1e-00011111111111", 0.0); // Issue #313
241
+ TEST_DOUBLE(fullPrecision, "-1e-00011111111111", -0.0);
242
+ TEST_DOUBLE(fullPrecision, "1e-214748363", 0.0); // Maximum supported negative exponent
243
+ TEST_DOUBLE(fullPrecision, "1e-214748364", 0.0);
244
+ TEST_DOUBLE(fullPrecision, "1e-21474836311", 0.0);
245
+ TEST_DOUBLE(fullPrecision, "0.017976931348623157e+310", 1.7976931348623157e+308); // Max double in another form
246
+
247
+ // Since
248
+ // abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599... x 10^-324
249
+ // abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044... x 10 ^ -324
250
+ // So 2.2250738585072012e-308 should round to 2^-1022 = 2.2250738585072014e-308
251
+ TEST_DOUBLE(fullPrecision, "2.2250738585072012e-308", 2.2250738585072014e-308); // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
252
+
253
+ // More closer to normal/subnormal boundary
254
+ // boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648... x 10^-308
255
+ TEST_DOUBLE(fullPrecision, "2.22507385850720113605740979670913197593481954635164564e-308", 2.2250738585072009e-308);
256
+ TEST_DOUBLE(fullPrecision, "2.22507385850720113605740979670913197593481954635164565e-308", 2.2250738585072014e-308);
257
+
258
+ // 1.0 is in (1.0 - 2^-54, 1.0 + 2^-53)
259
+ // 1.0 - 2^-54 = 0.999999999999999944488848768742172978818416595458984375
260
+ TEST_DOUBLE(fullPrecision, "0.999999999999999944488848768742172978818416595458984375", 1.0); // round to even
261
+ TEST_DOUBLE(fullPrecision, "0.999999999999999944488848768742172978818416595458984374", 0.99999999999999989); // previous double
262
+ TEST_DOUBLE(fullPrecision, "0.999999999999999944488848768742172978818416595458984376", 1.0); // next double
263
+ // 1.0 + 2^-53 = 1.00000000000000011102230246251565404236316680908203125
264
+ TEST_DOUBLE(fullPrecision, "1.00000000000000011102230246251565404236316680908203125", 1.0); // round to even
265
+ TEST_DOUBLE(fullPrecision, "1.00000000000000011102230246251565404236316680908203124", 1.0); // previous double
266
+ TEST_DOUBLE(fullPrecision, "1.00000000000000011102230246251565404236316680908203126", 1.00000000000000022); // next double
267
+
268
+ // Numbers from https://github.com/floitsch/double-conversion/blob/master/test/cctest/test-strtod.cc
269
+
270
+ TEST_DOUBLE(fullPrecision, "72057594037927928.0", 72057594037927928.0);
271
+ TEST_DOUBLE(fullPrecision, "72057594037927936.0", 72057594037927936.0);
272
+ TEST_DOUBLE(fullPrecision, "72057594037927932.0", 72057594037927936.0);
273
+ TEST_DOUBLE(fullPrecision, "7205759403792793199999e-5", 72057594037927928.0);
274
+ TEST_DOUBLE(fullPrecision, "7205759403792793200001e-5", 72057594037927936.0);
275
+
276
+ TEST_DOUBLE(fullPrecision, "9223372036854774784.0", 9223372036854774784.0);
277
+ TEST_DOUBLE(fullPrecision, "9223372036854775808.0", 9223372036854775808.0);
278
+ TEST_DOUBLE(fullPrecision, "9223372036854775296.0", 9223372036854775808.0);
279
+ TEST_DOUBLE(fullPrecision, "922337203685477529599999e-5", 9223372036854774784.0);
280
+ TEST_DOUBLE(fullPrecision, "922337203685477529600001e-5", 9223372036854775808.0);
281
+
282
+ TEST_DOUBLE(fullPrecision, "10141204801825834086073718800384", 10141204801825834086073718800384.0);
283
+ TEST_DOUBLE(fullPrecision, "10141204801825835211973625643008", 10141204801825835211973625643008.0);
284
+ TEST_DOUBLE(fullPrecision, "10141204801825834649023672221696", 10141204801825835211973625643008.0);
285
+ TEST_DOUBLE(fullPrecision, "1014120480182583464902367222169599999e-5", 10141204801825834086073718800384.0);
286
+ TEST_DOUBLE(fullPrecision, "1014120480182583464902367222169600001e-5", 10141204801825835211973625643008.0);
287
+
288
+ TEST_DOUBLE(fullPrecision, "5708990770823838890407843763683279797179383808", 5708990770823838890407843763683279797179383808.0);
289
+ TEST_DOUBLE(fullPrecision, "5708990770823839524233143877797980545530986496", 5708990770823839524233143877797980545530986496.0);
290
+ TEST_DOUBLE(fullPrecision, "5708990770823839207320493820740630171355185152", 5708990770823839524233143877797980545530986496.0);
291
+ TEST_DOUBLE(fullPrecision, "5708990770823839207320493820740630171355185151999e-3", 5708990770823838890407843763683279797179383808.0);
292
+ TEST_DOUBLE(fullPrecision, "5708990770823839207320493820740630171355185152001e-3", 5708990770823839524233143877797980545530986496.0);
293
+
294
+ {
295
+ char n1e308[310]; // '1' followed by 308 '0'
296
+ n1e308[0] = '1';
297
+ for (int i = 1; i < 309; i++)
298
+ n1e308[i] = '0';
299
+ n1e308[309] = '\0';
300
+ TEST_DOUBLE(fullPrecision, n1e308, 1E308);
301
+ }
302
+
303
+ // Cover trimming
304
+ TEST_DOUBLE(fullPrecision,
305
+ "2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508"
306
+ "7914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012"
307
+ "9811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306"
308
+ "6665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505"
309
+ "1080609940730262937128958950003583799967207254304360284078895771796150945516748243471030702609144621"
310
+ "5722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844"
311
+ "2390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042"
312
+ "7567186443383770486037861622771738545623065874679014086723327636718751234567890123456789012345678901"
313
+ "e-308",
314
+ 2.2250738585072014e-308);
315
+
316
+ {
317
+ static const unsigned count = 100; // Tested with 1000000 locally
318
+ Random r;
319
+ Reader reader; // Reusing reader to prevent heap allocation
320
+
321
+ // Exhaustively test different exponents with random significant
322
+ for (uint64_t exp = 0; exp < 2047; exp++) {
323
+ ;
324
+ for (unsigned i = 0; i < count; i++) {
325
+ // Need to call r() in two statements for cross-platform coherent sequence.
326
+ uint64_t u = (exp << 52) | uint64_t(r() & 0x000FFFFF) << 32;
327
+ u |= uint64_t(r());
328
+ internal::Double d = internal::Double(u);
329
+
330
+ char buffer[32];
331
+ *internal::dtoa(d.Value(), buffer) = '\0';
332
+
333
+ StringStream s(buffer);
334
+ ParseDoubleHandler h;
335
+ ASSERT_EQ(kParseErrorNone, reader.Parse<fullPrecision ? kParseFullPrecisionFlag : 0>(s, h).Code());
336
+ EXPECT_EQ(1u, h.step_);
337
+ internal::Double a(h.actual_);
338
+ if (fullPrecision) {
339
+ EXPECT_EQ(d.Uint64Value(), a.Uint64Value());
340
+ if (d.Uint64Value() != a.Uint64Value())
341
+ printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", buffer, h.actual_, d.Value());
342
+ }
343
+ else {
344
+ EXPECT_EQ(d.Sign(), a.Sign()); // for 0.0 != -0.0
345
+ EXPECT_DOUBLE_EQ(d.Value(), h.actual_);
346
+ }
347
+ }
348
+ }
349
+ }
350
+
351
+ // Issue #340
352
+ TEST_DOUBLE(fullPrecision, "7.450580596923828e-9", 7.450580596923828e-9);
353
+ {
354
+ internal::Double d(1.0);
355
+ for (int i = 0; i < 324; i++) {
356
+ char buffer[32];
357
+ *internal::dtoa(d.Value(), buffer) = '\0';
358
+
359
+ StringStream s(buffer);
360
+ ParseDoubleHandler h;
361
+ Reader reader;
362
+ ASSERT_EQ(kParseErrorNone, reader.Parse<fullPrecision ? kParseFullPrecisionFlag : 0>(s, h).Code());
363
+ EXPECT_EQ(1u, h.step_);
364
+ internal::Double a(h.actual_);
365
+ if (fullPrecision) {
366
+ EXPECT_EQ(d.Uint64Value(), a.Uint64Value());
367
+ if (d.Uint64Value() != a.Uint64Value())
368
+ printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", buffer, h.actual_, d.Value());
369
+ }
370
+ else {
371
+ EXPECT_EQ(d.Sign(), a.Sign()); // for 0.0 != -0.0
372
+ EXPECT_DOUBLE_EQ(d.Value(), h.actual_);
373
+ }
374
+
375
+
376
+ d = d.Value() * 0.5;
377
+ }
378
+ }
379
+ #undef TEST_DOUBLE
380
+ }
381
+
382
+ TEST(Reader, ParseNumber_NormalPrecisionDouble) {
383
+ TestParseDouble<false>();
384
+ }
385
+
386
+ TEST(Reader, ParseNumber_FullPrecisionDouble) {
387
+ TestParseDouble<true>();
388
+ }
389
+
390
+ TEST(Reader, ParseNumber_NormalPrecisionError) {
391
+ static unsigned count = 1000000;
392
+ Random r;
393
+
394
+ double ulpSum = 0.0;
395
+ double ulpMax = 0.0;
396
+ for (unsigned i = 0; i < count; i++) {
397
+ internal::Double e, a;
398
+ do {
399
+ // Need to call r() in two statements for cross-platform coherent sequence.
400
+ uint64_t u = uint64_t(r()) << 32;
401
+ u |= uint64_t(r());
402
+ e = u;
403
+ } while (e.IsNan() || e.IsInf() || !e.IsNormal());
404
+
405
+ char buffer[32];
406
+ *internal::dtoa(e.Value(), buffer) = '\0';
407
+
408
+ StringStream s(buffer);
409
+ ParseDoubleHandler h;
410
+ Reader reader;
411
+ ASSERT_EQ(kParseErrorNone, reader.Parse(s, h).Code());
412
+ EXPECT_EQ(1u, h.step_);
413
+
414
+ a = h.actual_;
415
+ uint64_t bias1 = e.ToBias();
416
+ uint64_t bias2 = a.ToBias();
417
+ double ulp = static_cast<double>(bias1 >= bias2 ? bias1 - bias2 : bias2 - bias1);
418
+ ulpMax = (std::max)(ulpMax, ulp);
419
+ ulpSum += ulp;
420
+ }
421
+ printf("ULP Average = %g, Max = %g \n", ulpSum / count, ulpMax);
422
+ }
423
+
424
+ TEST(Reader, ParseNumber_Error) {
425
+ #define TEST_NUMBER_ERROR(errorCode, str, errorOffset, streamPos) \
426
+ { \
427
+ char buffer[1001]; \
428
+ sprintf(buffer, "%s", str); \
429
+ InsituStringStream s(buffer); \
430
+ BaseReaderHandler<> h; \
431
+ Reader reader; \
432
+ EXPECT_FALSE(reader.Parse(s, h)); \
433
+ EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
434
+ EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
435
+ EXPECT_EQ(streamPos, s.Tell());\
436
+ }
437
+
438
+ // Number too big to be stored in double.
439
+ {
440
+ char n1e309[311]; // '1' followed by 309 '0'
441
+ n1e309[0] = '1';
442
+ for (int i = 1; i < 310; i++)
443
+ n1e309[i] = '0';
444
+ n1e309[310] = '\0';
445
+ TEST_NUMBER_ERROR(kParseErrorNumberTooBig, n1e309, 0, 309);
446
+ }
447
+ TEST_NUMBER_ERROR(kParseErrorNumberTooBig, "1e309", 0, 5);
448
+
449
+ // Miss fraction part in number.
450
+ TEST_NUMBER_ERROR(kParseErrorNumberMissFraction, "1.", 2, 2);
451
+ TEST_NUMBER_ERROR(kParseErrorNumberMissFraction, "1.a", 2, 2);
452
+
453
+ // Miss exponent in number.
454
+ TEST_NUMBER_ERROR(kParseErrorNumberMissExponent, "1e", 2, 2);
455
+ TEST_NUMBER_ERROR(kParseErrorNumberMissExponent, "1e_", 2, 2);
456
+
457
+ #undef TEST_NUMBER_ERROR
458
+ }
459
+
460
+ template <typename Encoding>
461
+ struct ParseStringHandler : BaseReaderHandler<Encoding, ParseStringHandler<Encoding> > {
462
+ ParseStringHandler() : str_(0), length_(0), copy_() {}
463
+ ~ParseStringHandler() { EXPECT_TRUE(str_ != 0); if (copy_) free(const_cast<typename Encoding::Ch*>(str_)); }
464
+
465
+ ParseStringHandler(const ParseStringHandler&);
466
+ ParseStringHandler& operator=(const ParseStringHandler&);
467
+
468
+ bool Default() { ADD_FAILURE(); return false; }
469
+ bool String(const typename Encoding::Ch* str, size_t length, bool copy) {
470
+ EXPECT_EQ(0, str_);
471
+ if (copy) {
472
+ str_ = static_cast<typename Encoding::Ch*>(malloc((length + 1) * sizeof(typename Encoding::Ch)));
473
+ memcpy(const_cast<typename Encoding::Ch*>(str_), str, (length + 1) * sizeof(typename Encoding::Ch));
474
+ }
475
+ else
476
+ str_ = str;
477
+ length_ = length;
478
+ copy_ = copy;
479
+ return true;
480
+ }
481
+
482
+ const typename Encoding::Ch* str_;
483
+ size_t length_;
484
+ bool copy_;
485
+ };
486
+
487
+ TEST(Reader, ParseString) {
488
+ #define TEST_STRING(Encoding, e, x) \
489
+ { \
490
+ Encoding::Ch* buffer = StrDup(x); \
491
+ GenericInsituStringStream<Encoding> is(buffer); \
492
+ ParseStringHandler<Encoding> h; \
493
+ GenericReader<Encoding, Encoding> reader; \
494
+ reader.Parse<kParseInsituFlag | kParseValidateEncodingFlag>(is, h); \
495
+ EXPECT_EQ(0, StrCmp<Encoding::Ch>(e, h.str_)); \
496
+ EXPECT_EQ(StrLen(e), h.length_); \
497
+ free(buffer); \
498
+ GenericStringStream<Encoding> s(x); \
499
+ ParseStringHandler<Encoding> h2; \
500
+ GenericReader<Encoding, Encoding> reader2; \
501
+ reader2.Parse(s, h2); \
502
+ EXPECT_EQ(0, StrCmp<Encoding::Ch>(e, h2.str_)); \
503
+ EXPECT_EQ(StrLen(e), h2.length_); \
504
+ }
505
+
506
+ // String constant L"\xXX" can only specify character code in bytes, which is not endianness-neutral.
507
+ // And old compiler does not support u"" and U"" string literal. So here specify string literal by array of Ch.
508
+ // In addition, GCC 4.8 generates -Wnarrowing warnings when character code >= 128 are assigned to signed integer types.
509
+ // Therefore, utype is added for declaring unsigned array, and then cast it to Encoding::Ch.
510
+ #define ARRAY(...) { __VA_ARGS__ }
511
+ #define TEST_STRINGARRAY(Encoding, utype, array, x) \
512
+ { \
513
+ static const utype ue[] = array; \
514
+ static const Encoding::Ch* e = reinterpret_cast<const Encoding::Ch *>(&ue[0]); \
515
+ TEST_STRING(Encoding, e, x); \
516
+ }
517
+
518
+ #define TEST_STRINGARRAY2(Encoding, utype, earray, xarray) \
519
+ { \
520
+ static const utype ue[] = earray; \
521
+ static const utype xe[] = xarray; \
522
+ static const Encoding::Ch* e = reinterpret_cast<const Encoding::Ch *>(&ue[0]); \
523
+ static const Encoding::Ch* x = reinterpret_cast<const Encoding::Ch *>(&xe[0]); \
524
+ TEST_STRING(Encoding, e, x); \
525
+ }
526
+
527
+ TEST_STRING(UTF8<>, "", "\"\"");
528
+ TEST_STRING(UTF8<>, "Hello", "\"Hello\"");
529
+ TEST_STRING(UTF8<>, "Hello\nWorld", "\"Hello\\nWorld\"");
530
+ TEST_STRING(UTF8<>, "\"\\/\b\f\n\r\t", "\"\\\"\\\\/\\b\\f\\n\\r\\t\"");
531
+ TEST_STRING(UTF8<>, "\x24", "\"\\u0024\""); // Dollar sign U+0024
532
+ TEST_STRING(UTF8<>, "\xC2\xA2", "\"\\u00A2\""); // Cents sign U+00A2
533
+ TEST_STRING(UTF8<>, "\xE2\x82\xAC", "\"\\u20AC\""); // Euro sign U+20AC
534
+ TEST_STRING(UTF8<>, "\xF0\x9D\x84\x9E", "\"\\uD834\\uDD1E\""); // G clef sign U+1D11E
535
+
536
+ // UTF16
537
+ TEST_STRING(UTF16<>, L"", L"\"\"");
538
+ TEST_STRING(UTF16<>, L"Hello", L"\"Hello\"");
539
+ TEST_STRING(UTF16<>, L"Hello\nWorld", L"\"Hello\\nWorld\"");
540
+ TEST_STRING(UTF16<>, L"\"\\/\b\f\n\r\t", L"\"\\\"\\\\/\\b\\f\\n\\r\\t\"");
541
+ TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0x0024, 0x0000), L"\"\\u0024\"");
542
+ TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0x00A2, 0x0000), L"\"\\u00A2\""); // Cents sign U+00A2
543
+ TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0x20AC, 0x0000), L"\"\\u20AC\""); // Euro sign U+20AC
544
+ TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0xD834, 0xDD1E, 0x0000), L"\"\\uD834\\uDD1E\""); // G clef sign U+1D11E
545
+
546
+ // UTF32
547
+ TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('\0'), ARRAY('\"', '\"', '\0'));
548
+ TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('H', 'e', 'l', 'l', 'o', '\0'), ARRAY('\"', 'H', 'e', 'l', 'l', 'o', '\"', '\0'));
549
+ TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('H', 'e', 'l', 'l', 'o', '\n', 'W', 'o', 'r', 'l', 'd', '\0'), ARRAY('\"', 'H', 'e', 'l', 'l', 'o', '\\', 'n', 'W', 'o', 'r', 'l', 'd', '\"', '\0'));
550
+ TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('\"', '\\', '/', '\b', '\f', '\n', '\r', '\t', '\0'), ARRAY('\"', '\\', '\"', '\\', '\\', '/', '\\', 'b', '\\', 'f', '\\', 'n', '\\', 'r', '\\', 't', '\"', '\0'));
551
+ TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x00024, 0x0000), ARRAY('\"', '\\', 'u', '0', '0', '2', '4', '\"', '\0'));
552
+ TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x000A2, 0x0000), ARRAY('\"', '\\', 'u', '0', '0', 'A', '2', '\"', '\0')); // Cents sign U+00A2
553
+ TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x020AC, 0x0000), ARRAY('\"', '\\', 'u', '2', '0', 'A', 'C', '\"', '\0')); // Euro sign U+20AC
554
+ TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x1D11E, 0x0000), ARRAY('\"', '\\', 'u', 'D', '8', '3', '4', '\\', 'u', 'D', 'D', '1', 'E', '\"', '\0')); // G clef sign U+1D11E
555
+
556
+ #undef TEST_STRINGARRAY
557
+ #undef ARRAY
558
+ #undef TEST_STRING
559
+
560
+ // Support of null character in string
561
+ {
562
+ StringStream s("\"Hello\\u0000World\"");
563
+ const char e[] = "Hello\0World";
564
+ ParseStringHandler<UTF8<> > h;
565
+ Reader reader;
566
+ reader.Parse(s, h);
567
+ EXPECT_EQ(0, memcmp(e, h.str_, h.length_ + 1));
568
+ EXPECT_EQ(11u, h.length_);
569
+ }
570
+ }
571
+
572
+ TEST(Reader, ParseString_Transcoding) {
573
+ const char* x = "\"Hello\"";
574
+ const wchar_t* e = L"Hello";
575
+ GenericStringStream<UTF8<> > is(x);
576
+ GenericReader<UTF8<>, UTF16<> > reader;
577
+ ParseStringHandler<UTF16<> > h;
578
+ reader.Parse(is, h);
579
+ EXPECT_EQ(0, StrCmp<UTF16<>::Ch>(e, h.str_));
580
+ EXPECT_EQ(StrLen(e), h.length_);
581
+ }
582
+
583
+ TEST(Reader, ParseString_TranscodingWithValidation) {
584
+ const char* x = "\"Hello\"";
585
+ const wchar_t* e = L"Hello";
586
+ GenericStringStream<UTF8<> > is(x);
587
+ GenericReader<UTF8<>, UTF16<> > reader;
588
+ ParseStringHandler<UTF16<> > h;
589
+ reader.Parse<kParseValidateEncodingFlag>(is, h);
590
+ EXPECT_EQ(0, StrCmp<UTF16<>::Ch>(e, h.str_));
591
+ EXPECT_EQ(StrLen(e), h.length_);
592
+ }
593
+
594
+ TEST(Reader, ParseString_NonDestructive) {
595
+ StringStream s("\"Hello\\nWorld\"");
596
+ ParseStringHandler<UTF8<> > h;
597
+ Reader reader;
598
+ reader.Parse(s, h);
599
+ EXPECT_EQ(0, StrCmp("Hello\nWorld", h.str_));
600
+ EXPECT_EQ(11u, h.length_);
601
+ }
602
+
603
+ template <typename Encoding>
604
+ ParseErrorCode TestString(const typename Encoding::Ch* str) {
605
+ GenericStringStream<Encoding> s(str);
606
+ BaseReaderHandler<Encoding> h;
607
+ GenericReader<Encoding, Encoding> reader;
608
+ reader.template Parse<kParseValidateEncodingFlag>(s, h);
609
+ return reader.GetParseErrorCode();
610
+ }
611
+
612
+ TEST(Reader, ParseString_Error) {
613
+ #define TEST_STRING_ERROR(errorCode, str, errorOffset, streamPos)\
614
+ {\
615
+ GenericStringStream<UTF8<> > s(str);\
616
+ BaseReaderHandler<UTF8<> > h;\
617
+ GenericReader<UTF8<> , UTF8<> > reader;\
618
+ reader.Parse<kParseValidateEncodingFlag>(s, h);\
619
+ EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
620
+ EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
621
+ EXPECT_EQ(streamPos, s.Tell());\
622
+ }
623
+
624
+ #define ARRAY(...) { __VA_ARGS__ }
625
+ #define TEST_STRINGENCODING_ERROR(Encoding, TargetEncoding, utype, array) \
626
+ { \
627
+ static const utype ue[] = array; \
628
+ static const Encoding::Ch* e = reinterpret_cast<const Encoding::Ch *>(&ue[0]); \
629
+ EXPECT_EQ(kParseErrorStringInvalidEncoding, TestString<Encoding>(e));\
630
+ /* decode error */\
631
+ GenericStringStream<Encoding> s(e);\
632
+ BaseReaderHandler<TargetEncoding> h;\
633
+ GenericReader<Encoding, TargetEncoding> reader;\
634
+ reader.Parse(s, h);\
635
+ EXPECT_EQ(kParseErrorStringInvalidEncoding, reader.GetParseErrorCode());\
636
+ }
637
+
638
+ // Invalid escape character in string.
639
+ TEST_STRING_ERROR(kParseErrorStringEscapeInvalid, "[\"\\a\"]", 2, 3);
640
+
641
+ // Incorrect hex digit after \\u escape in string.
642
+ TEST_STRING_ERROR(kParseErrorStringUnicodeEscapeInvalidHex, "[\"\\uABCG\"]", 2, 7);
643
+
644
+ // Quotation in \\u escape in string (Issue #288)
645
+ TEST_STRING_ERROR(kParseErrorStringUnicodeEscapeInvalidHex, "[\"\\uaaa\"]", 2, 7);
646
+ TEST_STRING_ERROR(kParseErrorStringUnicodeEscapeInvalidHex, "[\"\\uD800\\uFFF\"]", 2, 13);
647
+
648
+ // The surrogate pair in string is invalid.
649
+ TEST_STRING_ERROR(kParseErrorStringUnicodeSurrogateInvalid, "[\"\\uD800X\"]", 2, 8);
650
+ TEST_STRING_ERROR(kParseErrorStringUnicodeSurrogateInvalid, "[\"\\uD800\\uFFFF\"]", 2, 14);
651
+
652
+ // Missing a closing quotation mark in string.
653
+ TEST_STRING_ERROR(kParseErrorStringMissQuotationMark, "[\"Test]", 7, 7);
654
+
655
+ // http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
656
+
657
+ // 3 Malformed sequences
658
+
659
+ // 3.1 Unexpected continuation bytes
660
+ {
661
+ char e[] = { '[', '\"', 0, '\"', ']', '\0' };
662
+ for (unsigned char c = 0x80u; c <= 0xBFu; c++) {
663
+ e[2] = static_cast<char>(c);
664
+ ParseErrorCode error = TestString<UTF8<> >(e);
665
+ EXPECT_EQ(kParseErrorStringInvalidEncoding, error);
666
+ if (error != kParseErrorStringInvalidEncoding)
667
+ std::cout << static_cast<unsigned>(c) << std::endl;
668
+ }
669
+ }
670
+
671
+ // 3.2 Lonely start characters, 3.5 Impossible bytes
672
+ {
673
+ char e[] = { '[', '\"', 0, ' ', '\"', ']', '\0' };
674
+ for (unsigned c = 0xC0u; c <= 0xFFu; c++) {
675
+ e[2] = static_cast<char>(c);
676
+ int streamPos;
677
+ if (c <= 0xC1u)
678
+ streamPos = 3; // 0xC0 - 0xC1
679
+ else if (c <= 0xDFu)
680
+ streamPos = 4; // 0xC2 - 0xDF
681
+ else if (c <= 0xEFu)
682
+ streamPos = 5; // 0xE0 - 0xEF
683
+ else if (c <= 0xF4u)
684
+ streamPos = 6; // 0xF0 - 0xF4
685
+ else
686
+ streamPos = 3; // 0xF5 - 0xFF
687
+ TEST_STRING_ERROR(kParseErrorStringInvalidEncoding, e, 2, streamPos);
688
+ }
689
+ }
690
+
691
+ // 4 Overlong sequences
692
+
693
+ // 4.1 Examples of an overlong ASCII character
694
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC0u, 0xAFu, '\"', ']', '\0'));
695
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x80u, 0xAFu, '\"', ']', '\0'));
696
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x80u, 0x80u, 0xAFu, '\"', ']', '\0'));
697
+
698
+ // 4.2 Maximum overlong sequences
699
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC1u, 0xBFu, '\"', ']', '\0'));
700
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x9Fu, 0xBFu, '\"', ']', '\0'));
701
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x8Fu, 0xBFu, 0xBFu, '\"', ']', '\0'));
702
+
703
+ // 4.3 Overlong representation of the NUL character
704
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC0u, 0x80u, '\"', ']', '\0'));
705
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x80u, 0x80u, '\"', ']', '\0'));
706
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x80u, 0x80u, 0x80u, '\"', ']', '\0'));
707
+
708
+ // 5 Illegal code positions
709
+
710
+ // 5.1 Single UTF-16 surrogates
711
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xA0u, 0x80u, '\"', ']', '\0'));
712
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xADu, 0xBFu, '\"', ']', '\0'));
713
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xAEu, 0x80u, '\"', ']', '\0'));
714
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xAFu, 0xBFu, '\"', ']', '\0'));
715
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xB0u, 0x80u, '\"', ']', '\0'));
716
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xBEu, 0x80u, '\"', ']', '\0'));
717
+ TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xBFu, 0xBFu, '\"', ']', '\0'));
718
+
719
+ // Malform UTF-16 sequences
720
+ TEST_STRINGENCODING_ERROR(UTF16<>, UTF8<>, wchar_t, ARRAY('[', '\"', 0xDC00, 0xDC00, '\"', ']', '\0'));
721
+ TEST_STRINGENCODING_ERROR(UTF16<>, UTF8<>, wchar_t, ARRAY('[', '\"', 0xD800, 0xD800, '\"', ']', '\0'));
722
+
723
+ // Malform UTF-32 sequence
724
+ TEST_STRINGENCODING_ERROR(UTF32<>, UTF8<>, unsigned, ARRAY('[', '\"', 0x110000, '\"', ']', '\0'));
725
+
726
+ // Malform ASCII sequence
727
+ TEST_STRINGENCODING_ERROR(ASCII<>, UTF8<>, char, ARRAY('[', '\"', char(0x80u), '\"', ']', '\0'));
728
+ TEST_STRINGENCODING_ERROR(ASCII<>, UTF8<>, char, ARRAY('[', '\"', char(0x01u), '\"', ']', '\0'));
729
+ TEST_STRINGENCODING_ERROR(ASCII<>, UTF8<>, char, ARRAY('[', '\"', char(0x1Cu), '\"', ']', '\0'));
730
+
731
+ #undef ARRAY
732
+ #undef TEST_STRINGARRAY_ERROR
733
+ }
734
+
735
+ template <unsigned count>
736
+ struct ParseArrayHandler : BaseReaderHandler<UTF8<>, ParseArrayHandler<count> > {
737
+ ParseArrayHandler() : step_(0) {}
738
+
739
+ bool Default() { ADD_FAILURE(); return false; }
740
+ bool Uint(unsigned i) { EXPECT_EQ(step_, i); step_++; return true; }
741
+ bool StartArray() { EXPECT_EQ(0u, step_); step_++; return true; }
742
+ bool EndArray(SizeType) { step_++; return true; }
743
+
744
+ unsigned step_;
745
+ };
746
+
747
+ TEST(Reader, ParseEmptyArray) {
748
+ char *json = StrDup("[ ] ");
749
+ InsituStringStream s(json);
750
+ ParseArrayHandler<0> h;
751
+ Reader reader;
752
+ reader.Parse(s, h);
753
+ EXPECT_EQ(2u, h.step_);
754
+ free(json);
755
+ }
756
+
757
+ TEST(Reader, ParseArray) {
758
+ char *json = StrDup("[1, 2, 3, 4]");
759
+ InsituStringStream s(json);
760
+ ParseArrayHandler<4> h;
761
+ Reader reader;
762
+ reader.Parse(s, h);
763
+ EXPECT_EQ(6u, h.step_);
764
+ free(json);
765
+ }
766
+
767
+ TEST(Reader, ParseArray_Error) {
768
+ #define TEST_ARRAY_ERROR(errorCode, str, errorOffset) \
769
+ { \
770
+ int streamPos = errorOffset; \
771
+ char buffer[1001]; \
772
+ strncpy(buffer, str, 1000); \
773
+ InsituStringStream s(buffer); \
774
+ BaseReaderHandler<> h; \
775
+ GenericReader<UTF8<>, UTF8<>, CrtAllocator> reader; \
776
+ EXPECT_FALSE(reader.Parse(s, h)); \
777
+ EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
778
+ EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
779
+ EXPECT_EQ(streamPos, s.Tell());\
780
+ }
781
+
782
+ // Missing a comma or ']' after an array element.
783
+ TEST_ARRAY_ERROR(kParseErrorArrayMissCommaOrSquareBracket, "[1", 2);
784
+ TEST_ARRAY_ERROR(kParseErrorArrayMissCommaOrSquareBracket, "[1}", 2);
785
+ TEST_ARRAY_ERROR(kParseErrorArrayMissCommaOrSquareBracket, "[1 2]", 3);
786
+
787
+ // Array cannot have a trailing comma (without kParseTrailingCommasFlag);
788
+ // a value must follow a comma
789
+ TEST_ARRAY_ERROR(kParseErrorValueInvalid, "[1,]", 3);
790
+
791
+ #undef TEST_ARRAY_ERROR
792
+ }
793
+
794
+ struct ParseObjectHandler : BaseReaderHandler<UTF8<>, ParseObjectHandler> {
795
+ ParseObjectHandler() : step_(0) {}
796
+
797
+ bool Default() { ADD_FAILURE(); return false; }
798
+ bool Null() { EXPECT_EQ(8u, step_); step_++; return true; }
799
+ bool Bool(bool b) {
800
+ switch(step_) {
801
+ case 4: EXPECT_TRUE(b); step_++; return true;
802
+ case 6: EXPECT_FALSE(b); step_++; return true;
803
+ default: ADD_FAILURE(); return false;
804
+ }
805
+ }
806
+ bool Int(int i) {
807
+ switch(step_) {
808
+ case 10: EXPECT_EQ(123, i); step_++; return true;
809
+ case 15: EXPECT_EQ(1, i); step_++; return true;
810
+ case 16: EXPECT_EQ(2, i); step_++; return true;
811
+ case 17: EXPECT_EQ(3, i); step_++; return true;
812
+ default: ADD_FAILURE(); return false;
813
+ }
814
+ }
815
+ bool Uint(unsigned i) { return Int(static_cast<int>(i)); }
816
+ bool Double(double d) { EXPECT_EQ(12u, step_); EXPECT_DOUBLE_EQ(3.1416, d); step_++; return true; }
817
+ bool String(const char* str, size_t, bool) {
818
+ switch(step_) {
819
+ case 1: EXPECT_STREQ("hello", str); step_++; return true;
820
+ case 2: EXPECT_STREQ("world", str); step_++; return true;
821
+ case 3: EXPECT_STREQ("t", str); step_++; return true;
822
+ case 5: EXPECT_STREQ("f", str); step_++; return true;
823
+ case 7: EXPECT_STREQ("n", str); step_++; return true;
824
+ case 9: EXPECT_STREQ("i", str); step_++; return true;
825
+ case 11: EXPECT_STREQ("pi", str); step_++; return true;
826
+ case 13: EXPECT_STREQ("a", str); step_++; return true;
827
+ default: ADD_FAILURE(); return false;
828
+ }
829
+ }
830
+ bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; }
831
+ bool EndObject(SizeType memberCount) { EXPECT_EQ(19u, step_); EXPECT_EQ(7u, memberCount); step_++; return true; }
832
+ bool StartArray() { EXPECT_EQ(14u, step_); step_++; return true; }
833
+ bool EndArray(SizeType elementCount) { EXPECT_EQ(18u, step_); EXPECT_EQ(3u, elementCount); step_++; return true; }
834
+
835
+ unsigned step_;
836
+ };
837
+
838
+ TEST(Reader, ParseObject) {
839
+ const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ";
840
+
841
+ // Insitu
842
+ {
843
+ char* json2 = StrDup(json);
844
+ InsituStringStream s(json2);
845
+ ParseObjectHandler h;
846
+ Reader reader;
847
+ reader.Parse<kParseInsituFlag>(s, h);
848
+ EXPECT_EQ(20u, h.step_);
849
+ free(json2);
850
+ }
851
+
852
+ // Normal
853
+ {
854
+ StringStream s(json);
855
+ ParseObjectHandler h;
856
+ Reader reader;
857
+ reader.Parse(s, h);
858
+ EXPECT_EQ(20u, h.step_);
859
+ }
860
+ }
861
+
862
+ struct ParseEmptyObjectHandler : BaseReaderHandler<UTF8<>, ParseEmptyObjectHandler> {
863
+ ParseEmptyObjectHandler() : step_(0) {}
864
+
865
+ bool Default() { ADD_FAILURE(); return false; }
866
+ bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; }
867
+ bool EndObject(SizeType) { EXPECT_EQ(1u, step_); step_++; return true; }
868
+
869
+ unsigned step_;
870
+ };
871
+
872
+ TEST(Reader, Parse_EmptyObject) {
873
+ StringStream s("{ } ");
874
+ ParseEmptyObjectHandler h;
875
+ Reader reader;
876
+ reader.Parse(s, h);
877
+ EXPECT_EQ(2u, h.step_);
878
+ }
879
+
880
+ struct ParseMultipleRootHandler : BaseReaderHandler<UTF8<>, ParseMultipleRootHandler> {
881
+ ParseMultipleRootHandler() : step_(0) {}
882
+
883
+ bool Default() { ADD_FAILURE(); return false; }
884
+ bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; }
885
+ bool EndObject(SizeType) { EXPECT_EQ(1u, step_); step_++; return true; }
886
+ bool StartArray() { EXPECT_EQ(2u, step_); step_++; return true; }
887
+ bool EndArray(SizeType) { EXPECT_EQ(3u, step_); step_++; return true; }
888
+
889
+ unsigned step_;
890
+ };
891
+
892
+ template <unsigned parseFlags>
893
+ void TestMultipleRoot() {
894
+ StringStream s("{}[] a");
895
+ ParseMultipleRootHandler h;
896
+ Reader reader;
897
+ EXPECT_TRUE(reader.Parse<parseFlags>(s, h));
898
+ EXPECT_EQ(2u, h.step_);
899
+ EXPECT_TRUE(reader.Parse<parseFlags>(s, h));
900
+ EXPECT_EQ(4u, h.step_);
901
+ EXPECT_EQ(' ', s.Take());
902
+ EXPECT_EQ('a', s.Take());
903
+ }
904
+
905
+ TEST(Reader, Parse_MultipleRoot) {
906
+ TestMultipleRoot<kParseStopWhenDoneFlag>();
907
+ }
908
+
909
+ TEST(Reader, ParseIterative_MultipleRoot) {
910
+ TestMultipleRoot<kParseIterativeFlag | kParseStopWhenDoneFlag>();
911
+ }
912
+
913
+ template <unsigned parseFlags>
914
+ void TestInsituMultipleRoot() {
915
+ char* buffer = strdup("{}[] a");
916
+ InsituStringStream s(buffer);
917
+ ParseMultipleRootHandler h;
918
+ Reader reader;
919
+ EXPECT_TRUE(reader.Parse<kParseInsituFlag | parseFlags>(s, h));
920
+ EXPECT_EQ(2u, h.step_);
921
+ EXPECT_TRUE(reader.Parse<kParseInsituFlag | parseFlags>(s, h));
922
+ EXPECT_EQ(4u, h.step_);
923
+ EXPECT_EQ(' ', s.Take());
924
+ EXPECT_EQ('a', s.Take());
925
+ free(buffer);
926
+ }
927
+
928
+ TEST(Reader, ParseInsitu_MultipleRoot) {
929
+ TestInsituMultipleRoot<kParseStopWhenDoneFlag>();
930
+ }
931
+
932
+ TEST(Reader, ParseInsituIterative_MultipleRoot) {
933
+ TestInsituMultipleRoot<kParseIterativeFlag | kParseStopWhenDoneFlag>();
934
+ }
935
+
936
+ #define TEST_ERROR(errorCode, str, errorOffset) \
937
+ { \
938
+ int streamPos = errorOffset; \
939
+ char buffer[1001]; \
940
+ strncpy(buffer, str, 1000); \
941
+ InsituStringStream s(buffer); \
942
+ BaseReaderHandler<> h; \
943
+ Reader reader; \
944
+ EXPECT_FALSE(reader.Parse(s, h)); \
945
+ EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
946
+ EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
947
+ EXPECT_EQ(streamPos, s.Tell());\
948
+ }
949
+
950
+ TEST(Reader, ParseDocument_Error) {
951
+ // The document is empty.
952
+ TEST_ERROR(kParseErrorDocumentEmpty, "", 0);
953
+ TEST_ERROR(kParseErrorDocumentEmpty, " ", 1);
954
+ TEST_ERROR(kParseErrorDocumentEmpty, " \n", 2);
955
+
956
+ // The document root must not follow by other values.
957
+ TEST_ERROR(kParseErrorDocumentRootNotSingular, "[] 0", 3);
958
+ TEST_ERROR(kParseErrorDocumentRootNotSingular, "{} 0", 3);
959
+ TEST_ERROR(kParseErrorDocumentRootNotSingular, "null []", 5);
960
+ TEST_ERROR(kParseErrorDocumentRootNotSingular, "0 {}", 2);
961
+ }
962
+
963
+ TEST(Reader, ParseValue_Error) {
964
+ // Invalid value.
965
+ TEST_ERROR(kParseErrorValueInvalid, "nulL", 3);
966
+ TEST_ERROR(kParseErrorValueInvalid, "truE", 3);
967
+ TEST_ERROR(kParseErrorValueInvalid, "falsE", 4);
968
+ TEST_ERROR(kParseErrorValueInvalid, "a]", 0);
969
+ TEST_ERROR(kParseErrorValueInvalid, ".1", 0);
970
+ }
971
+
972
+ TEST(Reader, ParseObject_Error) {
973
+ // Missing a name for object member.
974
+ TEST_ERROR(kParseErrorObjectMissName, "{1}", 1);
975
+ TEST_ERROR(kParseErrorObjectMissName, "{:1}", 1);
976
+ TEST_ERROR(kParseErrorObjectMissName, "{null:1}", 1);
977
+ TEST_ERROR(kParseErrorObjectMissName, "{true:1}", 1);
978
+ TEST_ERROR(kParseErrorObjectMissName, "{false:1}", 1);
979
+ TEST_ERROR(kParseErrorObjectMissName, "{1:1}", 1);
980
+ TEST_ERROR(kParseErrorObjectMissName, "{[]:1}", 1);
981
+ TEST_ERROR(kParseErrorObjectMissName, "{{}:1}", 1);
982
+ TEST_ERROR(kParseErrorObjectMissName, "{xyz:1}", 1);
983
+
984
+ // Missing a colon after a name of object member.
985
+ TEST_ERROR(kParseErrorObjectMissColon, "{\"a\" 1}", 5);
986
+ TEST_ERROR(kParseErrorObjectMissColon, "{\"a\",1}", 4);
987
+
988
+ // Must be a comma or '}' after an object member
989
+ TEST_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, "{\"a\":1]", 6);
990
+
991
+ // Object cannot have a trailing comma (without kParseTrailingCommasFlag);
992
+ // an object member name must follow a comma
993
+ TEST_ERROR(kParseErrorObjectMissName, "{\"a\":1,}", 7);
994
+
995
+ // This tests that MemoryStream is checking the length in Peek().
996
+ {
997
+ MemoryStream ms("{\"a\"", 1);
998
+ BaseReaderHandler<> h;
999
+ Reader reader;
1000
+ EXPECT_FALSE(reader.Parse<kParseStopWhenDoneFlag>(ms, h));
1001
+ EXPECT_EQ(kParseErrorObjectMissName, reader.GetParseErrorCode());
1002
+ }
1003
+ }
1004
+
1005
+ #undef TEST_ERROR
1006
+
1007
+ TEST(Reader, SkipWhitespace) {
1008
+ StringStream ss(" A \t\tB\n \n\nC\r\r \rD \t\n\r E");
1009
+ const char* expected = "ABCDE";
1010
+ for (size_t i = 0; i < 5; i++) {
1011
+ SkipWhitespace(ss);
1012
+ EXPECT_EQ(expected[i], ss.Take());
1013
+ }
1014
+ }
1015
+
1016
+ // Test implementing a stream without copy stream optimization.
1017
+ // Clone from GenericStringStream except that copy constructor is disabled.
1018
+ template <typename Encoding>
1019
+ class CustomStringStream {
1020
+ public:
1021
+ typedef typename Encoding::Ch Ch;
1022
+
1023
+ CustomStringStream(const Ch *src) : src_(src), head_(src) {}
1024
+
1025
+ Ch Peek() const { return *src_; }
1026
+ Ch Take() { return *src_++; }
1027
+ size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1028
+
1029
+ Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
1030
+ void Put(Ch) { RAPIDJSON_ASSERT(false); }
1031
+ void Flush() { RAPIDJSON_ASSERT(false); }
1032
+ size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
1033
+
1034
+ private:
1035
+ // Prohibit copy constructor & assignment operator.
1036
+ CustomStringStream(const CustomStringStream&);
1037
+ CustomStringStream& operator=(const CustomStringStream&);
1038
+
1039
+ const Ch* src_; //!< Current read position.
1040
+ const Ch* head_; //!< Original head of the string.
1041
+ };
1042
+
1043
+ // If the following code is compiled, it should generate compilation error as predicted.
1044
+ // Because CustomStringStream<> is not copyable via making copy constructor private.
1045
+ #if 0
1046
+ namespace rapidjson {
1047
+
1048
+ template <typename Encoding>
1049
+ struct StreamTraits<CustomStringStream<Encoding> > {
1050
+ enum { copyOptimization = 1 };
1051
+ };
1052
+
1053
+ } // namespace rapidjson
1054
+ #endif
1055
+
1056
+ TEST(Reader, CustomStringStream) {
1057
+ const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ";
1058
+ CustomStringStream<UTF8<char> > s(json);
1059
+ ParseObjectHandler h;
1060
+ Reader reader;
1061
+ reader.Parse(s, h);
1062
+ EXPECT_EQ(20u, h.step_);
1063
+ }
1064
+
1065
+ #include <sstream>
1066
+
1067
+ class IStreamWrapper {
1068
+ public:
1069
+ typedef char Ch;
1070
+
1071
+ IStreamWrapper(std::istream& is) : is_(is) {}
1072
+
1073
+ Ch Peek() const {
1074
+ int c = is_.peek();
1075
+ return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
1076
+ }
1077
+
1078
+ Ch Take() {
1079
+ int c = is_.get();
1080
+ return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
1081
+ }
1082
+
1083
+ size_t Tell() const { return static_cast<size_t>(is_.tellg()); }
1084
+
1085
+ Ch* PutBegin() { assert(false); return 0; }
1086
+ void Put(Ch) { assert(false); }
1087
+ void Flush() { assert(false); }
1088
+ size_t PutEnd(Ch*) { assert(false); return 0; }
1089
+
1090
+ private:
1091
+ IStreamWrapper(const IStreamWrapper&);
1092
+ IStreamWrapper& operator=(const IStreamWrapper&);
1093
+
1094
+ std::istream& is_;
1095
+ };
1096
+
1097
+ TEST(Reader, Parse_IStreamWrapper_StringStream) {
1098
+ const char* json = "[1,2,3,4]";
1099
+
1100
+ std::stringstream ss(json);
1101
+ IStreamWrapper is(ss);
1102
+
1103
+ Reader reader;
1104
+ ParseArrayHandler<4> h;
1105
+ reader.Parse(is, h);
1106
+ EXPECT_FALSE(reader.HasParseError());
1107
+ }
1108
+
1109
+ // Test iterative parsing.
1110
+
1111
+ #define TESTERRORHANDLING(text, errorCode, offset)\
1112
+ {\
1113
+ int streamPos = offset; \
1114
+ StringStream json(text); \
1115
+ BaseReaderHandler<> handler; \
1116
+ Reader reader; \
1117
+ reader.Parse<kParseIterativeFlag>(json, handler); \
1118
+ EXPECT_TRUE(reader.HasParseError()); \
1119
+ EXPECT_EQ(errorCode, reader.GetParseErrorCode()); \
1120
+ EXPECT_EQ(offset, reader.GetErrorOffset()); \
1121
+ EXPECT_EQ(streamPos, json.Tell()); \
1122
+ }
1123
+
1124
+ TEST(Reader, IterativeParsing_ErrorHandling) {
1125
+ TESTERRORHANDLING("{\"a\": a}", kParseErrorValueInvalid, 6u);
1126
+
1127
+ TESTERRORHANDLING("", kParseErrorDocumentEmpty, 0u);
1128
+ TESTERRORHANDLING("{}{}", kParseErrorDocumentRootNotSingular, 2u);
1129
+
1130
+ TESTERRORHANDLING("{1}", kParseErrorObjectMissName, 1u);
1131
+ TESTERRORHANDLING("{\"a\", 1}", kParseErrorObjectMissColon, 4u);
1132
+ TESTERRORHANDLING("{\"a\"}", kParseErrorObjectMissColon, 4u);
1133
+ TESTERRORHANDLING("{\"a\": 1", kParseErrorObjectMissCommaOrCurlyBracket, 7u);
1134
+ TESTERRORHANDLING("[1 2 3]", kParseErrorArrayMissCommaOrSquareBracket, 3u);
1135
+ TESTERRORHANDLING("{\"a: 1", kParseErrorStringMissQuotationMark, 6u);
1136
+ TESTERRORHANDLING("{\"a\":}", kParseErrorValueInvalid, 5u);
1137
+ TESTERRORHANDLING("{\"a\":]", kParseErrorValueInvalid, 5u);
1138
+ TESTERRORHANDLING("[1,2,}", kParseErrorValueInvalid, 5u);
1139
+ TESTERRORHANDLING("[}]", kParseErrorValueInvalid, 1u);
1140
+ TESTERRORHANDLING("[,]", kParseErrorValueInvalid, 1u);
1141
+ TESTERRORHANDLING("[1,,]", kParseErrorValueInvalid, 3u);
1142
+
1143
+ // Trailing commas are not allowed without kParseTrailingCommasFlag
1144
+ TESTERRORHANDLING("{\"a\": 1,}", kParseErrorObjectMissName, 8u);
1145
+ TESTERRORHANDLING("[1,2,3,]", kParseErrorValueInvalid, 7u);
1146
+
1147
+ // Any JSON value can be a valid root element in RFC7159.
1148
+ TESTERRORHANDLING("\"ab", kParseErrorStringMissQuotationMark, 3u);
1149
+ TESTERRORHANDLING("truE", kParseErrorValueInvalid, 3u);
1150
+ TESTERRORHANDLING("False", kParseErrorValueInvalid, 0u);
1151
+ TESTERRORHANDLING("true, false", kParseErrorDocumentRootNotSingular, 4u);
1152
+ TESTERRORHANDLING("false, false", kParseErrorDocumentRootNotSingular, 5u);
1153
+ TESTERRORHANDLING("nulL", kParseErrorValueInvalid, 3u);
1154
+ TESTERRORHANDLING("null , null", kParseErrorDocumentRootNotSingular, 5u);
1155
+ TESTERRORHANDLING("1a", kParseErrorDocumentRootNotSingular, 1u);
1156
+ }
1157
+
1158
+ template<typename Encoding = UTF8<> >
1159
+ struct IterativeParsingReaderHandler {
1160
+ typedef typename Encoding::Ch Ch;
1161
+
1162
+ const static uint32_t LOG_NULL = 0x10000000;
1163
+ const static uint32_t LOG_BOOL = 0x20000000;
1164
+ const static uint32_t LOG_INT = 0x30000000;
1165
+ const static uint32_t LOG_UINT = 0x40000000;
1166
+ const static uint32_t LOG_INT64 = 0x50000000;
1167
+ const static uint32_t LOG_UINT64 = 0x60000000;
1168
+ const static uint32_t LOG_DOUBLE = 0x70000000;
1169
+ const static uint32_t LOG_STRING = 0x80000000;
1170
+ const static uint32_t LOG_STARTOBJECT = 0x90000000;
1171
+ const static uint32_t LOG_KEY = 0xA0000000;
1172
+ const static uint32_t LOG_ENDOBJECT = 0xB0000000;
1173
+ const static uint32_t LOG_STARTARRAY = 0xC0000000;
1174
+ const static uint32_t LOG_ENDARRAY = 0xD0000000;
1175
+
1176
+ const static size_t LogCapacity = 256;
1177
+ uint32_t Logs[LogCapacity];
1178
+ size_t LogCount;
1179
+
1180
+ IterativeParsingReaderHandler() : LogCount(0) {
1181
+ }
1182
+
1183
+ bool Null() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_NULL; return true; }
1184
+
1185
+ bool Bool(bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_BOOL; return true; }
1186
+
1187
+ bool Int(int) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_INT; return true; }
1188
+
1189
+ bool Uint(unsigned) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_INT; return true; }
1190
+
1191
+ bool Int64(int64_t) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_INT64; return true; }
1192
+
1193
+ bool Uint64(uint64_t) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_UINT64; return true; }
1194
+
1195
+ bool Double(double) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_DOUBLE; return true; }
1196
+
1197
+ bool RawNumber(const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STRING; return true; }
1198
+
1199
+ bool String(const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STRING; return true; }
1200
+
1201
+ bool StartObject() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTOBJECT; return true; }
1202
+
1203
+ bool Key (const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_KEY; return true; }
1204
+
1205
+ bool EndObject(SizeType c) {
1206
+ RAPIDJSON_ASSERT(LogCount < LogCapacity);
1207
+ RAPIDJSON_ASSERT((static_cast<uint32_t>(c) & 0xF0000000) == 0);
1208
+ Logs[LogCount++] = LOG_ENDOBJECT | static_cast<uint32_t>(c);
1209
+ return true;
1210
+ }
1211
+
1212
+ bool StartArray() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTARRAY; return true; }
1213
+
1214
+ bool EndArray(SizeType c) {
1215
+ RAPIDJSON_ASSERT(LogCount < LogCapacity);
1216
+ RAPIDJSON_ASSERT((static_cast<uint32_t>(c) & 0xF0000000) == 0);
1217
+ Logs[LogCount++] = LOG_ENDARRAY | static_cast<uint32_t>(c);
1218
+ return true;
1219
+ }
1220
+ };
1221
+
1222
+ TEST(Reader, IterativeParsing_General) {
1223
+ {
1224
+ StringStream is("[1, {\"k\": [1, 2]}, null, false, true, \"string\", 1.2]");
1225
+ Reader reader;
1226
+ IterativeParsingReaderHandler<> handler;
1227
+
1228
+ ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1229
+
1230
+ EXPECT_FALSE(r.IsError());
1231
+ EXPECT_FALSE(reader.HasParseError());
1232
+
1233
+ uint32_t e[] = {
1234
+ handler.LOG_STARTARRAY,
1235
+ handler.LOG_INT,
1236
+ handler.LOG_STARTOBJECT,
1237
+ handler.LOG_KEY,
1238
+ handler.LOG_STARTARRAY,
1239
+ handler.LOG_INT,
1240
+ handler.LOG_INT,
1241
+ handler.LOG_ENDARRAY | 2,
1242
+ handler.LOG_ENDOBJECT | 1,
1243
+ handler.LOG_NULL,
1244
+ handler.LOG_BOOL,
1245
+ handler.LOG_BOOL,
1246
+ handler.LOG_STRING,
1247
+ handler.LOG_DOUBLE,
1248
+ handler.LOG_ENDARRAY | 7
1249
+ };
1250
+
1251
+ EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount);
1252
+
1253
+ for (size_t i = 0; i < handler.LogCount; ++i) {
1254
+ EXPECT_EQ(e[i], handler.Logs[i]) << "i = " << i;
1255
+ }
1256
+ }
1257
+ }
1258
+
1259
+ TEST(Reader, IterativeParsing_Count) {
1260
+ {
1261
+ StringStream is("[{}, {\"k\": 1}, [1], []]");
1262
+ Reader reader;
1263
+ IterativeParsingReaderHandler<> handler;
1264
+
1265
+ ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1266
+
1267
+ EXPECT_FALSE(r.IsError());
1268
+ EXPECT_FALSE(reader.HasParseError());
1269
+
1270
+ uint32_t e[] = {
1271
+ handler.LOG_STARTARRAY,
1272
+ handler.LOG_STARTOBJECT,
1273
+ handler.LOG_ENDOBJECT | 0,
1274
+ handler.LOG_STARTOBJECT,
1275
+ handler.LOG_KEY,
1276
+ handler.LOG_INT,
1277
+ handler.LOG_ENDOBJECT | 1,
1278
+ handler.LOG_STARTARRAY,
1279
+ handler.LOG_INT,
1280
+ handler.LOG_ENDARRAY | 1,
1281
+ handler.LOG_STARTARRAY,
1282
+ handler.LOG_ENDARRAY | 0,
1283
+ handler.LOG_ENDARRAY | 4
1284
+ };
1285
+
1286
+ EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount);
1287
+
1288
+ for (size_t i = 0; i < handler.LogCount; ++i) {
1289
+ EXPECT_EQ(e[i], handler.Logs[i]) << "i = " << i;
1290
+ }
1291
+ }
1292
+ }
1293
+
1294
+ TEST(Reader, IterativePullParsing_General) {
1295
+ {
1296
+ IterativeParsingReaderHandler<> handler;
1297
+ uint32_t e[] = {
1298
+ handler.LOG_STARTARRAY,
1299
+ handler.LOG_INT,
1300
+ handler.LOG_STARTOBJECT,
1301
+ handler.LOG_KEY,
1302
+ handler.LOG_STARTARRAY,
1303
+ handler.LOG_INT,
1304
+ handler.LOG_INT,
1305
+ handler.LOG_ENDARRAY | 2,
1306
+ handler.LOG_ENDOBJECT | 1,
1307
+ handler.LOG_NULL,
1308
+ handler.LOG_BOOL,
1309
+ handler.LOG_BOOL,
1310
+ handler.LOG_STRING,
1311
+ handler.LOG_DOUBLE,
1312
+ handler.LOG_ENDARRAY | 7
1313
+ };
1314
+
1315
+ StringStream is("[1, {\"k\": [1, 2]}, null, false, true, \"string\", 1.2]");
1316
+ Reader reader;
1317
+
1318
+ reader.IterativeParseInit();
1319
+ while (!reader.IterativeParseComplete()) {
1320
+ size_t oldLogCount = handler.LogCount;
1321
+ EXPECT_TRUE(oldLogCount < sizeof(e) / sizeof(int)) << "overrun";
1322
+
1323
+ EXPECT_TRUE(reader.IterativeParseNext<kParseDefaultFlags>(is, handler)) << "parse fail";
1324
+ EXPECT_EQ(handler.LogCount, oldLogCount + 1) << "handler should be invoked exactly once each time";
1325
+ EXPECT_EQ(e[oldLogCount], handler.Logs[oldLogCount]) << "wrong event returned";
1326
+ }
1327
+
1328
+ EXPECT_FALSE(reader.HasParseError());
1329
+ EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount) << "handler invoked wrong number of times";
1330
+
1331
+ // The handler should not be invoked when the JSON has been fully read, but it should not fail
1332
+ size_t oldLogCount = handler.LogCount;
1333
+ EXPECT_TRUE(reader.IterativeParseNext<kParseDefaultFlags>(is, handler)) << "parse-next past complete is allowed";
1334
+ EXPECT_EQ(handler.LogCount, oldLogCount) << "parse-next past complete should not invoke handler";
1335
+ EXPECT_FALSE(reader.HasParseError()) << "parse-next past complete should not generate parse error";
1336
+ }
1337
+ }
1338
+
1339
+ // Test iterative parsing on kParseErrorTermination.
1340
+ struct HandlerTerminateAtStartObject : public IterativeParsingReaderHandler<> {
1341
+ bool StartObject() { return false; }
1342
+ };
1343
+
1344
+ struct HandlerTerminateAtStartArray : public IterativeParsingReaderHandler<> {
1345
+ bool StartArray() { return false; }
1346
+ };
1347
+
1348
+ struct HandlerTerminateAtEndObject : public IterativeParsingReaderHandler<> {
1349
+ bool EndObject(SizeType) { return false; }
1350
+ };
1351
+
1352
+ struct HandlerTerminateAtEndArray : public IterativeParsingReaderHandler<> {
1353
+ bool EndArray(SizeType) { return false; }
1354
+ };
1355
+
1356
+ TEST(Reader, IterativeParsing_ShortCircuit) {
1357
+ {
1358
+ HandlerTerminateAtStartObject handler;
1359
+ Reader reader;
1360
+ StringStream is("[1, {}]");
1361
+
1362
+ ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1363
+
1364
+ EXPECT_TRUE(reader.HasParseError());
1365
+ EXPECT_EQ(kParseErrorTermination, r.Code());
1366
+ EXPECT_EQ(4u, r.Offset());
1367
+ }
1368
+
1369
+ {
1370
+ HandlerTerminateAtStartArray handler;
1371
+ Reader reader;
1372
+ StringStream is("{\"a\": []}");
1373
+
1374
+ ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1375
+
1376
+ EXPECT_TRUE(reader.HasParseError());
1377
+ EXPECT_EQ(kParseErrorTermination, r.Code());
1378
+ EXPECT_EQ(6u, r.Offset());
1379
+ }
1380
+
1381
+ {
1382
+ HandlerTerminateAtEndObject handler;
1383
+ Reader reader;
1384
+ StringStream is("[1, {}]");
1385
+
1386
+ ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1387
+
1388
+ EXPECT_TRUE(reader.HasParseError());
1389
+ EXPECT_EQ(kParseErrorTermination, r.Code());
1390
+ EXPECT_EQ(5u, r.Offset());
1391
+ }
1392
+
1393
+ {
1394
+ HandlerTerminateAtEndArray handler;
1395
+ Reader reader;
1396
+ StringStream is("{\"a\": []}");
1397
+
1398
+ ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1399
+
1400
+ EXPECT_TRUE(reader.HasParseError());
1401
+ EXPECT_EQ(kParseErrorTermination, r.Code());
1402
+ EXPECT_EQ(7u, r.Offset());
1403
+ }
1404
+ }
1405
+
1406
+ // For covering BaseReaderHandler default functions
1407
+ TEST(Reader, BaseReaderHandler_Default) {
1408
+ BaseReaderHandler<> h;
1409
+ Reader reader;
1410
+ StringStream is("[null, true, -1, 1, -1234567890123456789, 1234567890123456789, 3.14, \"s\", { \"a\" : 1 }]");
1411
+ EXPECT_TRUE(reader.Parse(is, h));
1412
+ }
1413
+
1414
+ template <int e>
1415
+ struct TerminateHandler {
1416
+ bool Null() { return e != 0; }
1417
+ bool Bool(bool) { return e != 1; }
1418
+ bool Int(int) { return e != 2; }
1419
+ bool Uint(unsigned) { return e != 3; }
1420
+ bool Int64(int64_t) { return e != 4; }
1421
+ bool Uint64(uint64_t) { return e != 5; }
1422
+ bool Double(double) { return e != 6; }
1423
+ bool RawNumber(const char*, SizeType, bool) { return e != 7; }
1424
+ bool String(const char*, SizeType, bool) { return e != 8; }
1425
+ bool StartObject() { return e != 9; }
1426
+ bool Key(const char*, SizeType, bool) { return e != 10; }
1427
+ bool EndObject(SizeType) { return e != 11; }
1428
+ bool StartArray() { return e != 12; }
1429
+ bool EndArray(SizeType) { return e != 13; }
1430
+ };
1431
+
1432
+ #define TEST_TERMINATION(e, json)\
1433
+ {\
1434
+ Reader reader;\
1435
+ TerminateHandler<e> h;\
1436
+ StringStream is(json);\
1437
+ EXPECT_FALSE(reader.Parse(is, h));\
1438
+ EXPECT_EQ(kParseErrorTermination, reader.GetParseErrorCode());\
1439
+ }
1440
+
1441
+ TEST(Reader, ParseTerminationByHandler) {
1442
+ TEST_TERMINATION(0, "[null");
1443
+ TEST_TERMINATION(1, "[true");
1444
+ TEST_TERMINATION(1, "[false");
1445
+ TEST_TERMINATION(2, "[-1");
1446
+ TEST_TERMINATION(3, "[1");
1447
+ TEST_TERMINATION(4, "[-1234567890123456789");
1448
+ TEST_TERMINATION(5, "[1234567890123456789");
1449
+ TEST_TERMINATION(6, "[0.5]");
1450
+ // RawNumber() is never called
1451
+ TEST_TERMINATION(8, "[\"a\"");
1452
+ TEST_TERMINATION(9, "[{");
1453
+ TEST_TERMINATION(10, "[{\"a\"");
1454
+ TEST_TERMINATION(11, "[{}");
1455
+ TEST_TERMINATION(11, "[{\"a\":1}"); // non-empty object
1456
+ TEST_TERMINATION(12, "{\"a\":[");
1457
+ TEST_TERMINATION(13, "{\"a\":[]");
1458
+ TEST_TERMINATION(13, "{\"a\":[1]"); // non-empty array
1459
+ }
1460
+
1461
+ TEST(Reader, ParseComments) {
1462
+ const char* json =
1463
+ "// Here is a one-line comment.\n"
1464
+ "{// And here's another one\n"
1465
+ " /*And here's an in-line one.*/\"hello\" : \"world\","
1466
+ " \"t\" :/* And one with '*' symbol*/true ,"
1467
+ "/* A multiline comment\n"
1468
+ " goes here*/"
1469
+ " \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3]"
1470
+ "}/*And the last one to be sure */";
1471
+
1472
+ StringStream s(json);
1473
+ ParseObjectHandler h;
1474
+ Reader reader;
1475
+ EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
1476
+ EXPECT_EQ(20u, h.step_);
1477
+ }
1478
+
1479
+ TEST(Reader, ParseEmptyInlineComment) {
1480
+ const char* json = "{/**/\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1481
+
1482
+ StringStream s(json);
1483
+ ParseObjectHandler h;
1484
+ Reader reader;
1485
+ EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
1486
+ EXPECT_EQ(20u, h.step_);
1487
+ }
1488
+
1489
+ TEST(Reader, ParseEmptyOnelineComment) {
1490
+ const char* json = "{//\n\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1491
+
1492
+ StringStream s(json);
1493
+ ParseObjectHandler h;
1494
+ Reader reader;
1495
+ EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
1496
+ EXPECT_EQ(20u, h.step_);
1497
+ }
1498
+
1499
+ TEST(Reader, ParseMultipleCommentsInARow) {
1500
+ const char* json =
1501
+ "{/* first comment *//* second */\n"
1502
+ "/* third */ /*fourth*/// last one\n"
1503
+ "\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1504
+
1505
+ StringStream s(json);
1506
+ ParseObjectHandler h;
1507
+ Reader reader;
1508
+ EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
1509
+ EXPECT_EQ(20u, h.step_);
1510
+ }
1511
+
1512
+ TEST(Reader, InlineCommentsAreDisabledByDefault) {
1513
+ {
1514
+ const char* json = "{/* Inline comment. */\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1515
+
1516
+ StringStream s(json);
1517
+ ParseObjectHandler h;
1518
+ Reader reader;
1519
+ EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
1520
+ }
1521
+
1522
+ {
1523
+ const char* json =
1524
+ "{\"hello\" : /* Multiline comment starts here\n"
1525
+ " continues here\n"
1526
+ " and ends here */\"world\", \"t\" :true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1527
+
1528
+ StringStream s(json);
1529
+ ParseObjectHandler h;
1530
+ Reader reader;
1531
+ EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
1532
+ }
1533
+ }
1534
+
1535
+ TEST(Reader, OnelineCommentsAreDisabledByDefault) {
1536
+ const char* json = "{// One-line comment\n\"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1537
+
1538
+ StringStream s(json);
1539
+ ParseObjectHandler h;
1540
+ Reader reader;
1541
+ EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
1542
+ }
1543
+
1544
+ TEST(Reader, EofAfterOneLineComment) {
1545
+ const char* json = "{\"hello\" : \"world\" // EOF is here -->\0 \n}";
1546
+
1547
+ StringStream s(json);
1548
+ ParseObjectHandler h;
1549
+ Reader reader;
1550
+ EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
1551
+ EXPECT_EQ(kParseErrorObjectMissCommaOrCurlyBracket, reader.GetParseErrorCode());
1552
+ }
1553
+
1554
+ TEST(Reader, IncompleteMultilineComment) {
1555
+ const char* json = "{\"hello\" : \"world\" /* EOF is here -->\0 */}";
1556
+
1557
+ StringStream s(json);
1558
+ ParseObjectHandler h;
1559
+ Reader reader;
1560
+ EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
1561
+ EXPECT_EQ(kParseErrorUnspecificSyntaxError, reader.GetParseErrorCode());
1562
+ }
1563
+
1564
+ TEST(Reader, IncompleteMultilineComment2) {
1565
+ const char* json = "{\"hello\" : \"world\" /* *\0 */}";
1566
+
1567
+ StringStream s(json);
1568
+ ParseObjectHandler h;
1569
+ Reader reader;
1570
+ EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
1571
+ EXPECT_EQ(kParseErrorUnspecificSyntaxError, reader.GetParseErrorCode());
1572
+ }
1573
+
1574
+ TEST(Reader, UnrecognizedComment) {
1575
+ const char* json = "{\"hello\" : \"world\" /! }";
1576
+
1577
+ StringStream s(json);
1578
+ ParseObjectHandler h;
1579
+ Reader reader;
1580
+ EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
1581
+ EXPECT_EQ(kParseErrorUnspecificSyntaxError, reader.GetParseErrorCode());
1582
+ }
1583
+
1584
+ struct NumbersAsStringsHandler {
1585
+ bool Null() { return true; }
1586
+ bool Bool(bool) { return true; }
1587
+ bool Int(int) { return true; }
1588
+ bool Uint(unsigned) { return true; }
1589
+ bool Int64(int64_t) { return true; }
1590
+ bool Uint64(uint64_t) { return true; }
1591
+ bool Double(double) { return true; }
1592
+ // 'str' is not null-terminated
1593
+ bool RawNumber(const char* str, SizeType length, bool) {
1594
+ EXPECT_TRUE(str != 0);
1595
+ EXPECT_TRUE(expected_len_ == length);
1596
+ EXPECT_TRUE(strncmp(str, expected_, length) == 0);
1597
+ return true;
1598
+ }
1599
+ bool String(const char*, SizeType, bool) { return true; }
1600
+ bool StartObject() { return true; }
1601
+ bool Key(const char*, SizeType, bool) { return true; }
1602
+ bool EndObject(SizeType) { return true; }
1603
+ bool StartArray() { return true; }
1604
+ bool EndArray(SizeType) { return true; }
1605
+
1606
+ NumbersAsStringsHandler(const char* expected)
1607
+ : expected_(expected)
1608
+ , expected_len_(strlen(expected)) {}
1609
+
1610
+ const char* expected_;
1611
+ size_t expected_len_;
1612
+ };
1613
+
1614
+ TEST(Reader, NumbersAsStrings) {
1615
+ {
1616
+ const char* json = "{ \"pi\": 3.1416 } ";
1617
+ StringStream s(json);
1618
+ NumbersAsStringsHandler h("3.1416");
1619
+ Reader reader;
1620
+ EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1621
+ }
1622
+ {
1623
+ char* json = StrDup("{ \"pi\": 3.1416 } ");
1624
+ InsituStringStream s(json);
1625
+ NumbersAsStringsHandler h("3.1416");
1626
+ Reader reader;
1627
+ EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
1628
+ free(json);
1629
+ }
1630
+ {
1631
+ const char* json = "{ \"gigabyte\": 1.0e9 } ";
1632
+ StringStream s(json);
1633
+ NumbersAsStringsHandler h("1.0e9");
1634
+ Reader reader;
1635
+ EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1636
+ }
1637
+ {
1638
+ char* json = StrDup("{ \"gigabyte\": 1.0e9 } ");
1639
+ InsituStringStream s(json);
1640
+ NumbersAsStringsHandler h("1.0e9");
1641
+ Reader reader;
1642
+ EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
1643
+ free(json);
1644
+ }
1645
+ {
1646
+ const char* json = "{ \"pi\": 314.159e-2 } ";
1647
+ StringStream s(json);
1648
+ NumbersAsStringsHandler h("314.159e-2");
1649
+ Reader reader;
1650
+ EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1651
+ }
1652
+ {
1653
+ char* json = StrDup("{ \"gigabyte\": 314.159e-2 } ");
1654
+ InsituStringStream s(json);
1655
+ NumbersAsStringsHandler h("314.159e-2");
1656
+ Reader reader;
1657
+ EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
1658
+ free(json);
1659
+ }
1660
+ {
1661
+ const char* json = "{ \"negative\": -1.54321 } ";
1662
+ StringStream s(json);
1663
+ NumbersAsStringsHandler h("-1.54321");
1664
+ Reader reader;
1665
+ EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1666
+ }
1667
+ {
1668
+ char* json = StrDup("{ \"negative\": -1.54321 } ");
1669
+ InsituStringStream s(json);
1670
+ NumbersAsStringsHandler h("-1.54321");
1671
+ Reader reader;
1672
+ EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
1673
+ free(json);
1674
+ }
1675
+ {
1676
+ const char* json = "{ \"pi\": 314.159e-2 } ";
1677
+ std::stringstream ss(json);
1678
+ IStreamWrapper s(ss);
1679
+ NumbersAsStringsHandler h("314.159e-2");
1680
+ Reader reader;
1681
+ EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1682
+ }
1683
+ }
1684
+
1685
+ template <unsigned extraFlags>
1686
+ void TestTrailingCommas() {
1687
+ {
1688
+ StringStream s("[1,2,3,]");
1689
+ ParseArrayHandler<3> h;
1690
+ Reader reader;
1691
+ EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h));
1692
+ EXPECT_EQ(5u, h.step_);
1693
+ }
1694
+ {
1695
+ const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false,"
1696
+ "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3],}";
1697
+ StringStream s(json);
1698
+ ParseObjectHandler h;
1699
+ Reader reader;
1700
+ EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h));
1701
+ EXPECT_EQ(20u, h.step_);
1702
+ }
1703
+ {
1704
+ // whitespace around trailing commas
1705
+ const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false,"
1706
+ "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3\n,\n]\n,\n} ";
1707
+ StringStream s(json);
1708
+ ParseObjectHandler h;
1709
+ Reader reader;
1710
+ EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h));
1711
+ EXPECT_EQ(20u, h.step_);
1712
+ }
1713
+ {
1714
+ // comments around trailing commas
1715
+ const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null,"
1716
+ "\"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3/*test*/,/*test*/]/*test*/,/*test*/}";
1717
+ StringStream s(json);
1718
+ ParseObjectHandler h;
1719
+ Reader reader;
1720
+ EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag|kParseCommentsFlag>(s, h));
1721
+ EXPECT_EQ(20u, h.step_);
1722
+ }
1723
+ }
1724
+
1725
+ TEST(Reader, TrailingCommas) {
1726
+ TestTrailingCommas<kParseNoFlags>();
1727
+ }
1728
+
1729
+ TEST(Reader, TrailingCommasIterative) {
1730
+ TestTrailingCommas<kParseIterativeFlag>();
1731
+ }
1732
+
1733
+ template <unsigned extraFlags>
1734
+ void TestMultipleTrailingCommaErrors() {
1735
+ // only a single trailing comma is allowed.
1736
+ {
1737
+ StringStream s("[1,2,3,,]");
1738
+ ParseArrayHandler<3> h;
1739
+ Reader reader;
1740
+ ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1741
+ EXPECT_TRUE(reader.HasParseError());
1742
+ EXPECT_EQ(kParseErrorValueInvalid, r.Code());
1743
+ EXPECT_EQ(7u, r.Offset());
1744
+ }
1745
+ {
1746
+ const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false,"
1747
+ "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3,],,}";
1748
+ StringStream s(json);
1749
+ ParseObjectHandler h;
1750
+ Reader reader;
1751
+ ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1752
+ EXPECT_TRUE(reader.HasParseError());
1753
+ EXPECT_EQ(kParseErrorObjectMissName, r.Code());
1754
+ EXPECT_EQ(95u, r.Offset());
1755
+ }
1756
+ }
1757
+
1758
+ TEST(Reader, MultipleTrailingCommaErrors) {
1759
+ TestMultipleTrailingCommaErrors<kParseNoFlags>();
1760
+ }
1761
+
1762
+ TEST(Reader, MultipleTrailingCommaErrorsIterative) {
1763
+ TestMultipleTrailingCommaErrors<kParseIterativeFlag>();
1764
+ }
1765
+
1766
+ template <unsigned extraFlags>
1767
+ void TestEmptyExceptForCommaErrors() {
1768
+ // not allowed even with trailing commas enabled; the
1769
+ // trailing comma must follow a value.
1770
+ {
1771
+ StringStream s("[,]");
1772
+ ParseArrayHandler<3> h;
1773
+ Reader reader;
1774
+ ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1775
+ EXPECT_TRUE(reader.HasParseError());
1776
+ EXPECT_EQ(kParseErrorValueInvalid, r.Code());
1777
+ EXPECT_EQ(1u, r.Offset());
1778
+ }
1779
+ {
1780
+ StringStream s("{,}");
1781
+ ParseObjectHandler h;
1782
+ Reader reader;
1783
+ ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1784
+ EXPECT_TRUE(reader.HasParseError());
1785
+ EXPECT_EQ(kParseErrorObjectMissName, r.Code());
1786
+ EXPECT_EQ(1u, r.Offset());
1787
+ }
1788
+ }
1789
+
1790
+ TEST(Reader, EmptyExceptForCommaErrors) {
1791
+ TestEmptyExceptForCommaErrors<kParseNoFlags>();
1792
+ }
1793
+
1794
+ TEST(Reader, EmptyExceptForCommaErrorsIterative) {
1795
+ TestEmptyExceptForCommaErrors<kParseIterativeFlag>();
1796
+ }
1797
+
1798
+ template <unsigned extraFlags>
1799
+ void TestTrailingCommaHandlerTermination() {
1800
+ {
1801
+ HandlerTerminateAtEndArray h;
1802
+ Reader reader;
1803
+ StringStream s("[1,2,3,]");
1804
+ ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1805
+ EXPECT_TRUE(reader.HasParseError());
1806
+ EXPECT_EQ(kParseErrorTermination, r.Code());
1807
+ EXPECT_EQ(7u, r.Offset());
1808
+ }
1809
+ {
1810
+ HandlerTerminateAtEndObject h;
1811
+ Reader reader;
1812
+ StringStream s("{\"t\": true, \"f\": false,}");
1813
+ ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1814
+ EXPECT_TRUE(reader.HasParseError());
1815
+ EXPECT_EQ(kParseErrorTermination, r.Code());
1816
+ EXPECT_EQ(23u, r.Offset());
1817
+ }
1818
+ }
1819
+
1820
+ TEST(Reader, TrailingCommaHandlerTermination) {
1821
+ TestTrailingCommaHandlerTermination<kParseNoFlags>();
1822
+ }
1823
+
1824
+ TEST(Reader, TrailingCommaHandlerTerminationIterative) {
1825
+ TestTrailingCommaHandlerTermination<kParseIterativeFlag>();
1826
+ }
1827
+
1828
+ TEST(Reader, ParseNanAndInfinity) {
1829
+ #define TEST_NAN_INF(str, x) \
1830
+ { \
1831
+ { \
1832
+ StringStream s(str); \
1833
+ ParseDoubleHandler h; \
1834
+ Reader reader; \
1835
+ ASSERT_EQ(kParseErrorNone, reader.Parse<kParseNanAndInfFlag>(s, h).Code()); \
1836
+ EXPECT_EQ(1u, h.step_); \
1837
+ internal::Double e(x), a(h.actual_); \
1838
+ EXPECT_EQ(e.IsNan(), a.IsNan()); \
1839
+ EXPECT_EQ(e.IsInf(), a.IsInf()); \
1840
+ if (!e.IsNan()) \
1841
+ EXPECT_EQ(e.Sign(), a.Sign()); \
1842
+ } \
1843
+ { \
1844
+ const char* json = "{ \"naninfdouble\": " str " } "; \
1845
+ StringStream s(json); \
1846
+ NumbersAsStringsHandler h(str); \
1847
+ Reader reader; \
1848
+ EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag|kParseNanAndInfFlag>(s, h)); \
1849
+ } \
1850
+ { \
1851
+ char* json = StrDup("{ \"naninfdouble\": " str " } "); \
1852
+ InsituStringStream s(json); \
1853
+ NumbersAsStringsHandler h(str); \
1854
+ Reader reader; \
1855
+ EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag|kParseNanAndInfFlag>(s, h)); \
1856
+ free(json); \
1857
+ } \
1858
+ }
1859
+ #define TEST_NAN_INF_ERROR(errorCode, str, errorOffset) \
1860
+ { \
1861
+ int streamPos = errorOffset; \
1862
+ char buffer[1001]; \
1863
+ strncpy(buffer, str, 1000); \
1864
+ InsituStringStream s(buffer); \
1865
+ BaseReaderHandler<> h; \
1866
+ Reader reader; \
1867
+ EXPECT_FALSE(reader.Parse<kParseNanAndInfFlag>(s, h)); \
1868
+ EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
1869
+ EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
1870
+ EXPECT_EQ(streamPos, s.Tell());\
1871
+ }
1872
+
1873
+ double nan = std::numeric_limits<double>::quiet_NaN();
1874
+ double inf = std::numeric_limits<double>::infinity();
1875
+
1876
+ TEST_NAN_INF("NaN", nan);
1877
+ TEST_NAN_INF("-NaN", nan);
1878
+ TEST_NAN_INF("Inf", inf);
1879
+ TEST_NAN_INF("Infinity", inf);
1880
+ TEST_NAN_INF("-Inf", -inf);
1881
+ TEST_NAN_INF("-Infinity", -inf);
1882
+ TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "NInf", 1);
1883
+ TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "NaInf", 2);
1884
+ TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "INan", 1);
1885
+ TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "InNan", 2);
1886
+ TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "nan", 1);
1887
+ TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "-nan", 1);
1888
+ TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "NAN", 1);
1889
+ TEST_NAN_INF_ERROR(kParseErrorValueInvalid, "-Infinty", 6);
1890
+
1891
+ #undef TEST_NAN_INF_ERROR
1892
+ #undef TEST_NAN_INF
1893
+ }
1894
+
1895
+ RAPIDJSON_DIAG_POP