rj_schema 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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