rj_schema 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (299) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +18 -0
  3. data/ext/rj_schema/extconf.rb +7 -0
  4. data/ext/rj_schema/rapidjson/CHANGELOG.md +158 -0
  5. data/ext/rj_schema/rapidjson/CMakeLists.txt +221 -0
  6. data/ext/rj_schema/rapidjson/CMakeModules/FindGTestSrc.cmake +30 -0
  7. data/ext/rj_schema/rapidjson/RapidJSON.pc.in +7 -0
  8. data/ext/rj_schema/rapidjson/RapidJSONConfig.cmake.in +15 -0
  9. data/ext/rj_schema/rapidjson/RapidJSONConfigVersion.cmake.in +10 -0
  10. data/ext/rj_schema/rapidjson/appveyor.yml +41 -0
  11. data/ext/rj_schema/rapidjson/bin/data/glossary.json +22 -0
  12. data/ext/rj_schema/rapidjson/bin/data/menu.json +27 -0
  13. data/ext/rj_schema/rapidjson/bin/data/readme.txt +1 -0
  14. data/ext/rj_schema/rapidjson/bin/data/sample.json +3315 -0
  15. data/ext/rj_schema/rapidjson/bin/data/webapp.json +88 -0
  16. data/ext/rj_schema/rapidjson/bin/data/widget.json +26 -0
  17. data/ext/rj_schema/rapidjson/bin/draft-04/schema +150 -0
  18. data/ext/rj_schema/rapidjson/bin/encodings/utf16be.json +0 -0
  19. data/ext/rj_schema/rapidjson/bin/encodings/utf16bebom.json +0 -0
  20. data/ext/rj_schema/rapidjson/bin/encodings/utf16le.json +0 -0
  21. data/ext/rj_schema/rapidjson/bin/encodings/utf16lebom.json +0 -0
  22. data/ext/rj_schema/rapidjson/bin/encodings/utf32be.json +0 -0
  23. data/ext/rj_schema/rapidjson/bin/encodings/utf32bebom.json +0 -0
  24. data/ext/rj_schema/rapidjson/bin/encodings/utf32le.json +0 -0
  25. data/ext/rj_schema/rapidjson/bin/encodings/utf32lebom.json +0 -0
  26. data/ext/rj_schema/rapidjson/bin/encodings/utf8.json +7 -0
  27. data/ext/rj_schema/rapidjson/bin/encodings/utf8bom.json +7 -0
  28. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail1.json +1 -0
  29. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail10.json +1 -0
  30. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail11.json +1 -0
  31. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail12.json +1 -0
  32. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail13.json +1 -0
  33. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail14.json +1 -0
  34. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail15.json +1 -0
  35. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail16.json +1 -0
  36. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail17.json +1 -0
  37. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail18.json +1 -0
  38. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail19.json +1 -0
  39. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail2.json +1 -0
  40. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail20.json +1 -0
  41. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail21.json +1 -0
  42. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail22.json +1 -0
  43. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail23.json +1 -0
  44. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail24.json +1 -0
  45. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail25.json +1 -0
  46. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail26.json +1 -0
  47. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail27.json +2 -0
  48. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail28.json +2 -0
  49. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail29.json +1 -0
  50. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail3.json +1 -0
  51. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail30.json +1 -0
  52. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail31.json +1 -0
  53. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail32.json +1 -0
  54. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail33.json +1 -0
  55. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail4.json +1 -0
  56. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail5.json +1 -0
  57. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail6.json +1 -0
  58. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail7.json +1 -0
  59. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail8.json +1 -0
  60. data/ext/rj_schema/rapidjson/bin/jsonchecker/fail9.json +1 -0
  61. data/ext/rj_schema/rapidjson/bin/jsonchecker/pass1.json +58 -0
  62. data/ext/rj_schema/rapidjson/bin/jsonchecker/pass2.json +1 -0
  63. data/ext/rj_schema/rapidjson/bin/jsonchecker/pass3.json +6 -0
  64. data/ext/rj_schema/rapidjson/bin/jsonchecker/readme.txt +3 -0
  65. data/ext/rj_schema/rapidjson/bin/jsonschema/LICENSE +19 -0
  66. data/ext/rj_schema/rapidjson/bin/jsonschema/README.md +148 -0
  67. data/ext/rj_schema/rapidjson/bin/jsonschema/bin/jsonschema_suite +283 -0
  68. data/ext/rj_schema/rapidjson/bin/jsonschema/remotes/folder/folderInteger.json +3 -0
  69. data/ext/rj_schema/rapidjson/bin/jsonschema/remotes/integer.json +3 -0
  70. data/ext/rj_schema/rapidjson/bin/jsonschema/remotes/subSchemas.json +8 -0
  71. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/additionalItems.json +82 -0
  72. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/additionalProperties.json +88 -0
  73. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/default.json +49 -0
  74. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/dependencies.json +108 -0
  75. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/disallow.json +80 -0
  76. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/divisibleBy.json +60 -0
  77. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/enum.json +71 -0
  78. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/extends.json +94 -0
  79. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/items.json +46 -0
  80. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/maxItems.json +28 -0
  81. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/maxLength.json +33 -0
  82. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/maximum.json +42 -0
  83. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/minItems.json +28 -0
  84. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/minLength.json +33 -0
  85. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/minimum.json +42 -0
  86. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/optional/bignum.json +107 -0
  87. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/optional/format.json +222 -0
  88. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/optional/jsregex.json +18 -0
  89. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/optional/zeroTerminatedFloats.json +15 -0
  90. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/pattern.json +34 -0
  91. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/patternProperties.json +110 -0
  92. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/properties.json +92 -0
  93. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/ref.json +159 -0
  94. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/refRemote.json +74 -0
  95. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/required.json +53 -0
  96. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/type.json +474 -0
  97. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft3/uniqueItems.json +79 -0
  98. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/additionalItems.json +82 -0
  99. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/additionalProperties.json +88 -0
  100. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/allOf.json +112 -0
  101. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/anyOf.json +68 -0
  102. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/default.json +49 -0
  103. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/definitions.json +32 -0
  104. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/dependencies.json +113 -0
  105. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/enum.json +72 -0
  106. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/items.json +46 -0
  107. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/maxItems.json +28 -0
  108. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/maxLength.json +33 -0
  109. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/maxProperties.json +28 -0
  110. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/maximum.json +42 -0
  111. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/minItems.json +28 -0
  112. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/minLength.json +33 -0
  113. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/minProperties.json +28 -0
  114. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/minimum.json +42 -0
  115. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/multipleOf.json +60 -0
  116. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/not.json +96 -0
  117. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/oneOf.json +68 -0
  118. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/optional/bignum.json +107 -0
  119. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/optional/format.json +148 -0
  120. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/optional/zeroTerminatedFloats.json +15 -0
  121. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/pattern.json +34 -0
  122. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/patternProperties.json +110 -0
  123. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/properties.json +92 -0
  124. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/ref.json +159 -0
  125. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/refRemote.json +74 -0
  126. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/required.json +39 -0
  127. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/type.json +330 -0
  128. data/ext/rj_schema/rapidjson/bin/jsonschema/tests/draft4/uniqueItems.json +79 -0
  129. data/ext/rj_schema/rapidjson/bin/jsonschema/tox.ini +8 -0
  130. data/ext/rj_schema/rapidjson/bin/types/booleans.json +102 -0
  131. data/ext/rj_schema/rapidjson/bin/types/floats.json +102 -0
  132. data/ext/rj_schema/rapidjson/bin/types/guids.json +102 -0
  133. data/ext/rj_schema/rapidjson/bin/types/integers.json +102 -0
  134. data/ext/rj_schema/rapidjson/bin/types/mixed.json +592 -0
  135. data/ext/rj_schema/rapidjson/bin/types/nulls.json +102 -0
  136. data/ext/rj_schema/rapidjson/bin/types/paragraphs.json +102 -0
  137. data/ext/rj_schema/rapidjson/bin/types/readme.txt +1 -0
  138. data/ext/rj_schema/rapidjson/contrib/natvis/LICENSE +45 -0
  139. data/ext/rj_schema/rapidjson/contrib/natvis/README.md +7 -0
  140. data/ext/rj_schema/rapidjson/contrib/natvis/rapidjson.natvis +38 -0
  141. data/ext/rj_schema/rapidjson/doc/CMakeLists.txt +27 -0
  142. data/ext/rj_schema/rapidjson/doc/Doxyfile.in +2369 -0
  143. data/ext/rj_schema/rapidjson/doc/Doxyfile.zh-cn.in +2369 -0
  144. data/ext/rj_schema/rapidjson/doc/diagram/architecture.dot +50 -0
  145. data/ext/rj_schema/rapidjson/doc/diagram/architecture.png +0 -0
  146. data/ext/rj_schema/rapidjson/doc/diagram/insituparsing.dot +65 -0
  147. data/ext/rj_schema/rapidjson/doc/diagram/insituparsing.png +0 -0
  148. data/ext/rj_schema/rapidjson/doc/diagram/iterative-parser-states-diagram.dot +62 -0
  149. data/ext/rj_schema/rapidjson/doc/diagram/iterative-parser-states-diagram.png +0 -0
  150. data/ext/rj_schema/rapidjson/doc/diagram/makefile +8 -0
  151. data/ext/rj_schema/rapidjson/doc/diagram/move1.dot +47 -0
  152. data/ext/rj_schema/rapidjson/doc/diagram/move1.png +0 -0
  153. data/ext/rj_schema/rapidjson/doc/diagram/move2.dot +62 -0
  154. data/ext/rj_schema/rapidjson/doc/diagram/move2.png +0 -0
  155. data/ext/rj_schema/rapidjson/doc/diagram/move3.dot +60 -0
  156. data/ext/rj_schema/rapidjson/doc/diagram/move3.png +0 -0
  157. data/ext/rj_schema/rapidjson/doc/diagram/normalparsing.dot +56 -0
  158. data/ext/rj_schema/rapidjson/doc/diagram/normalparsing.png +0 -0
  159. data/ext/rj_schema/rapidjson/doc/diagram/simpledom.dot +54 -0
  160. data/ext/rj_schema/rapidjson/doc/diagram/simpledom.png +0 -0
  161. data/ext/rj_schema/rapidjson/doc/diagram/tutorial.dot +58 -0
  162. data/ext/rj_schema/rapidjson/doc/diagram/tutorial.png +0 -0
  163. data/ext/rj_schema/rapidjson/doc/diagram/utilityclass.dot +73 -0
  164. data/ext/rj_schema/rapidjson/doc/diagram/utilityclass.png +0 -0
  165. data/ext/rj_schema/rapidjson/doc/dom.md +280 -0
  166. data/ext/rj_schema/rapidjson/doc/dom.zh-cn.md +284 -0
  167. data/ext/rj_schema/rapidjson/doc/encoding.md +146 -0
  168. data/ext/rj_schema/rapidjson/doc/encoding.zh-cn.md +152 -0
  169. data/ext/rj_schema/rapidjson/doc/faq.md +289 -0
  170. data/ext/rj_schema/rapidjson/doc/faq.zh-cn.md +290 -0
  171. data/ext/rj_schema/rapidjson/doc/features.md +104 -0
  172. data/ext/rj_schema/rapidjson/doc/features.zh-cn.md +103 -0
  173. data/ext/rj_schema/rapidjson/doc/internals.md +368 -0
  174. data/ext/rj_schema/rapidjson/doc/internals.zh-cn.md +363 -0
  175. data/ext/rj_schema/rapidjson/doc/logo/rapidjson.png +0 -0
  176. data/ext/rj_schema/rapidjson/doc/logo/rapidjson.svg +119 -0
  177. data/ext/rj_schema/rapidjson/doc/misc/DoxygenLayout.xml +194 -0
  178. data/ext/rj_schema/rapidjson/doc/misc/doxygenextra.css +274 -0
  179. data/ext/rj_schema/rapidjson/doc/misc/footer.html +11 -0
  180. data/ext/rj_schema/rapidjson/doc/misc/header.html +24 -0
  181. data/ext/rj_schema/rapidjson/doc/npm.md +31 -0
  182. data/ext/rj_schema/rapidjson/doc/performance.md +26 -0
  183. data/ext/rj_schema/rapidjson/doc/performance.zh-cn.md +26 -0
  184. data/ext/rj_schema/rapidjson/doc/pointer.md +234 -0
  185. data/ext/rj_schema/rapidjson/doc/pointer.zh-cn.md +234 -0
  186. data/ext/rj_schema/rapidjson/doc/sax.md +509 -0
  187. data/ext/rj_schema/rapidjson/doc/sax.zh-cn.md +487 -0
  188. data/ext/rj_schema/rapidjson/doc/schema.md +505 -0
  189. data/ext/rj_schema/rapidjson/doc/schema.zh-cn.md +237 -0
  190. data/ext/rj_schema/rapidjson/doc/stream.md +426 -0
  191. data/ext/rj_schema/rapidjson/doc/stream.zh-cn.md +426 -0
  192. data/ext/rj_schema/rapidjson/doc/tutorial.md +536 -0
  193. data/ext/rj_schema/rapidjson/doc/tutorial.zh-cn.md +534 -0
  194. data/ext/rj_schema/rapidjson/docker/debian/Dockerfile +8 -0
  195. data/ext/rj_schema/rapidjson/example/CMakeLists.txt +45 -0
  196. data/ext/rj_schema/rapidjson/example/archiver/archiver.cpp +292 -0
  197. data/ext/rj_schema/rapidjson/example/archiver/archiver.h +145 -0
  198. data/ext/rj_schema/rapidjson/example/archiver/archivertest.cpp +287 -0
  199. data/ext/rj_schema/rapidjson/example/capitalize/capitalize.cpp +67 -0
  200. data/ext/rj_schema/rapidjson/example/condense/condense.cpp +32 -0
  201. data/ext/rj_schema/rapidjson/example/filterkey/filterkey.cpp +135 -0
  202. data/ext/rj_schema/rapidjson/example/filterkeydom/filterkeydom.cpp +170 -0
  203. data/ext/rj_schema/rapidjson/example/jsonx/jsonx.cpp +207 -0
  204. data/ext/rj_schema/rapidjson/example/lookaheadparser/lookaheadparser.cpp +350 -0
  205. data/ext/rj_schema/rapidjson/example/messagereader/messagereader.cpp +105 -0
  206. data/ext/rj_schema/rapidjson/example/parsebyparts/parsebyparts.cpp +176 -0
  207. data/ext/rj_schema/rapidjson/example/pretty/pretty.cpp +30 -0
  208. data/ext/rj_schema/rapidjson/example/prettyauto/prettyauto.cpp +56 -0
  209. data/ext/rj_schema/rapidjson/example/schemavalidator/schemavalidator.cpp +78 -0
  210. data/ext/rj_schema/rapidjson/example/serialize/serialize.cpp +173 -0
  211. data/ext/rj_schema/rapidjson/example/simpledom/simpledom.cpp +29 -0
  212. data/ext/rj_schema/rapidjson/example/simplepullreader/simplepullreader.cpp +53 -0
  213. data/ext/rj_schema/rapidjson/example/simplereader/simplereader.cpp +42 -0
  214. data/ext/rj_schema/rapidjson/example/simplewriter/simplewriter.cpp +36 -0
  215. data/ext/rj_schema/rapidjson/example/tutorial/tutorial.cpp +151 -0
  216. data/ext/rj_schema/rapidjson/include/rapidjson/allocators.h +271 -0
  217. data/ext/rj_schema/rapidjson/include/rapidjson/cursorstreamwrapper.h +78 -0
  218. data/ext/rj_schema/rapidjson/include/rapidjson/document.h +2630 -0
  219. data/ext/rj_schema/rapidjson/include/rapidjson/encodedstream.h +299 -0
  220. data/ext/rj_schema/rapidjson/include/rapidjson/encodings.h +716 -0
  221. data/ext/rj_schema/rapidjson/include/rapidjson/error/en.h +74 -0
  222. data/ext/rj_schema/rapidjson/include/rapidjson/error/error.h +161 -0
  223. data/ext/rj_schema/rapidjson/include/rapidjson/filereadstream.h +99 -0
  224. data/ext/rj_schema/rapidjson/include/rapidjson/filewritestream.h +104 -0
  225. data/ext/rj_schema/rapidjson/include/rapidjson/fwd.h +151 -0
  226. data/ext/rj_schema/rapidjson/include/rapidjson/internal/biginteger.h +290 -0
  227. data/ext/rj_schema/rapidjson/include/rapidjson/internal/diyfp.h +258 -0
  228. data/ext/rj_schema/rapidjson/include/rapidjson/internal/dtoa.h +245 -0
  229. data/ext/rj_schema/rapidjson/include/rapidjson/internal/ieee754.h +78 -0
  230. data/ext/rj_schema/rapidjson/include/rapidjson/internal/itoa.h +304 -0
  231. data/ext/rj_schema/rapidjson/include/rapidjson/internal/meta.h +181 -0
  232. data/ext/rj_schema/rapidjson/include/rapidjson/internal/pow10.h +55 -0
  233. data/ext/rj_schema/rapidjson/include/rapidjson/internal/regex.h +734 -0
  234. data/ext/rj_schema/rapidjson/include/rapidjson/internal/stack.h +231 -0
  235. data/ext/rj_schema/rapidjson/include/rapidjson/internal/strfunc.h +69 -0
  236. data/ext/rj_schema/rapidjson/include/rapidjson/internal/strtod.h +269 -0
  237. data/ext/rj_schema/rapidjson/include/rapidjson/internal/swap.h +46 -0
  238. data/ext/rj_schema/rapidjson/include/rapidjson/istreamwrapper.h +115 -0
  239. data/ext/rj_schema/rapidjson/include/rapidjson/memorybuffer.h +70 -0
  240. data/ext/rj_schema/rapidjson/include/rapidjson/memorystream.h +71 -0
  241. data/ext/rj_schema/rapidjson/include/rapidjson/msinttypes/inttypes.h +316 -0
  242. data/ext/rj_schema/rapidjson/include/rapidjson/msinttypes/stdint.h +300 -0
  243. data/ext/rj_schema/rapidjson/include/rapidjson/ostreamwrapper.h +81 -0
  244. data/ext/rj_schema/rapidjson/include/rapidjson/pointer.h +1363 -0
  245. data/ext/rj_schema/rapidjson/include/rapidjson/prettywriter.h +277 -0
  246. data/ext/rj_schema/rapidjson/include/rapidjson/rapidjson.h +628 -0
  247. data/ext/rj_schema/rapidjson/include/rapidjson/reader.h +2222 -0
  248. data/ext/rj_schema/rapidjson/include/rapidjson/schema.h +2479 -0
  249. data/ext/rj_schema/rapidjson/include/rapidjson/stream.h +223 -0
  250. data/ext/rj_schema/rapidjson/include/rapidjson/stringbuffer.h +121 -0
  251. data/ext/rj_schema/rapidjson/include/rapidjson/writer.h +716 -0
  252. data/ext/rj_schema/rapidjson/include_dirs.js +2 -0
  253. data/ext/rj_schema/rapidjson/library.json +15 -0
  254. data/ext/rj_schema/rapidjson/license.txt +57 -0
  255. data/ext/rj_schema/rapidjson/package.json +24 -0
  256. data/ext/rj_schema/rapidjson/rapidjson.autopkg +77 -0
  257. data/ext/rj_schema/rapidjson/readme.md +160 -0
  258. data/ext/rj_schema/rapidjson/readme.zh-cn.md +152 -0
  259. data/ext/rj_schema/rapidjson/test/CMakeLists.txt +20 -0
  260. data/ext/rj_schema/rapidjson/test/perftest/CMakeLists.txt +28 -0
  261. data/ext/rj_schema/rapidjson/test/perftest/misctest.cpp +974 -0
  262. data/ext/rj_schema/rapidjson/test/perftest/perftest.cpp +24 -0
  263. data/ext/rj_schema/rapidjson/test/perftest/perftest.h +185 -0
  264. data/ext/rj_schema/rapidjson/test/perftest/platformtest.cpp +166 -0
  265. data/ext/rj_schema/rapidjson/test/perftest/rapidjsontest.cpp +472 -0
  266. data/ext/rj_schema/rapidjson/test/perftest/schematest.cpp +216 -0
  267. data/ext/rj_schema/rapidjson/test/unittest/CMakeLists.txt +92 -0
  268. data/ext/rj_schema/rapidjson/test/unittest/allocatorstest.cpp +102 -0
  269. data/ext/rj_schema/rapidjson/test/unittest/bigintegertest.cpp +133 -0
  270. data/ext/rj_schema/rapidjson/test/unittest/cursorstreamwrappertest.cpp +115 -0
  271. data/ext/rj_schema/rapidjson/test/unittest/documenttest.cpp +672 -0
  272. data/ext/rj_schema/rapidjson/test/unittest/dtoatest.cpp +98 -0
  273. data/ext/rj_schema/rapidjson/test/unittest/encodedstreamtest.cpp +313 -0
  274. data/ext/rj_schema/rapidjson/test/unittest/encodingstest.cpp +451 -0
  275. data/ext/rj_schema/rapidjson/test/unittest/filestreamtest.cpp +112 -0
  276. data/ext/rj_schema/rapidjson/test/unittest/fwdtest.cpp +230 -0
  277. data/ext/rj_schema/rapidjson/test/unittest/istreamwrappertest.cpp +181 -0
  278. data/ext/rj_schema/rapidjson/test/unittest/itoatest.cpp +160 -0
  279. data/ext/rj_schema/rapidjson/test/unittest/jsoncheckertest.cpp +143 -0
  280. data/ext/rj_schema/rapidjson/test/unittest/namespacetest.cpp +70 -0
  281. data/ext/rj_schema/rapidjson/test/unittest/ostreamwrappertest.cpp +92 -0
  282. data/ext/rj_schema/rapidjson/test/unittest/pointertest.cpp +1529 -0
  283. data/ext/rj_schema/rapidjson/test/unittest/prettywritertest.cpp +344 -0
  284. data/ext/rj_schema/rapidjson/test/unittest/readertest.cpp +1895 -0
  285. data/ext/rj_schema/rapidjson/test/unittest/regextest.cpp +638 -0
  286. data/ext/rj_schema/rapidjson/test/unittest/schematest.cpp +2009 -0
  287. data/ext/rj_schema/rapidjson/test/unittest/simdtest.cpp +219 -0
  288. data/ext/rj_schema/rapidjson/test/unittest/strfunctest.cpp +30 -0
  289. data/ext/rj_schema/rapidjson/test/unittest/stringbuffertest.cpp +192 -0
  290. data/ext/rj_schema/rapidjson/test/unittest/strtodtest.cpp +132 -0
  291. data/ext/rj_schema/rapidjson/test/unittest/unittest.cpp +51 -0
  292. data/ext/rj_schema/rapidjson/test/unittest/unittest.h +140 -0
  293. data/ext/rj_schema/rapidjson/test/unittest/valuetest.cpp +1829 -0
  294. data/ext/rj_schema/rapidjson/test/unittest/writertest.cpp +598 -0
  295. data/ext/rj_schema/rapidjson/test/valgrind.supp +17 -0
  296. data/ext/rj_schema/rapidjson/travis-doxygen.sh +121 -0
  297. data/ext/rj_schema/rj_schema.cpp +136 -0
  298. data/lib/rj_schema.rb +7 -0
  299. metadata +371 -0
@@ -0,0 +1,58 @@
1
+ digraph {
2
+ compound=true
3
+ fontname="Inconsolata, Consolas"
4
+ fontsize=10
5
+ margin="0,0"
6
+ ranksep=0.2
7
+ penwidth=0.5
8
+
9
+ node [fontname="Inconsolata, Consolas", fontsize=10, penwidth=0.5]
10
+ edge [fontname="Inconsolata, Consolas", fontsize=10]
11
+
12
+ subgraph cluster1 {
13
+ margin="10,10"
14
+ labeljust="left"
15
+ label = "Document"
16
+ style=filled
17
+ fillcolor=gray95
18
+ node [shape=Mrecord, style=filled, colorscheme=spectral7]
19
+
20
+ root [label="{object|}", fillcolor=3]
21
+
22
+ {
23
+ hello [label="{string|\"hello\"}", fillcolor=5]
24
+ t [label="{string|\"t\"}", fillcolor=5]
25
+ f [label="{string|\"f\"}", fillcolor=5]
26
+ n [label="{string|\"n\"}", fillcolor=5]
27
+ i [label="{string|\"i\"}", fillcolor=5]
28
+ pi [label="{string|\"pi\"}", fillcolor=5]
29
+ a [label="{string|\"a\"}", fillcolor=5]
30
+
31
+ world [label="{string|\"world\"}", fillcolor=5]
32
+ true [label="{true|}", fillcolor=7]
33
+ false [label="{false|}", fillcolor=2]
34
+ null [label="{null|}", fillcolor=1]
35
+ i1 [label="{number|123}", fillcolor=6]
36
+ pi1 [label="{number|3.1416}", fillcolor=6]
37
+ array [label="{array|size=4}", fillcolor=4]
38
+
39
+ a1 [label="{number|1}", fillcolor=6]
40
+ a2 [label="{number|2}", fillcolor=6]
41
+ a3 [label="{number|3}", fillcolor=6]
42
+ a4 [label="{number|4}", fillcolor=6]
43
+ }
44
+
45
+ edge [arrowhead=vee]
46
+ root -> { hello; t; f; n; i; pi; a }
47
+ array -> { a1; a2; a3; a4 }
48
+
49
+ edge [arrowhead=none]
50
+ hello -> world
51
+ t -> true
52
+ f -> false
53
+ n -> null
54
+ i -> i1
55
+ pi -> pi1
56
+ a -> array
57
+ }
58
+ }
@@ -0,0 +1,73 @@
1
+ digraph {
2
+ rankdir=LR
3
+ compound=true
4
+ fontname="Inconsolata, Consolas"
5
+ fontsize=10
6
+ margin="0,0"
7
+ ranksep=0.3
8
+ nodesep=0.15
9
+ penwidth=0.5
10
+ colorscheme=spectral7
11
+
12
+ node [shape=box, fontname="Inconsolata, Consolas", fontsize=10, penwidth=0.5, style=filled, fillcolor=white]
13
+ edge [fontname="Inconsolata, Consolas", fontsize=10, penwidth=0.5]
14
+
15
+ subgraph cluster0 {
16
+ style=filled
17
+ fillcolor=4
18
+
19
+ Encoding [label="<<concept>>\nEncoding"]
20
+
21
+ edge [arrowtail=onormal, dir=back]
22
+ Encoding -> { UTF8; UTF16; UTF32; ASCII; AutoUTF }
23
+ UTF16 -> { UTF16LE; UTF16BE }
24
+ UTF32 -> { UTF32LE; UTF32BE }
25
+ }
26
+
27
+ subgraph cluster1 {
28
+ style=filled
29
+ fillcolor=5
30
+
31
+ Stream [label="<<concept>>\nStream"]
32
+ InputByteStream [label="<<concept>>\nInputByteStream"]
33
+ OutputByteStream [label="<<concept>>\nOutputByteStream"]
34
+
35
+ edge [arrowtail=onormal, dir=back]
36
+ Stream -> {
37
+ StringStream; InsituStringStream; StringBuffer;
38
+ EncodedInputStream; EncodedOutputStream;
39
+ AutoUTFInputStream; AutoUTFOutputStream
40
+ InputByteStream; OutputByteStream
41
+ }
42
+
43
+ InputByteStream -> { MemoryStream; FlieReadStream }
44
+ OutputByteStream -> { MemoryBuffer; FileWriteStream }
45
+ }
46
+
47
+ subgraph cluster2 {
48
+ style=filled
49
+ fillcolor=3
50
+
51
+ Allocator [label="<<concept>>\nAllocator"]
52
+
53
+ edge [arrowtail=onormal, dir=back]
54
+ Allocator -> { CrtAllocator; MemoryPoolAllocator }
55
+ }
56
+
57
+ {
58
+ edge [arrowtail=odiamond, arrowhead=vee, dir=both]
59
+ EncodedInputStream -> InputByteStream
60
+ EncodedOutputStream -> OutputByteStream
61
+ AutoUTFInputStream -> InputByteStream
62
+ AutoUTFOutputStream -> OutputByteStream
63
+ MemoryPoolAllocator -> Allocator [label="base", tailport=s]
64
+ }
65
+
66
+ {
67
+ edge [arrowhead=vee, style=dashed]
68
+ AutoUTFInputStream -> AutoUTF
69
+ AutoUTFOutputStream -> AutoUTF
70
+ }
71
+
72
+ //UTF32LE -> Stream [style=invis]
73
+ }
@@ -0,0 +1,280 @@
1
+ # DOM
2
+
3
+ Document Object Model(DOM) is an in-memory representation of JSON for query and manipulation. The basic usage of DOM is described in [Tutorial](doc/tutorial.md). This section will describe some details and more advanced usages.
4
+
5
+ [TOC]
6
+
7
+ # Template {#Template}
8
+
9
+ In the tutorial, `Value` and `Document` was used. Similarly to `std::string`, these are actually `typedef` of template classes:
10
+
11
+ ~~~~~~~~~~cpp
12
+ namespace rapidjson {
13
+
14
+ template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
15
+ class GenericValue {
16
+ // ...
17
+ };
18
+
19
+ template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
20
+ class GenericDocument : public GenericValue<Encoding, Allocator> {
21
+ // ...
22
+ };
23
+
24
+ typedef GenericValue<UTF8<> > Value;
25
+ typedef GenericDocument<UTF8<> > Document;
26
+
27
+ } // namespace rapidjson
28
+ ~~~~~~~~~~
29
+
30
+ User can customize these template parameters.
31
+
32
+ ## Encoding {#Encoding}
33
+
34
+ The `Encoding` parameter specifies the encoding of JSON String value in memory. Possible options are `UTF8`, `UTF16`, `UTF32`. Note that, these 3 types are also template class. `UTF8<>` is `UTF8<char>`, which means using char to store the characters. You may refer to [Encoding](doc/encoding.md) for details.
35
+
36
+ Suppose a Windows application would query localization strings stored in JSON files. Unicode-enabled functions in Windows use UTF-16 (wide character) encoding. No matter what encoding was used in JSON files, we can store the strings in UTF-16 in memory.
37
+
38
+ ~~~~~~~~~~cpp
39
+ using namespace rapidjson;
40
+
41
+ typedef GenericDocument<UTF16<> > WDocument;
42
+ typedef GenericValue<UTF16<> > WValue;
43
+
44
+ FILE* fp = fopen("localization.json", "rb"); // non-Windows use "r"
45
+
46
+ char readBuffer[256];
47
+ FileReadStream bis(fp, readBuffer, sizeof(readBuffer));
48
+
49
+ AutoUTFInputStream<unsigned, FileReadStream> eis(bis); // wraps bis into eis
50
+
51
+ WDocument d;
52
+ d.ParseStream<0, AutoUTF<unsigned> >(eis);
53
+
54
+ const WValue locale(L"ja"); // Japanese
55
+
56
+ MessageBoxW(hWnd, d[locale].GetString(), L"Test", MB_OK);
57
+ ~~~~~~~~~~
58
+
59
+ ## Allocator {#Allocator}
60
+
61
+ The `Allocator` defines which allocator class is used when allocating/deallocating memory for `Document`/`Value`. `Document` owns, or references to an `Allocator` instance. On the other hand, `Value` does not do so, in order to reduce memory consumption.
62
+
63
+ The default allocator used in `GenericDocument` is `MemoryPoolAllocator`. This allocator actually allocate memory sequentially, and cannot deallocate one by one. This is very suitable when parsing a JSON into a DOM tree.
64
+
65
+ Another allocator is `CrtAllocator`, of which CRT is short for C RunTime library. This allocator simply calls the standard `malloc()`/`realloc()`/`free()`. When there is a lot of add and remove operations, this allocator may be preferred. But this allocator is far less efficient than `MemoryPoolAllocator`.
66
+
67
+ # Parsing {#Parsing}
68
+
69
+ `Document` provides several functions for parsing. In below, (1) is the fundamental function, while the others are helpers which call (1).
70
+
71
+ ~~~~~~~~~~cpp
72
+ using namespace rapidjson;
73
+
74
+ // (1) Fundamental
75
+ template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
76
+ GenericDocument& GenericDocument::ParseStream(InputStream& is);
77
+
78
+ // (2) Using the same Encoding for stream
79
+ template <unsigned parseFlags, typename InputStream>
80
+ GenericDocument& GenericDocument::ParseStream(InputStream& is);
81
+
82
+ // (3) Using default parse flags
83
+ template <typename InputStream>
84
+ GenericDocument& GenericDocument::ParseStream(InputStream& is);
85
+
86
+ // (4) In situ parsing
87
+ template <unsigned parseFlags>
88
+ GenericDocument& GenericDocument::ParseInsitu(Ch* str);
89
+
90
+ // (5) In situ parsing, using default parse flags
91
+ GenericDocument& GenericDocument::ParseInsitu(Ch* str);
92
+
93
+ // (6) Normal parsing of a string
94
+ template <unsigned parseFlags, typename SourceEncoding>
95
+ GenericDocument& GenericDocument::Parse(const Ch* str);
96
+
97
+ // (7) Normal parsing of a string, using same Encoding of Document
98
+ template <unsigned parseFlags>
99
+ GenericDocument& GenericDocument::Parse(const Ch* str);
100
+
101
+ // (8) Normal parsing of a string, using default parse flags
102
+ GenericDocument& GenericDocument::Parse(const Ch* str);
103
+ ~~~~~~~~~~
104
+
105
+ The examples of [tutorial](doc/tutorial.md) uses (8) for normal parsing of string. The examples of [stream](doc/stream.md) uses the first three. *In situ* parsing will be described soon.
106
+
107
+ The `parseFlags` are combination of the following bit-flags:
108
+
109
+ Parse flags | Meaning
110
+ ------------------------------|-----------------------------------
111
+ `kParseNoFlags` | No flag is set.
112
+ `kParseDefaultFlags` | Default parse flags. It is equal to macro `RAPIDJSON_PARSE_DEFAULT_FLAGS`, which is defined as `kParseNoFlags`.
113
+ `kParseInsituFlag` | In-situ(destructive) parsing.
114
+ `kParseValidateEncodingFlag` | Validate encoding of JSON strings.
115
+ `kParseIterativeFlag` | Iterative(constant complexity in terms of function call stack size) parsing.
116
+ `kParseStopWhenDoneFlag` | After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate `kParseErrorDocumentRootNotSingular` error. Using this flag for parsing multiple JSONs in the same stream.
117
+ `kParseFullPrecisionFlag` | Parse number in full precision (slower). If this flag is not set, the normal precision (faster) is used. Normal precision has maximum 3 [ULP](http://en.wikipedia.org/wiki/Unit_in_the_last_place) error.
118
+ `kParseCommentsFlag` | Allow one-line `// ...` and multi-line `/* ... */` comments (relaxed JSON syntax).
119
+ `kParseNumbersAsStringsFlag` | Parse numerical type values as strings.
120
+ `kParseTrailingCommasFlag` | Allow trailing commas at the end of objects and arrays (relaxed JSON syntax).
121
+ `kParseNanAndInfFlag` | Allow parsing `NaN`, `Inf`, `Infinity`, `-Inf` and `-Infinity` as `double` values (relaxed JSON syntax).
122
+
123
+ By using a non-type template parameter, instead of a function parameter, C++ compiler can generate code which is optimized for specified combinations, improving speed, and reducing code size (if only using a single specialization). The downside is the flags needed to be determined in compile-time.
124
+
125
+ The `SourceEncoding` parameter defines what encoding is in the stream. This can be differed to the `Encoding` of the `Document`. See [Transcoding and Validation](#TranscodingAndValidation) section for details.
126
+
127
+ And the `InputStream` is type of input stream.
128
+
129
+ ## Parse Error {#ParseError}
130
+
131
+ When the parse processing succeeded, the `Document` contains the parse results. When there is an error, the original DOM is *unchanged*. And the error state of parsing can be obtained by `bool HasParseError()`, `ParseErrorCode GetParseError()` and `size_t GetErrorOffset()`.
132
+
133
+ Parse Error Code | Description
134
+ --------------------------------------------|---------------------------------------------------
135
+ `kParseErrorNone` | No error.
136
+ `kParseErrorDocumentEmpty` | The document is empty.
137
+ `kParseErrorDocumentRootNotSingular` | The document root must not follow by other values.
138
+ `kParseErrorValueInvalid` | Invalid value.
139
+ `kParseErrorObjectMissName` | Missing a name for object member.
140
+ `kParseErrorObjectMissColon` | Missing a colon after a name of object member.
141
+ `kParseErrorObjectMissCommaOrCurlyBracket` | Missing a comma or `}` after an object member.
142
+ `kParseErrorArrayMissCommaOrSquareBracket` | Missing a comma or `]` after an array element.
143
+ `kParseErrorStringUnicodeEscapeInvalidHex` | Incorrect hex digit after `\\u` escape in string.
144
+ `kParseErrorStringUnicodeSurrogateInvalid` | The surrogate pair in string is invalid.
145
+ `kParseErrorStringEscapeInvalid` | Invalid escape character in string.
146
+ `kParseErrorStringMissQuotationMark` | Missing a closing quotation mark in string.
147
+ `kParseErrorStringInvalidEncoding` | Invalid encoding in string.
148
+ `kParseErrorNumberTooBig` | Number too big to be stored in `double`.
149
+ `kParseErrorNumberMissFraction` | Miss fraction part in number.
150
+ `kParseErrorNumberMissExponent` | Miss exponent in number.
151
+
152
+ The offset of error is defined as the character number from beginning of stream. Currently RapidJSON does not keep track of line number.
153
+
154
+ To get an error message, RapidJSON provided a English messages in `rapidjson/error/en.h`. User can customize it for other locales, or use a custom localization system.
155
+
156
+ Here shows an example of parse error handling.
157
+
158
+ ~~~~~~~~~~cpp
159
+ #include "rapidjson/document.h"
160
+ #include "rapidjson/error/en.h"
161
+
162
+ // ...
163
+ Document d;
164
+ if (d.Parse(json).HasParseError()) {
165
+ fprintf(stderr, "\nError(offset %u): %s\n",
166
+ (unsigned)d.GetErrorOffset(),
167
+ GetParseError_En(d.GetParseError()));
168
+ // ...
169
+ }
170
+ ~~~~~~~~~~
171
+
172
+ ## In Situ Parsing {#InSituParsing}
173
+
174
+ From [Wikipedia](http://en.wikipedia.org/wiki/In_situ):
175
+
176
+ > *In situ* ... is a Latin phrase that translates literally to "on site" or "in position". It means "locally", "on site", "on the premises" or "in place" to describe an event where it takes place, and is used in many different contexts.
177
+ > ...
178
+ > (In computer science) An algorithm is said to be an in situ algorithm, or in-place algorithm, if the extra amount of memory required to execute the algorithm is O(1), that is, does not exceed a constant no matter how large the input. For example, heapsort is an in situ sorting algorithm.
179
+
180
+ In normal parsing process, a large overhead is to decode JSON strings and copy them to other buffers. *In situ* parsing decodes those JSON string at the place where it is stored. It is possible in JSON because the length of decoded string is always shorter than or equal to the one in JSON. In this context, decoding a JSON string means to process the escapes, such as `"\n"`, `"\u1234"`, etc., and add a null terminator (`'\0'`)at the end of string.
181
+
182
+ The following diagrams compare normal and *in situ* parsing. The JSON string values contain pointers to the decoded string.
183
+
184
+ ![normal parsing](diagram/normalparsing.png)
185
+
186
+ In normal parsing, the decoded string are copied to freshly allocated buffers. `"\\n"` (2 characters) is decoded as `"\n"` (1 character). `"\\u0073"` (6 characters) is decoded as `"s"` (1 character).
187
+
188
+ ![instiu parsing](diagram/insituparsing.png)
189
+
190
+ *In situ* parsing just modified the original JSON. Updated characters are highlighted in the diagram. If the JSON string does not contain escape character, such as `"msg"`, the parsing process merely replace the closing double quotation mark with a null character.
191
+
192
+ Since *in situ* parsing modify the input, the parsing API needs `char*` instead of `const char*`.
193
+
194
+ ~~~~~~~~~~cpp
195
+ // Read whole file into a buffer
196
+ FILE* fp = fopen("test.json", "r");
197
+ fseek(fp, 0, SEEK_END);
198
+ size_t filesize = (size_t)ftell(fp);
199
+ fseek(fp, 0, SEEK_SET);
200
+ char* buffer = (char*)malloc(filesize + 1);
201
+ size_t readLength = fread(buffer, 1, filesize, fp);
202
+ buffer[readLength] = '\0';
203
+ fclose(fp);
204
+
205
+ // In situ parsing the buffer into d, buffer will also be modified
206
+ Document d;
207
+ d.ParseInsitu(buffer);
208
+
209
+ // Query/manipulate the DOM here...
210
+
211
+ free(buffer);
212
+ // Note: At this point, d may have dangling pointers pointed to the deallocated buffer.
213
+ ~~~~~~~~~~
214
+
215
+ The JSON strings are marked as const-string. But they may not be really "constant". The life cycle of it depends on the JSON buffer.
216
+
217
+ In situ parsing minimizes allocation overheads and memory copying. Generally this improves cache coherence, which is an important factor of performance in modern computer.
218
+
219
+ There are some limitations of *in situ* parsing:
220
+
221
+ 1. The whole JSON is in memory.
222
+ 2. The source encoding in stream and target encoding in document must be the same.
223
+ 3. The buffer need to be retained until the document is no longer used.
224
+ 4. If the DOM need to be used for long period after parsing, and there are few JSON strings in the DOM, retaining the buffer may be a memory waste.
225
+
226
+ *In situ* parsing is mostly suitable for short-term JSON that only need to be processed once, and then be released from memory. In practice, these situation is very common, for example, deserializing JSON to C++ objects, processing web requests represented in JSON, etc.
227
+
228
+ ## Transcoding and Validation {#TranscodingAndValidation}
229
+
230
+ RapidJSON supports conversion between Unicode formats (officially termed UCS Transformation Format) internally. During DOM parsing, the source encoding of the stream can be different from the encoding of the DOM. For example, the source stream contains a UTF-8 JSON, while the DOM is using UTF-16 encoding. There is an example code in [EncodedInputStream](doc/stream.md).
231
+
232
+ When writing a JSON from DOM to output stream, transcoding can also be used. An example is in [EncodedOutputStream](doc/stream.md).
233
+
234
+ During transcoding, the source string is decoded to into Unicode code points, and then the code points are encoded in the target format. During decoding, it will validate the byte sequence in the source string. If it is not a valid sequence, the parser will be stopped with `kParseErrorStringInvalidEncoding` error.
235
+
236
+ When the source encoding of stream is the same as encoding of DOM, by default, the parser will *not* validate the sequence. User may use `kParseValidateEncodingFlag` to force validation.
237
+
238
+ # Techniques {#Techniques}
239
+
240
+ Some techniques about using DOM API is discussed here.
241
+
242
+ ## DOM as SAX Event Publisher
243
+
244
+ In RapidJSON, stringifying a DOM with `Writer` may be look a little bit weird.
245
+
246
+ ~~~~~~~~~~cpp
247
+ // ...
248
+ Writer<StringBuffer> writer(buffer);
249
+ d.Accept(writer);
250
+ ~~~~~~~~~~
251
+
252
+ Actually, `Value::Accept()` is responsible for publishing SAX events about the value to the handler. With this design, `Value` and `Writer` are decoupled. `Value` can generate SAX events, and `Writer` can handle those events.
253
+
254
+ User may create custom handlers for transforming the DOM into other formats. For example, a handler which converts the DOM into XML.
255
+
256
+ For more about SAX events and handler, please refer to [SAX](doc/sax.md).
257
+
258
+ ## User Buffer {#UserBuffer}
259
+
260
+ Some applications may try to avoid memory allocations whenever possible.
261
+
262
+ `MemoryPoolAllocator` can support this by letting user to provide a buffer. The buffer can be on the program stack, or a "scratch buffer" which is statically allocated (a static/global array) for storing temporary data.
263
+
264
+ `MemoryPoolAllocator` will use the user buffer to satisfy allocations. When the user buffer is used up, it will allocate a chunk of memory from the base allocator (by default the `CrtAllocator`).
265
+
266
+ Here is an example of using stack memory. The first allocator is for storing values, while the second allocator is for storing temporary data during parsing.
267
+
268
+ ~~~~~~~~~~cpp
269
+ typedef GenericDocument<UTF8<>, MemoryPoolAllocator<>, MemoryPoolAllocator<>> DocumentType;
270
+ char valueBuffer[4096];
271
+ char parseBuffer[1024];
272
+ MemoryPoolAllocator<> valueAllocator(valueBuffer, sizeof(valueBuffer));
273
+ MemoryPoolAllocator<> parseAllocator(parseBuffer, sizeof(parseBuffer));
274
+ DocumentType d(&valueAllocator, sizeof(parseBuffer), &parseAllocator);
275
+ d.Parse(json);
276
+ ~~~~~~~~~~
277
+
278
+ If the total size of allocation is less than 4096+1024 bytes during parsing, this code does not invoke any heap allocation (via `new` or `malloc()`) at all.
279
+
280
+ User can query the current memory consumption in bytes via `MemoryPoolAllocator::Size()`. And then user can determine a suitable size of user buffer.
@@ -0,0 +1,284 @@
1
+ # DOM
2
+
3
+ 文档对象模型(Document Object Model, DOM)是一种罝于内存中的 JSON 表示方式,以供查询及操作。我们己于 [教程](doc/tutorial.zh-cn.md) 中介绍了 DOM 的基本用法,本节将讲述一些细节及高级用法。
4
+
5
+ [TOC]
6
+
7
+ # 模板 {#Template}
8
+
9
+ 教程中使用了 `Value` 和 `Document` 类型。与 `std::string` 相似,这些类型其实是两个模板类的 `typedef`:
10
+
11
+ ~~~~~~~~~~cpp
12
+ namespace rapidjson {
13
+
14
+ template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
15
+ class GenericValue {
16
+ // ...
17
+ };
18
+
19
+ template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
20
+ class GenericDocument : public GenericValue<Encoding, Allocator> {
21
+ // ...
22
+ };
23
+
24
+ typedef GenericValue<UTF8<> > Value;
25
+ typedef GenericDocument<UTF8<> > Document;
26
+
27
+ } // namespace rapidjson
28
+ ~~~~~~~~~~
29
+
30
+ 使用者可以自定义这些模板参数。
31
+
32
+ ## 编码 {#Encoding}
33
+
34
+ `Encoding` 参数指明在内存中的 JSON String 使用哪种编码。可行的选项有 `UTF8`、`UTF16`、`UTF32`。要注意这 3 个类型其实也是模板类。`UTF8<>` 等同 `UTF8<char>`,这代表它使用 `char` 来存储字符串。更多细节可以参考 [编码](doc/encoding.zh-cn.md)。
35
+
36
+ 这里是一个例子。假设一个 Windows 应用软件希望查询存储于 JSON 中的本地化字符串。Windows 中含 Unicode 的函数使用 UTF-16(宽字符)编码。无论 JSON 文件使用哪种编码,我们都可以把字符串以 UTF-16 形式存储在内存。
37
+
38
+ ~~~~~~~~~~cpp
39
+ using namespace rapidjson;
40
+
41
+ typedef GenericDocument<UTF16<> > WDocument;
42
+ typedef GenericValue<UTF16<> > WValue;
43
+
44
+ FILE* fp = fopen("localization.json", "rb"); // 非 Windows 平台使用 "r"
45
+
46
+ char readBuffer[256];
47
+ FileReadStream bis(fp, readBuffer, sizeof(readBuffer));
48
+
49
+ AutoUTFInputStream<unsigned, FileReadStream> eis(bis); // 包装 bis 成 eis
50
+
51
+ WDocument d;
52
+ d.ParseStream<0, AutoUTF<unsigned> >(eis);
53
+
54
+ const WValue locale(L"ja"); // Japanese
55
+
56
+ MessageBoxW(hWnd, d[locale].GetString(), L"Test", MB_OK);
57
+ ~~~~~~~~~~
58
+
59
+ ## 分配器 {#Allocator}
60
+
61
+ `Allocator` 定义当 `Document`/`Value` 分配或释放内存时使用那个分配类。`Document` 拥有或引用到一个 `Allocator` 实例。而为了节省内存,`Value` 没有这么做。
62
+
63
+ `GenericDocument` 的缺省分配器是 `MemoryPoolAllocator`。此分配器实际上会顺序地分配内存,并且不能逐一释放。当要解析一个 JSON 并生成 DOM,这种分配器是非常合适的。
64
+
65
+ RapidJSON 还提供另一个分配器 `CrtAllocator`,当中 CRT 是 C 运行库(C RunTime library)的缩写。此分配器简单地读用标准的 `malloc()`/`realloc()`/`free()`。当我们需要许多增减操作,这种分配器会更为适合。然而这种分配器远远比 `MemoryPoolAllocator` 低效。
66
+
67
+ # 解析 {#Parsing}
68
+
69
+ `Document` 提供几个解析函数。以下的 (1) 是根本的函数,其他都是调用 (1) 的协助函数。
70
+
71
+ ~~~~~~~~~~cpp
72
+ using namespace rapidjson;
73
+
74
+ // (1) 根本
75
+ template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
76
+ GenericDocument& GenericDocument::ParseStream(InputStream& is);
77
+
78
+ // (2) 使用流的编码
79
+ template <unsigned parseFlags, typename InputStream>
80
+ GenericDocument& GenericDocument::ParseStream(InputStream& is);
81
+
82
+ // (3) 使用缺省标志
83
+ template <typename InputStream>
84
+ GenericDocument& GenericDocument::ParseStream(InputStream& is);
85
+
86
+ // (4) 原位解析
87
+ template <unsigned parseFlags>
88
+ GenericDocument& GenericDocument::ParseInsitu(Ch* str);
89
+
90
+ // (5) 原位解析,使用缺省标志
91
+ GenericDocument& GenericDocument::ParseInsitu(Ch* str);
92
+
93
+ // (6) 正常解析一个字符串
94
+ template <unsigned parseFlags, typename SourceEncoding>
95
+ GenericDocument& GenericDocument::Parse(const Ch* str);
96
+
97
+ // (7) 正常解析一个字符串,使用 Document 的编码
98
+ template <unsigned parseFlags>
99
+ GenericDocument& GenericDocument::Parse(const Ch* str);
100
+
101
+ // (8) 正常解析一个字符串,使用缺省标志
102
+ GenericDocument& GenericDocument::Parse(const Ch* str);
103
+ ~~~~~~~~~~
104
+
105
+ [教程](doc/tutorial.zh-cn.md) 中的例使用 (8) 去正常解析字符串。而 [流](doc/stream.zh-cn.md) 的例子使用前 3 个函数。我们将稍后介绍原位(*In situ*) 解析。
106
+
107
+ `parseFlags` 是以下位标置的组合:
108
+
109
+ 解析位标志 | 意义
110
+ ------------------------------|-----------------------------------
111
+ `kParseNoFlags` | 没有任何标志。
112
+ `kParseDefaultFlags` | 缺省的解析选项。它等于 `RAPIDJSON_PARSE_DEFAULT_FLAGS` 宏,此宏定义为 `kParseNoFlags`。
113
+ `kParseInsituFlag` | 原位(破坏性)解析。
114
+ `kParseValidateEncodingFlag` | 校验 JSON 字符串的编码。
115
+ `kParseIterativeFlag` | 迭代式(调用堆栈大小为常数复杂度)解析。
116
+ `kParseStopWhenDoneFlag` | 当从流解析了一个完整的 JSON 根节点之后,停止继续处理余下的流。当使用了此标志,解析器便不会产生 `kParseErrorDocumentRootNotSingular` 错误。可使用本标志去解析同一个流里的多个 JSON。
117
+ `kParseFullPrecisionFlag` | 使用完整的精确度去解析数字(较慢)。如不设置此标节,则会使用正常的精确度(较快)。正常精确度会有最多 3 个 [ULP](http://en.wikipedia.org/wiki/Unit_in_the_last_place) 的误差。
118
+ `kParseCommentsFlag` | 容许单行 `// ...` 及多行 `/* ... */` 注释(放宽的 JSON 语法)。
119
+ `kParseNumbersAsStringsFlag` | 把数字类型解析成字符串。
120
+ `kParseTrailingCommasFlag` | 容许在对象和数组结束前含有逗号(放宽的 JSON 语法)。
121
+ `kParseNanAndInfFlag` | 容许 `NaN`、`Inf`、`Infinity`、`-Inf` 及 `-Infinity` 作为 `double` 值(放宽的 JSON 语法)。
122
+
123
+ 由于使用了非类型模板参数,而不是函数参数,C++ 编译器能为个别组合生成代码,以改善性能及减少代码尺寸(当只用单种特化)。缺点是需要在编译期决定标志。
124
+
125
+ `SourceEncoding` 参数定义流使用了什么编码。这与 `Document` 的 `Encoding` 不相同。细节可参考 [转码和校验](#TranscodingAndValidation) 一节。
126
+
127
+ 此外 `InputStream` 是输入流的类型。
128
+
129
+ ## 解析错误 {#ParseError}
130
+
131
+ 当解析过程顺利完成,`Document` 便会含有解析结果。当过程出现错误,原来的 DOM 会*维持不变*。可使用 `bool HasParseError()`、`ParseErrorCode GetParseError()` 及 `size_t GetErrorOffset()` 获取解析的错误状态。
132
+
133
+ 解析错误代号 | 描述
134
+ --------------------------------------------|---------------------------------------------------
135
+ `kParseErrorNone` | 无错误。
136
+ `kParseErrorDocumentEmpty` | 文档是空的。
137
+ `kParseErrorDocumentRootNotSingular` | 文档的根后面不能有其它值。
138
+ `kParseErrorValueInvalid` | 不合法的值。
139
+ `kParseErrorObjectMissName` | Object 成员缺少名字。
140
+ `kParseErrorObjectMissColon` | Object 成员名字后缺少冒号。
141
+ `kParseErrorObjectMissCommaOrCurlyBracket` | Object 成员后缺少逗号或 `}`。
142
+ `kParseErrorArrayMissCommaOrSquareBracket` | Array 元素后缺少逗号或 `]` 。
143
+ `kParseErrorStringUnicodeEscapeInvalidHex` | String 中的 `\\u` 转义符后含非十六进位数字。
144
+ `kParseErrorStringUnicodeSurrogateInvalid` | String 中的代理对(surrogate pair)不合法。
145
+ `kParseErrorStringEscapeInvalid` | String 含非法转义字符。
146
+ `kParseErrorStringMissQuotationMark` | String 缺少关闭引号。
147
+ `kParseErrorStringInvalidEncoding` | String 含非法编码。
148
+ `kParseErrorNumberTooBig` | Number 的值太大,不能存储于 `double`。
149
+ `kParseErrorNumberMissFraction` | Number 缺少了小数部分。
150
+ `kParseErrorNumberMissExponent` | Number 缺少了指数。
151
+
152
+ 错误的偏移量定义为从流开始至错误处的字符数量。目前 RapidJSON 不记录错误行号。
153
+
154
+ 要取得错误讯息,RapidJSON 在 `rapidjson/error/en.h` 中提供了英文错误讯息。使用者可以修改它用于其他语言环境,或使用一个自定义的本地化系统。
155
+
156
+ 以下是一个处理错误的例子。
157
+
158
+ ~~~~~~~~~~cpp
159
+ #include "rapidjson/document.h"
160
+ #include "rapidjson/error/en.h"
161
+
162
+ // ...
163
+ Document d;
164
+ if (d.Parse(json).HasParseError()) {
165
+ fprintf(stderr, "\nError(offset %u): %s\n",
166
+ (unsigned)d.GetErrorOffset(),
167
+ GetParseError_En(d.GetParseErrorCode()));
168
+ // ...
169
+ }
170
+ ~~~~~~~~~~
171
+
172
+ ## 原位解析 {#InSituParsing}
173
+
174
+ 根据 [维基百科](http://en.wikipedia.org/wiki/In_situ):
175
+
176
+ > *In situ* ... is a Latin phrase that translates literally to "on site" or "in position". It means "locally", "on site", "on the premises" or "in place" to describe an event where it takes place, and is used in many different contexts.
177
+ > ...
178
+ > (In computer science) An algorithm is said to be an in situ algorithm, or in-place algorithm, if the extra amount of memory required to execute the algorithm is O(1), that is, does not exceed a constant no matter how large the input. For example, heapsort is an in situ sorting algorithm.
179
+
180
+ > 翻译:*In situ*……是一个拉丁文片语,字面上的意思是指「现场」、「在位置」。在许多不同语境中,它描述一个事件发生的位置,意指「本地」、「现场」、「在处所」、「就位」。
181
+ > ……
182
+ > (在计算机科学中)一个算法若称为原位算法,或在位算法,是指执行该算法所需的额外内存空间是 O(1) 的,换句话说,无论输入大小都只需要常数空间。例如,堆排序是一个原位排序算法。
183
+
184
+ 在正常的解析过程中,对 JSON string 解码并复制至其他缓冲区是一个很大的开销。原位解析(*in situ* parsing)把这些 JSON string 直接解码于它原来存储的地方。由于解码后的 string 长度总是短于或等于原来储存于 JSON 的 string,所以这是可行的。在这个语境下,对 JSON string 进行解码是指处理转义符,如 `"\n"`、`"\u1234"` 等,以及在 string 末端加入空终止符号 (`'\0'`)。
185
+
186
+ 以下的图比较正常及原位解析。JSON string 值包含指向解码后的字符串。
187
+
188
+ ![正常解析](diagram/normalparsing.png)
189
+
190
+ 在正常解析中,解码后的字符串被复制至全新分配的缓冲区中。`"\\n"`(2 个字符)被解码成 `"\n"`(1 个字符)。`"\\u0073"`(6 个字符)被解码成 `"s"`(1 个字符)。
191
+
192
+ ![原位解析](diagram/insituparsing.png)
193
+
194
+ 原位解析直接修改了原来的 JSON。图中高亮了被更新的字符。若 JSON string 不含转义符,例如 `"msg"`,那么解析过程仅仅是以空字符代替结束双引号。
195
+
196
+ 由于原位解析修改了输入,其解析 API 需要 `char*` 而非 `const char*`。
197
+
198
+ ~~~~~~~~~~cpp
199
+ // 把整个文件读入 buffer
200
+ FILE* fp = fopen("test.json", "r");
201
+ fseek(fp, 0, SEEK_END);
202
+ size_t filesize = (size_t)ftell(fp);
203
+ fseek(fp, 0, SEEK_SET);
204
+ char* buffer = (char*)malloc(filesize + 1);
205
+ size_t readLength = fread(buffer, 1, filesize, fp);
206
+ buffer[readLength] = '\0';
207
+ fclose(fp);
208
+
209
+ // 原位解析 buffer 至 d,buffer 内容会被修改。
210
+ Document d;
211
+ d.ParseInsitu(buffer);
212
+
213
+ // 在此查询、修改 DOM……
214
+
215
+ free(buffer);
216
+ // 注意:在这个位置,d 可能含有指向已被释放的 buffer 的悬空指针
217
+ ~~~~~~~~~~
218
+
219
+ JSON string 会被打上 const-string 的标志。但它们可能并非真正的「常数」。它的生命周期取决于存储 JSON 的缓冲区。
220
+
221
+ 原位解析把分配开销及内存复制减至最小。通常这样做能改善缓存一致性,而这对现代计算机来说是一个重要的性能因素。
222
+
223
+ 原位解析有以下限制:
224
+
225
+ 1. 整个 JSON 须存储在内存之中。
226
+ 2. 流的来源缓码与文档的目标编码必须相同。
227
+ 3. 需要保留缓冲区,直至文档不再被使用。
228
+ 4. 若 DOM 需要在解析后被长期使用,而 DOM 内只有很少 JSON string,保留缓冲区可能造成内存浪费。
229
+
230
+ 原位解析最适合用于短期的、用完即弃的 JSON。实际应用中,这些场合是非常普遍的,例如反序列化 JSON 至 C++ 对象、处理以 JSON 表示的 web 请求等。
231
+
232
+ ## 转码与校验 {#TranscodingAndValidation}
233
+
234
+ RapidJSON 内部支持不同 Unicode 格式(正式的术语是 UCS 变换格式)间的转换。在 DOM 解析时,流的来源编码与 DOM 的编码可以不同。例如,来源流可能含有 UTF-8 的 JSON,而 DOM 则使用 UTF-16 编码。在 [EncodedInputStream](doc/stream.zh-cn.md) 一节里有一个例子。
235
+
236
+ 当从 DOM 输出一个 JSON 至输出流之时,也可以使用转码功能。在 [EncodedOutputStream](doc/stream.zh-cn.md) 一节里有一个例子。
237
+
238
+ 在转码过程中,会把来源 string 解码成 Unicode 码点,然后把码点编码成目标格式。在解码时,它会校验来源 string 的字节序列是否合法。若遇上非合法序列,解析器会停止并返回 `kParseErrorStringInvalidEncoding` 错误。
239
+
240
+ 当来源编码与 DOM 的编码相同,解析器缺省地 * 不会 * 校验序列。使用者可开启 `kParseValidateEncodingFlag` 去强制校验。
241
+
242
+ # 技巧 {#Techniques}
243
+
244
+ 这里讨论一些 DOM API 的使用技巧。
245
+
246
+ ## 把 DOM 作为 SAX 事件发表者
247
+
248
+ 在 RapidJSON 中,利用 `Writer` 把 DOM 生成 JSON 的做法,看来有点奇怪。
249
+
250
+ ~~~~~~~~~~cpp
251
+ // ...
252
+ Writer<StringBuffer> writer(buffer);
253
+ d.Accept(writer);
254
+ ~~~~~~~~~~
255
+
256
+ 实际上,`Value::Accept()` 是负责发布该值相关的 SAX 事件至处理器的。通过这个设计,`Value` 及 `Writer` 解除了偶合。`Value` 可生成 SAX 事件,而 `Writer` 则可以处理这些事件。
257
+
258
+ 使用者可以创建自定义的处理器,去把 DOM 转换成其它格式。例如,一个把 DOM 转换成 XML 的处理器。
259
+
260
+ 要知道更多关于 SAX 事件与处理器,可参阅 [SAX](doc/sax.zh-cn.md)。
261
+
262
+ ## 使用者缓冲区 {#UserBuffer}
263
+
264
+ 许多应用软件可能需要尽量减少内存分配。
265
+
266
+ `MemoryPoolAllocator` 可以帮助这方面,它容许使用者提供一个缓冲区。该缓冲区可能置于程序堆栈,或是一个静态分配的「草稿缓冲区(scratch buffer)」(一个静态/全局的数组),用于储存临时数据。
267
+
268
+ `MemoryPoolAllocator` 会先用使用者缓冲区去解决分配请求。当使用者缓冲区用完,就会从基础分配器(缺省为 `CrtAllocator`)分配一块内存。
269
+
270
+ 以下是使用堆栈内存的例子,第一个分配器用于存储值,第二个用于解析时的临时缓冲。
271
+
272
+ ~~~~~~~~~~cpp
273
+ typedef GenericDocument<UTF8<>, MemoryPoolAllocator<>, MemoryPoolAllocator<>> DocumentType;
274
+ char valueBuffer[4096];
275
+ char parseBuffer[1024];
276
+ MemoryPoolAllocator<> valueAllocator(valueBuffer, sizeof(valueBuffer));
277
+ MemoryPoolAllocator<> parseAllocator(parseBuffer, sizeof(parseBuffer));
278
+ DocumentType d(&valueAllocator, sizeof(parseBuffer), &parseAllocator);
279
+ d.Parse(json);
280
+ ~~~~~~~~~~
281
+
282
+ 若解析时分配总量少于 4096+1024 字节时,这段代码不会造成任何堆内存分配(经 `new` 或 `malloc()`)。
283
+
284
+ 使用者可以通过 `MemoryPoolAllocator::Size()` 查询当前已分的内存大小。那么使用者可以拟定使用者缓冲区的合适大小。