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,51 @@
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/rapidjson.h"
17
+
18
+ #ifdef __clang__
19
+ #pragma GCC diagnostic push
20
+ #if __has_warning("-Wdeprecated")
21
+ #pragma GCC diagnostic ignored "-Wdeprecated"
22
+ #endif
23
+ #endif
24
+
25
+ AssertException::~AssertException() throw() {}
26
+
27
+ #ifdef __clang__
28
+ #pragma GCC diagnostic pop
29
+ #endif
30
+
31
+ int main(int argc, char **argv) {
32
+ ::testing::InitGoogleTest(&argc, argv);
33
+
34
+ std::cout << "RapidJSON v" << RAPIDJSON_VERSION_STRING << std::endl;
35
+
36
+ #ifdef _MSC_VER
37
+ _CrtMemState memoryState = { 0 };
38
+ (void)memoryState;
39
+ _CrtMemCheckpoint(&memoryState);
40
+ //_CrtSetBreakAlloc(X);
41
+ //void *testWhetherMemoryLeakDetectionWorks = malloc(1);
42
+ #endif
43
+
44
+ int ret = RUN_ALL_TESTS();
45
+
46
+ #ifdef _MSC_VER
47
+ // Current gtest constantly leak 2 blocks at exit
48
+ _CrtMemDumpAllObjectsSince(&memoryState);
49
+ #endif
50
+ return ret;
51
+ }
@@ -0,0 +1,140 @@
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
+ #ifndef UNITTEST_H_
16
+ #define UNITTEST_H_
17
+
18
+ // gtest indirectly included inttypes.h, without __STDC_CONSTANT_MACROS.
19
+ #ifndef __STDC_CONSTANT_MACROS
20
+ #ifdef __clang__
21
+ #pragma GCC diagnostic push
22
+ #if __has_warning("-Wreserved-id-macro")
23
+ #pragma GCC diagnostic ignored "-Wreserved-id-macro"
24
+ #endif
25
+ #endif
26
+
27
+ # define __STDC_CONSTANT_MACROS 1 // required by C++ standard
28
+
29
+ #ifdef __clang__
30
+ #pragma GCC diagnostic pop
31
+ #endif
32
+ #endif
33
+
34
+ #ifdef _MSC_VER
35
+ #define _CRTDBG_MAP_ALLOC
36
+ #include <crtdbg.h>
37
+ #pragma warning(disable : 4996) // 'function': was declared deprecated
38
+ #endif
39
+
40
+ #if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
41
+ #if defined(__clang__) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
42
+ #pragma GCC diagnostic push
43
+ #endif
44
+ #pragma GCC diagnostic ignored "-Weffc++"
45
+ #endif
46
+
47
+ #include "gtest/gtest.h"
48
+ #include <stdexcept>
49
+
50
+ #if defined(__clang__) || defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
51
+ #pragma GCC diagnostic pop
52
+ #endif
53
+
54
+ #ifdef __clang__
55
+ // All TEST() macro generated this warning, disable globally
56
+ #pragma GCC diagnostic ignored "-Wglobal-constructors"
57
+ #endif
58
+
59
+ template <typename Ch>
60
+ inline unsigned StrLen(const Ch* s) {
61
+ const Ch* p = s;
62
+ while (*p) p++;
63
+ return unsigned(p - s);
64
+ }
65
+
66
+ template<typename Ch>
67
+ inline int StrCmp(const Ch* s1, const Ch* s2) {
68
+ while(*s1 && (*s1 == *s2)) { s1++; s2++; }
69
+ return static_cast<unsigned>(*s1) < static_cast<unsigned>(*s2) ? -1 : static_cast<unsigned>(*s1) > static_cast<unsigned>(*s2);
70
+ }
71
+
72
+ template <typename Ch>
73
+ inline Ch* StrDup(const Ch* str) {
74
+ size_t bufferSize = sizeof(Ch) * (StrLen(str) + 1);
75
+ Ch* buffer = static_cast<Ch*>(malloc(bufferSize));
76
+ memcpy(buffer, str, bufferSize);
77
+ return buffer;
78
+ }
79
+
80
+ inline FILE* TempFile(char *filename) {
81
+ #if defined(__WIN32__) || defined(_MSC_VER)
82
+ filename = tmpnam(filename);
83
+
84
+ // For Visual Studio, tmpnam() adds a backslash in front. Remove it.
85
+ if (filename[0] == '\\')
86
+ for (int i = 0; filename[i] != '\0'; i++)
87
+ filename[i] = filename[i + 1];
88
+
89
+ return fopen(filename, "wb");
90
+ #else
91
+ strcpy(filename, "/tmp/fileXXXXXX");
92
+ int fd = mkstemp(filename);
93
+ return fdopen(fd, "w");
94
+ #endif
95
+ }
96
+
97
+ // Use exception for catching assert
98
+ #ifdef _MSC_VER
99
+ #pragma warning(disable : 4127)
100
+ #endif
101
+
102
+ #ifdef __clang__
103
+ #pragma GCC diagnostic push
104
+ #if __has_warning("-Wdeprecated")
105
+ #pragma GCC diagnostic ignored "-Wdeprecated"
106
+ #endif
107
+ #endif
108
+
109
+ class AssertException : public std::logic_error {
110
+ public:
111
+ AssertException(const char* w) : std::logic_error(w) {}
112
+ AssertException(const AssertException& rhs) : std::logic_error(rhs) {}
113
+ virtual ~AssertException() throw();
114
+ };
115
+
116
+ #ifdef __clang__
117
+ #pragma GCC diagnostic pop
118
+ #endif
119
+
120
+ // Not using noexcept for testing RAPIDJSON_ASSERT()
121
+ #define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
122
+
123
+ #ifndef RAPIDJSON_ASSERT
124
+ #define RAPIDJSON_ASSERT(x) (!(x) ? throw AssertException(RAPIDJSON_STRINGIFY(x)) : (void)0u)
125
+ #endif
126
+
127
+ class Random {
128
+ public:
129
+ Random(unsigned seed = 0) : mSeed(seed) {}
130
+
131
+ unsigned operator()() {
132
+ mSeed = 214013 * mSeed + 2531011;
133
+ return mSeed;
134
+ }
135
+
136
+ private:
137
+ unsigned mSeed;
138
+ };
139
+
140
+ #endif // UNITTEST_H_
@@ -0,0 +1,1829 @@
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/document.h"
17
+ #include <algorithm>
18
+
19
+ #ifdef __clang__
20
+ RAPIDJSON_DIAG_PUSH
21
+ RAPIDJSON_DIAG_OFF(c++98-compat)
22
+ #endif
23
+
24
+ using namespace rapidjson;
25
+
26
+ TEST(Value, Size) {
27
+ if (sizeof(SizeType) == 4) {
28
+ #if RAPIDJSON_48BITPOINTER_OPTIMIZATION
29
+ EXPECT_EQ(16, sizeof(Value));
30
+ #elif RAPIDJSON_64BIT
31
+ EXPECT_EQ(24, sizeof(Value));
32
+ #else
33
+ EXPECT_EQ(16, sizeof(Value));
34
+ #endif
35
+ }
36
+ }
37
+
38
+ TEST(Value, DefaultConstructor) {
39
+ Value x;
40
+ EXPECT_EQ(kNullType, x.GetType());
41
+ EXPECT_TRUE(x.IsNull());
42
+
43
+ //std::cout << "sizeof(Value): " << sizeof(x) << std::endl;
44
+ }
45
+
46
+ // Should not pass compilation
47
+ //TEST(Value, copy_constructor) {
48
+ // Value x(1234);
49
+ // Value y = x;
50
+ //}
51
+
52
+ #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
53
+
54
+ #if 0 // Many old compiler does not support these. Turn it off temporaily.
55
+
56
+ #include <type_traits>
57
+
58
+ TEST(Value, Traits) {
59
+ typedef GenericValue<UTF8<>, CrtAllocator> Value;
60
+ static_assert(std::is_constructible<Value>::value, "");
61
+ static_assert(std::is_default_constructible<Value>::value, "");
62
+ #ifndef _MSC_VER
63
+ static_assert(!std::is_copy_constructible<Value>::value, "");
64
+ #endif
65
+ static_assert(std::is_move_constructible<Value>::value, "");
66
+
67
+ #ifndef _MSC_VER
68
+ static_assert(std::is_nothrow_constructible<Value>::value, "");
69
+ static_assert(std::is_nothrow_default_constructible<Value>::value, "");
70
+ static_assert(!std::is_nothrow_copy_constructible<Value>::value, "");
71
+ static_assert(std::is_nothrow_move_constructible<Value>::value, "");
72
+ #endif
73
+
74
+ static_assert(std::is_assignable<Value,Value>::value, "");
75
+ #ifndef _MSC_VER
76
+ static_assert(!std::is_copy_assignable<Value>::value, "");
77
+ #endif
78
+ static_assert(std::is_move_assignable<Value>::value, "");
79
+
80
+ #ifndef _MSC_VER
81
+ static_assert(std::is_nothrow_assignable<Value, Value>::value, "");
82
+ #endif
83
+ static_assert(!std::is_nothrow_copy_assignable<Value>::value, "");
84
+ #ifndef _MSC_VER
85
+ static_assert(std::is_nothrow_move_assignable<Value>::value, "");
86
+ #endif
87
+
88
+ static_assert(std::is_destructible<Value>::value, "");
89
+ #ifndef _MSC_VER
90
+ static_assert(std::is_nothrow_destructible<Value>::value, "");
91
+ #endif
92
+ }
93
+
94
+ #endif
95
+
96
+ TEST(Value, MoveConstructor) {
97
+ typedef GenericValue<UTF8<>, CrtAllocator> V;
98
+ V::AllocatorType allocator;
99
+
100
+ V x((V(kArrayType)));
101
+ x.Reserve(4u, allocator);
102
+ x.PushBack(1, allocator).PushBack(2, allocator).PushBack(3, allocator).PushBack(4, allocator);
103
+ EXPECT_TRUE(x.IsArray());
104
+ EXPECT_EQ(4u, x.Size());
105
+
106
+ // Value y(x); // does not compile (!is_copy_constructible)
107
+ V y(std::move(x));
108
+ EXPECT_TRUE(x.IsNull());
109
+ EXPECT_TRUE(y.IsArray());
110
+ EXPECT_EQ(4u, y.Size());
111
+
112
+ // Value z = y; // does not compile (!is_copy_assignable)
113
+ V z = std::move(y);
114
+ EXPECT_TRUE(y.IsNull());
115
+ EXPECT_TRUE(z.IsArray());
116
+ EXPECT_EQ(4u, z.Size());
117
+ }
118
+
119
+ #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
120
+
121
+ TEST(Value, AssignmentOperator) {
122
+ Value x(1234);
123
+ Value y;
124
+ y = x;
125
+ EXPECT_TRUE(x.IsNull()); // move semantic
126
+ EXPECT_EQ(1234, y.GetInt());
127
+
128
+ y = 5678;
129
+ EXPECT_TRUE(y.IsInt());
130
+ EXPECT_EQ(5678, y.GetInt());
131
+
132
+ x = "Hello";
133
+ EXPECT_TRUE(x.IsString());
134
+ EXPECT_STREQ(x.GetString(),"Hello");
135
+
136
+ y = StringRef(x.GetString(),x.GetStringLength());
137
+ EXPECT_TRUE(y.IsString());
138
+ EXPECT_EQ(y.GetString(),x.GetString());
139
+ EXPECT_EQ(y.GetStringLength(),x.GetStringLength());
140
+
141
+ static char mstr[] = "mutable";
142
+ // y = mstr; // should not compile
143
+ y = StringRef(mstr);
144
+ EXPECT_TRUE(y.IsString());
145
+ EXPECT_EQ(y.GetString(),mstr);
146
+
147
+ #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
148
+ // C++11 move assignment
149
+ x = Value("World");
150
+ EXPECT_TRUE(x.IsString());
151
+ EXPECT_STREQ("World", x.GetString());
152
+
153
+ x = std::move(y);
154
+ EXPECT_TRUE(y.IsNull());
155
+ EXPECT_TRUE(x.IsString());
156
+ EXPECT_EQ(x.GetString(), mstr);
157
+
158
+ y = std::move(Value().SetInt(1234));
159
+ EXPECT_TRUE(y.IsInt());
160
+ EXPECT_EQ(1234, y);
161
+ #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
162
+ }
163
+
164
+ template <typename A, typename B>
165
+ void TestEqual(const A& a, const B& b) {
166
+ EXPECT_TRUE (a == b);
167
+ EXPECT_FALSE(a != b);
168
+ EXPECT_TRUE (b == a);
169
+ EXPECT_FALSE(b != a);
170
+ }
171
+
172
+ template <typename A, typename B>
173
+ void TestUnequal(const A& a, const B& b) {
174
+ EXPECT_FALSE(a == b);
175
+ EXPECT_TRUE (a != b);
176
+ EXPECT_FALSE(b == a);
177
+ EXPECT_TRUE (b != a);
178
+ }
179
+
180
+ TEST(Value, EqualtoOperator) {
181
+ Value::AllocatorType allocator;
182
+ Value x(kObjectType);
183
+ x.AddMember("hello", "world", allocator)
184
+ .AddMember("t", Value(true).Move(), allocator)
185
+ .AddMember("f", Value(false).Move(), allocator)
186
+ .AddMember("n", Value(kNullType).Move(), allocator)
187
+ .AddMember("i", 123, allocator)
188
+ .AddMember("pi", 3.14, allocator)
189
+ .AddMember("a", Value(kArrayType).Move().PushBack(1, allocator).PushBack(2, allocator).PushBack(3, allocator), allocator);
190
+
191
+ // Test templated operator==() and operator!=()
192
+ TestEqual(x["hello"], "world");
193
+ const char* cc = "world";
194
+ TestEqual(x["hello"], cc);
195
+ char* c = strdup("world");
196
+ TestEqual(x["hello"], c);
197
+ free(c);
198
+
199
+ TestEqual(x["t"], true);
200
+ TestEqual(x["f"], false);
201
+ TestEqual(x["i"], 123);
202
+ TestEqual(x["pi"], 3.14);
203
+
204
+ // Test operator==() (including different allocators)
205
+ CrtAllocator crtAllocator;
206
+ GenericValue<UTF8<>, CrtAllocator> y;
207
+ GenericDocument<UTF8<>, CrtAllocator> z(&crtAllocator);
208
+ y.CopyFrom(x, crtAllocator);
209
+ z.CopyFrom(y, z.GetAllocator());
210
+ TestEqual(x, y);
211
+ TestEqual(y, z);
212
+ TestEqual(z, x);
213
+
214
+ // Swapping member order should be fine.
215
+ EXPECT_TRUE(y.RemoveMember("t"));
216
+ TestUnequal(x, y);
217
+ TestUnequal(z, y);
218
+ EXPECT_TRUE(z.RemoveMember("t"));
219
+ TestUnequal(x, z);
220
+ TestEqual(y, z);
221
+ y.AddMember("t", false, crtAllocator);
222
+ z.AddMember("t", false, z.GetAllocator());
223
+ TestUnequal(x, y);
224
+ TestUnequal(z, x);
225
+ y["t"] = true;
226
+ z["t"] = true;
227
+ TestEqual(x, y);
228
+ TestEqual(y, z);
229
+ TestEqual(z, x);
230
+
231
+ // Swapping element order is not OK
232
+ x["a"][0].Swap(x["a"][1]);
233
+ TestUnequal(x, y);
234
+ x["a"][0].Swap(x["a"][1]);
235
+ TestEqual(x, y);
236
+
237
+ // Array of different size
238
+ x["a"].PushBack(4, allocator);
239
+ TestUnequal(x, y);
240
+ x["a"].PopBack();
241
+ TestEqual(x, y);
242
+
243
+ // Issue #129: compare Uint64
244
+ x.SetUint64(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFF0));
245
+ y.SetUint64(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF));
246
+ TestUnequal(x, y);
247
+ }
248
+
249
+ template <typename Value>
250
+ void TestCopyFrom() {
251
+ typename Value::AllocatorType a;
252
+ Value v1(1234);
253
+ Value v2(v1, a); // deep copy constructor
254
+ EXPECT_TRUE(v1.GetType() == v2.GetType());
255
+ EXPECT_EQ(v1.GetInt(), v2.GetInt());
256
+
257
+ v1.SetString("foo");
258
+ v2.CopyFrom(v1, a);
259
+ EXPECT_TRUE(v1.GetType() == v2.GetType());
260
+ EXPECT_STREQ(v1.GetString(), v2.GetString());
261
+ EXPECT_EQ(v1.GetString(), v2.GetString()); // string NOT copied
262
+
263
+ v1.SetString("bar", a); // copy string
264
+ v2.CopyFrom(v1, a);
265
+ EXPECT_TRUE(v1.GetType() == v2.GetType());
266
+ EXPECT_STREQ(v1.GetString(), v2.GetString());
267
+ EXPECT_NE(v1.GetString(), v2.GetString()); // string copied
268
+
269
+
270
+ v1.SetArray().PushBack(1234, a);
271
+ v2.CopyFrom(v1, a);
272
+ EXPECT_TRUE(v2.IsArray());
273
+ EXPECT_EQ(v1.Size(), v2.Size());
274
+
275
+ v1.PushBack(Value().SetString("foo", a), a); // push string copy
276
+ EXPECT_TRUE(v1.Size() != v2.Size());
277
+ v2.CopyFrom(v1, a);
278
+ EXPECT_TRUE(v1.Size() == v2.Size());
279
+ EXPECT_STREQ(v1[1].GetString(), v2[1].GetString());
280
+ EXPECT_NE(v1[1].GetString(), v2[1].GetString()); // string got copied
281
+ }
282
+
283
+ TEST(Value, CopyFrom) {
284
+ TestCopyFrom<Value>();
285
+ TestCopyFrom<GenericValue<UTF8<>, CrtAllocator> >();
286
+ }
287
+
288
+ TEST(Value, Swap) {
289
+ Value v1(1234);
290
+ Value v2(kObjectType);
291
+
292
+ EXPECT_EQ(&v1, &v1.Swap(v2));
293
+ EXPECT_TRUE(v1.IsObject());
294
+ EXPECT_TRUE(v2.IsInt());
295
+ EXPECT_EQ(1234, v2.GetInt());
296
+
297
+ // testing std::swap compatibility
298
+ using std::swap;
299
+ swap(v1, v2);
300
+ EXPECT_TRUE(v1.IsInt());
301
+ EXPECT_TRUE(v2.IsObject());
302
+ }
303
+
304
+ TEST(Value, Null) {
305
+ // Default constructor
306
+ Value x;
307
+ EXPECT_EQ(kNullType, x.GetType());
308
+ EXPECT_TRUE(x.IsNull());
309
+
310
+ EXPECT_FALSE(x.IsTrue());
311
+ EXPECT_FALSE(x.IsFalse());
312
+ EXPECT_FALSE(x.IsNumber());
313
+ EXPECT_FALSE(x.IsString());
314
+ EXPECT_FALSE(x.IsObject());
315
+ EXPECT_FALSE(x.IsArray());
316
+
317
+ // Constructor with type
318
+ Value y(kNullType);
319
+ EXPECT_TRUE(y.IsNull());
320
+
321
+ // SetNull();
322
+ Value z(true);
323
+ z.SetNull();
324
+ EXPECT_TRUE(z.IsNull());
325
+ }
326
+
327
+ TEST(Value, True) {
328
+ // Constructor with bool
329
+ Value x(true);
330
+ EXPECT_EQ(kTrueType, x.GetType());
331
+ EXPECT_TRUE(x.GetBool());
332
+ EXPECT_TRUE(x.IsBool());
333
+ EXPECT_TRUE(x.IsTrue());
334
+
335
+ EXPECT_FALSE(x.IsNull());
336
+ EXPECT_FALSE(x.IsFalse());
337
+ EXPECT_FALSE(x.IsNumber());
338
+ EXPECT_FALSE(x.IsString());
339
+ EXPECT_FALSE(x.IsObject());
340
+ EXPECT_FALSE(x.IsArray());
341
+
342
+ // Constructor with type
343
+ Value y(kTrueType);
344
+ EXPECT_TRUE(y.IsTrue());
345
+
346
+ // SetBool()
347
+ Value z;
348
+ z.SetBool(true);
349
+ EXPECT_TRUE(z.IsTrue());
350
+
351
+ // Templated functions
352
+ EXPECT_TRUE(z.Is<bool>());
353
+ EXPECT_TRUE(z.Get<bool>());
354
+ EXPECT_FALSE(z.Set<bool>(false).Get<bool>());
355
+ EXPECT_TRUE(z.Set(true).Get<bool>());
356
+ }
357
+
358
+ TEST(Value, False) {
359
+ // Constructor with bool
360
+ Value x(false);
361
+ EXPECT_EQ(kFalseType, x.GetType());
362
+ EXPECT_TRUE(x.IsBool());
363
+ EXPECT_TRUE(x.IsFalse());
364
+
365
+ EXPECT_FALSE(x.IsNull());
366
+ EXPECT_FALSE(x.IsTrue());
367
+ EXPECT_FALSE(x.GetBool());
368
+ //EXPECT_FALSE((bool)x);
369
+ EXPECT_FALSE(x.IsNumber());
370
+ EXPECT_FALSE(x.IsString());
371
+ EXPECT_FALSE(x.IsObject());
372
+ EXPECT_FALSE(x.IsArray());
373
+
374
+ // Constructor with type
375
+ Value y(kFalseType);
376
+ EXPECT_TRUE(y.IsFalse());
377
+
378
+ // SetBool()
379
+ Value z;
380
+ z.SetBool(false);
381
+ EXPECT_TRUE(z.IsFalse());
382
+ }
383
+
384
+ TEST(Value, Int) {
385
+ // Constructor with int
386
+ Value x(1234);
387
+ EXPECT_EQ(kNumberType, x.GetType());
388
+ EXPECT_EQ(1234, x.GetInt());
389
+ EXPECT_EQ(1234u, x.GetUint());
390
+ EXPECT_EQ(1234, x.GetInt64());
391
+ EXPECT_EQ(1234u, x.GetUint64());
392
+ EXPECT_NEAR(1234.0, x.GetDouble(), 0.0);
393
+ //EXPECT_EQ(1234, (int)x);
394
+ //EXPECT_EQ(1234, (unsigned)x);
395
+ //EXPECT_EQ(1234, (int64_t)x);
396
+ //EXPECT_EQ(1234, (uint64_t)x);
397
+ //EXPECT_EQ(1234, (double)x);
398
+ EXPECT_TRUE(x.IsNumber());
399
+ EXPECT_TRUE(x.IsInt());
400
+ EXPECT_TRUE(x.IsUint());
401
+ EXPECT_TRUE(x.IsInt64());
402
+ EXPECT_TRUE(x.IsUint64());
403
+
404
+ EXPECT_FALSE(x.IsDouble());
405
+ EXPECT_FALSE(x.IsFloat());
406
+ EXPECT_FALSE(x.IsNull());
407
+ EXPECT_FALSE(x.IsBool());
408
+ EXPECT_FALSE(x.IsFalse());
409
+ EXPECT_FALSE(x.IsTrue());
410
+ EXPECT_FALSE(x.IsString());
411
+ EXPECT_FALSE(x.IsObject());
412
+ EXPECT_FALSE(x.IsArray());
413
+
414
+ Value nx(-1234);
415
+ EXPECT_EQ(-1234, nx.GetInt());
416
+ EXPECT_EQ(-1234, nx.GetInt64());
417
+ EXPECT_TRUE(nx.IsInt());
418
+ EXPECT_TRUE(nx.IsInt64());
419
+ EXPECT_FALSE(nx.IsUint());
420
+ EXPECT_FALSE(nx.IsUint64());
421
+
422
+ // Constructor with type
423
+ Value y(kNumberType);
424
+ EXPECT_TRUE(y.IsNumber());
425
+ EXPECT_TRUE(y.IsInt());
426
+ EXPECT_EQ(0, y.GetInt());
427
+
428
+ // SetInt()
429
+ Value z;
430
+ z.SetInt(1234);
431
+ EXPECT_EQ(1234, z.GetInt());
432
+
433
+ // operator=(int)
434
+ z = 5678;
435
+ EXPECT_EQ(5678, z.GetInt());
436
+
437
+ // Templated functions
438
+ EXPECT_TRUE(z.Is<int>());
439
+ EXPECT_EQ(5678, z.Get<int>());
440
+ EXPECT_EQ(5679, z.Set(5679).Get<int>());
441
+ EXPECT_EQ(5680, z.Set<int>(5680).Get<int>());
442
+ }
443
+
444
+ TEST(Value, Uint) {
445
+ // Constructor with int
446
+ Value x(1234u);
447
+ EXPECT_EQ(kNumberType, x.GetType());
448
+ EXPECT_EQ(1234, x.GetInt());
449
+ EXPECT_EQ(1234u, x.GetUint());
450
+ EXPECT_EQ(1234, x.GetInt64());
451
+ EXPECT_EQ(1234u, x.GetUint64());
452
+ EXPECT_TRUE(x.IsNumber());
453
+ EXPECT_TRUE(x.IsInt());
454
+ EXPECT_TRUE(x.IsUint());
455
+ EXPECT_TRUE(x.IsInt64());
456
+ EXPECT_TRUE(x.IsUint64());
457
+ EXPECT_NEAR(1234.0, x.GetDouble(), 0.0); // Number can always be cast as double but !IsDouble().
458
+
459
+ EXPECT_FALSE(x.IsDouble());
460
+ EXPECT_FALSE(x.IsFloat());
461
+ EXPECT_FALSE(x.IsNull());
462
+ EXPECT_FALSE(x.IsBool());
463
+ EXPECT_FALSE(x.IsFalse());
464
+ EXPECT_FALSE(x.IsTrue());
465
+ EXPECT_FALSE(x.IsString());
466
+ EXPECT_FALSE(x.IsObject());
467
+ EXPECT_FALSE(x.IsArray());
468
+
469
+ // SetUint()
470
+ Value z;
471
+ z.SetUint(1234);
472
+ EXPECT_EQ(1234u, z.GetUint());
473
+
474
+ // operator=(unsigned)
475
+ z = 5678u;
476
+ EXPECT_EQ(5678u, z.GetUint());
477
+
478
+ z = 2147483648u; // 2^31, cannot cast as int
479
+ EXPECT_EQ(2147483648u, z.GetUint());
480
+ EXPECT_FALSE(z.IsInt());
481
+ EXPECT_TRUE(z.IsInt64()); // Issue 41: Incorrect parsing of unsigned int number types
482
+
483
+ // Templated functions
484
+ EXPECT_TRUE(z.Is<unsigned>());
485
+ EXPECT_EQ(2147483648u, z.Get<unsigned>());
486
+ EXPECT_EQ(2147483649u, z.Set(2147483649u).Get<unsigned>());
487
+ EXPECT_EQ(2147483650u, z.Set<unsigned>(2147483650u).Get<unsigned>());
488
+ }
489
+
490
+ TEST(Value, Int64) {
491
+ // Constructor with int
492
+ Value x(int64_t(1234));
493
+ EXPECT_EQ(kNumberType, x.GetType());
494
+ EXPECT_EQ(1234, x.GetInt());
495
+ EXPECT_EQ(1234u, x.GetUint());
496
+ EXPECT_EQ(1234, x.GetInt64());
497
+ EXPECT_EQ(1234u, x.GetUint64());
498
+ EXPECT_TRUE(x.IsNumber());
499
+ EXPECT_TRUE(x.IsInt());
500
+ EXPECT_TRUE(x.IsUint());
501
+ EXPECT_TRUE(x.IsInt64());
502
+ EXPECT_TRUE(x.IsUint64());
503
+
504
+ EXPECT_FALSE(x.IsDouble());
505
+ EXPECT_FALSE(x.IsFloat());
506
+ EXPECT_FALSE(x.IsNull());
507
+ EXPECT_FALSE(x.IsBool());
508
+ EXPECT_FALSE(x.IsFalse());
509
+ EXPECT_FALSE(x.IsTrue());
510
+ EXPECT_FALSE(x.IsString());
511
+ EXPECT_FALSE(x.IsObject());
512
+ EXPECT_FALSE(x.IsArray());
513
+
514
+ Value nx(int64_t(-1234));
515
+ EXPECT_EQ(-1234, nx.GetInt());
516
+ EXPECT_EQ(-1234, nx.GetInt64());
517
+ EXPECT_TRUE(nx.IsInt());
518
+ EXPECT_TRUE(nx.IsInt64());
519
+ EXPECT_FALSE(nx.IsUint());
520
+ EXPECT_FALSE(nx.IsUint64());
521
+
522
+ // SetInt64()
523
+ Value z;
524
+ z.SetInt64(1234);
525
+ EXPECT_EQ(1234, z.GetInt64());
526
+
527
+ z.SetInt64(2147483648u); // 2^31, cannot cast as int
528
+ EXPECT_FALSE(z.IsInt());
529
+ EXPECT_TRUE(z.IsUint());
530
+ EXPECT_NEAR(2147483648.0, z.GetDouble(), 0.0);
531
+
532
+ z.SetInt64(int64_t(4294967295u) + 1); // 2^32, cannot cast as uint
533
+ EXPECT_FALSE(z.IsInt());
534
+ EXPECT_FALSE(z.IsUint());
535
+ EXPECT_NEAR(4294967296.0, z.GetDouble(), 0.0);
536
+
537
+ z.SetInt64(-int64_t(2147483648u) - 1); // -2^31-1, cannot cast as int
538
+ EXPECT_FALSE(z.IsInt());
539
+ EXPECT_NEAR(-2147483649.0, z.GetDouble(), 0.0);
540
+
541
+ int64_t i = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 00000000));
542
+ z.SetInt64(i);
543
+ EXPECT_DOUBLE_EQ(-9223372036854775808.0, z.GetDouble());
544
+
545
+ // Templated functions
546
+ EXPECT_TRUE(z.Is<int64_t>());
547
+ EXPECT_EQ(i, z.Get<int64_t>());
548
+ #if 0 // signed integer underflow is undefined behaviour
549
+ EXPECT_EQ(i - 1, z.Set(i - 1).Get<int64_t>());
550
+ EXPECT_EQ(i - 2, z.Set<int64_t>(i - 2).Get<int64_t>());
551
+ #endif
552
+ }
553
+
554
+ TEST(Value, Uint64) {
555
+ // Constructor with int
556
+ Value x(uint64_t(1234));
557
+ EXPECT_EQ(kNumberType, x.GetType());
558
+ EXPECT_EQ(1234, x.GetInt());
559
+ EXPECT_EQ(1234u, x.GetUint());
560
+ EXPECT_EQ(1234, x.GetInt64());
561
+ EXPECT_EQ(1234u, x.GetUint64());
562
+ EXPECT_TRUE(x.IsNumber());
563
+ EXPECT_TRUE(x.IsInt());
564
+ EXPECT_TRUE(x.IsUint());
565
+ EXPECT_TRUE(x.IsInt64());
566
+ EXPECT_TRUE(x.IsUint64());
567
+
568
+ EXPECT_FALSE(x.IsDouble());
569
+ EXPECT_FALSE(x.IsFloat());
570
+ EXPECT_FALSE(x.IsNull());
571
+ EXPECT_FALSE(x.IsBool());
572
+ EXPECT_FALSE(x.IsFalse());
573
+ EXPECT_FALSE(x.IsTrue());
574
+ EXPECT_FALSE(x.IsString());
575
+ EXPECT_FALSE(x.IsObject());
576
+ EXPECT_FALSE(x.IsArray());
577
+
578
+ // SetUint64()
579
+ Value z;
580
+ z.SetUint64(1234);
581
+ EXPECT_EQ(1234u, z.GetUint64());
582
+
583
+ z.SetUint64(uint64_t(2147483648u)); // 2^31, cannot cast as int
584
+ EXPECT_FALSE(z.IsInt());
585
+ EXPECT_TRUE(z.IsUint());
586
+ EXPECT_TRUE(z.IsInt64());
587
+
588
+ z.SetUint64(uint64_t(4294967295u) + 1); // 2^32, cannot cast as uint
589
+ EXPECT_FALSE(z.IsInt());
590
+ EXPECT_FALSE(z.IsUint());
591
+ EXPECT_TRUE(z.IsInt64());
592
+
593
+ uint64_t u = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);
594
+ z.SetUint64(u); // 2^63 cannot cast as int64
595
+ EXPECT_FALSE(z.IsInt64());
596
+ EXPECT_EQ(u, z.GetUint64()); // Issue 48
597
+ EXPECT_DOUBLE_EQ(9223372036854775808.0, z.GetDouble());
598
+
599
+ // Templated functions
600
+ EXPECT_TRUE(z.Is<uint64_t>());
601
+ EXPECT_EQ(u, z.Get<uint64_t>());
602
+ EXPECT_EQ(u + 1, z.Set(u + 1).Get<uint64_t>());
603
+ EXPECT_EQ(u + 2, z.Set<uint64_t>(u + 2).Get<uint64_t>());
604
+ }
605
+
606
+ TEST(Value, Double) {
607
+ // Constructor with double
608
+ Value x(12.34);
609
+ EXPECT_EQ(kNumberType, x.GetType());
610
+ EXPECT_NEAR(12.34, x.GetDouble(), 0.0);
611
+ EXPECT_TRUE(x.IsNumber());
612
+ EXPECT_TRUE(x.IsDouble());
613
+
614
+ EXPECT_FALSE(x.IsInt());
615
+ EXPECT_FALSE(x.IsNull());
616
+ EXPECT_FALSE(x.IsBool());
617
+ EXPECT_FALSE(x.IsFalse());
618
+ EXPECT_FALSE(x.IsTrue());
619
+ EXPECT_FALSE(x.IsString());
620
+ EXPECT_FALSE(x.IsObject());
621
+ EXPECT_FALSE(x.IsArray());
622
+
623
+ // SetDouble()
624
+ Value z;
625
+ z.SetDouble(12.34);
626
+ EXPECT_NEAR(12.34, z.GetDouble(), 0.0);
627
+
628
+ z = 56.78;
629
+ EXPECT_NEAR(56.78, z.GetDouble(), 0.0);
630
+
631
+ // Templated functions
632
+ EXPECT_TRUE(z.Is<double>());
633
+ EXPECT_EQ(56.78, z.Get<double>());
634
+ EXPECT_EQ(57.78, z.Set(57.78).Get<double>());
635
+ EXPECT_EQ(58.78, z.Set<double>(58.78).Get<double>());
636
+ }
637
+
638
+ TEST(Value, Float) {
639
+ // Constructor with double
640
+ Value x(12.34f);
641
+ EXPECT_EQ(kNumberType, x.GetType());
642
+ EXPECT_NEAR(12.34f, x.GetFloat(), 0.0);
643
+ EXPECT_TRUE(x.IsNumber());
644
+ EXPECT_TRUE(x.IsDouble());
645
+ EXPECT_TRUE(x.IsFloat());
646
+
647
+ EXPECT_FALSE(x.IsInt());
648
+ EXPECT_FALSE(x.IsNull());
649
+ EXPECT_FALSE(x.IsBool());
650
+ EXPECT_FALSE(x.IsFalse());
651
+ EXPECT_FALSE(x.IsTrue());
652
+ EXPECT_FALSE(x.IsString());
653
+ EXPECT_FALSE(x.IsObject());
654
+ EXPECT_FALSE(x.IsArray());
655
+
656
+ // SetFloat()
657
+ Value z;
658
+ z.SetFloat(12.34f);
659
+ EXPECT_NEAR(12.34f, z.GetFloat(), 0.0f);
660
+
661
+ // Issue 573
662
+ z.SetInt(0);
663
+ EXPECT_EQ(0.0f, z.GetFloat());
664
+
665
+ z = 56.78f;
666
+ EXPECT_NEAR(56.78f, z.GetFloat(), 0.0f);
667
+
668
+ // Templated functions
669
+ EXPECT_TRUE(z.Is<float>());
670
+ EXPECT_EQ(56.78f, z.Get<float>());
671
+ EXPECT_EQ(57.78f, z.Set(57.78f).Get<float>());
672
+ EXPECT_EQ(58.78f, z.Set<float>(58.78f).Get<float>());
673
+ }
674
+
675
+ TEST(Value, IsLosslessDouble) {
676
+ EXPECT_TRUE(Value(0.0).IsLosslessDouble());
677
+ EXPECT_TRUE(Value(12.34).IsLosslessDouble());
678
+ EXPECT_TRUE(Value(-123).IsLosslessDouble());
679
+ EXPECT_TRUE(Value(2147483648u).IsLosslessDouble());
680
+ EXPECT_TRUE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x40000000, 0x00000000))).IsLosslessDouble());
681
+ #if !(defined(_MSC_VER) && _MSC_VER < 1800) // VC2010 has problem
682
+ EXPECT_TRUE(Value(RAPIDJSON_UINT64_C2(0xA0000000, 0x00000000)).IsLosslessDouble());
683
+ #endif
684
+
685
+ EXPECT_FALSE(Value(static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF))).IsLosslessDouble()); // INT64_MAX
686
+ EXPECT_FALSE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF))).IsLosslessDouble()); // -INT64_MAX
687
+ EXPECT_TRUE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF)) - 1).IsLosslessDouble()); // INT64_MIN
688
+ EXPECT_FALSE(Value(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF)).IsLosslessDouble()); // UINT64_MAX
689
+
690
+ EXPECT_TRUE(Value(3.4028234e38f).IsLosslessDouble()); // FLT_MAX
691
+ EXPECT_TRUE(Value(-3.4028234e38f).IsLosslessDouble()); // -FLT_MAX
692
+ EXPECT_TRUE(Value(1.17549435e-38f).IsLosslessDouble()); // FLT_MIN
693
+ EXPECT_TRUE(Value(-1.17549435e-38f).IsLosslessDouble()); // -FLT_MIN
694
+ EXPECT_TRUE(Value(1.7976931348623157e+308).IsLosslessDouble()); // DBL_MAX
695
+ EXPECT_TRUE(Value(-1.7976931348623157e+308).IsLosslessDouble()); // -DBL_MAX
696
+ EXPECT_TRUE(Value(2.2250738585072014e-308).IsLosslessDouble()); // DBL_MIN
697
+ EXPECT_TRUE(Value(-2.2250738585072014e-308).IsLosslessDouble()); // -DBL_MIN
698
+ }
699
+
700
+ TEST(Value, IsLosslessFloat) {
701
+ EXPECT_TRUE(Value(12.25).IsLosslessFloat());
702
+ EXPECT_TRUE(Value(-123).IsLosslessFloat());
703
+ EXPECT_TRUE(Value(2147483648u).IsLosslessFloat());
704
+ EXPECT_TRUE(Value(3.4028234e38f).IsLosslessFloat());
705
+ EXPECT_TRUE(Value(-3.4028234e38f).IsLosslessFloat());
706
+ EXPECT_FALSE(Value(3.4028235e38).IsLosslessFloat());
707
+ EXPECT_FALSE(Value(0.3).IsLosslessFloat());
708
+ }
709
+
710
+ TEST(Value, String) {
711
+ // Construction with const string
712
+ Value x("Hello", 5); // literal
713
+ EXPECT_EQ(kStringType, x.GetType());
714
+ EXPECT_TRUE(x.IsString());
715
+ EXPECT_STREQ("Hello", x.GetString());
716
+ EXPECT_EQ(5u, x.GetStringLength());
717
+
718
+ EXPECT_FALSE(x.IsNumber());
719
+ EXPECT_FALSE(x.IsNull());
720
+ EXPECT_FALSE(x.IsBool());
721
+ EXPECT_FALSE(x.IsFalse());
722
+ EXPECT_FALSE(x.IsTrue());
723
+ EXPECT_FALSE(x.IsObject());
724
+ EXPECT_FALSE(x.IsArray());
725
+
726
+ static const char cstr[] = "World"; // const array
727
+ Value(cstr).Swap(x);
728
+ EXPECT_TRUE(x.IsString());
729
+ EXPECT_EQ(x.GetString(), cstr);
730
+ EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1);
731
+
732
+ static char mstr[] = "Howdy"; // non-const array
733
+ // Value(mstr).Swap(x); // should not compile
734
+ Value(StringRef(mstr)).Swap(x);
735
+ EXPECT_TRUE(x.IsString());
736
+ EXPECT_EQ(x.GetString(), mstr);
737
+ EXPECT_EQ(x.GetStringLength(), sizeof(mstr)-1);
738
+ strncpy(mstr,"Hello", sizeof(mstr));
739
+ EXPECT_STREQ(x.GetString(), "Hello");
740
+
741
+ const char* pstr = cstr;
742
+ //Value(pstr).Swap(x); // should not compile
743
+ Value(StringRef(pstr)).Swap(x);
744
+ EXPECT_TRUE(x.IsString());
745
+ EXPECT_EQ(x.GetString(), cstr);
746
+ EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1);
747
+
748
+ char* mpstr = mstr;
749
+ Value(StringRef(mpstr,sizeof(mstr)-1)).Swap(x);
750
+ EXPECT_TRUE(x.IsString());
751
+ EXPECT_EQ(x.GetString(), mstr);
752
+ EXPECT_EQ(x.GetStringLength(), 5u);
753
+ EXPECT_STREQ(x.GetString(), "Hello");
754
+
755
+ // Constructor with copy string
756
+ MemoryPoolAllocator<> allocator;
757
+ Value c(x.GetString(), x.GetStringLength(), allocator);
758
+ EXPECT_NE(x.GetString(), c.GetString());
759
+ EXPECT_EQ(x.GetStringLength(), c.GetStringLength());
760
+ EXPECT_STREQ(x.GetString(), c.GetString());
761
+ //x.SetString("World");
762
+ x.SetString("World", 5);
763
+ EXPECT_STREQ("Hello", c.GetString());
764
+ EXPECT_EQ(5u, c.GetStringLength());
765
+
766
+ // Constructor with type
767
+ Value y(kStringType);
768
+ EXPECT_TRUE(y.IsString());
769
+ EXPECT_STREQ("", y.GetString()); // Empty string should be "" instead of 0 (issue 226)
770
+ EXPECT_EQ(0u, y.GetStringLength());
771
+
772
+ // SetConsttring()
773
+ Value z;
774
+ z.SetString("Hello");
775
+ EXPECT_TRUE(x.IsString());
776
+ z.SetString("Hello", 5);
777
+ EXPECT_STREQ("Hello", z.GetString());
778
+ EXPECT_STREQ("Hello", z.GetString());
779
+ EXPECT_EQ(5u, z.GetStringLength());
780
+
781
+ z.SetString("Hello");
782
+ EXPECT_TRUE(z.IsString());
783
+ EXPECT_STREQ("Hello", z.GetString());
784
+
785
+ //z.SetString(mstr); // should not compile
786
+ //z.SetString(pstr); // should not compile
787
+ z.SetString(StringRef(mstr));
788
+ EXPECT_TRUE(z.IsString());
789
+ EXPECT_STREQ(z.GetString(), mstr);
790
+
791
+ z.SetString(cstr);
792
+ EXPECT_TRUE(z.IsString());
793
+ EXPECT_EQ(cstr, z.GetString());
794
+
795
+ z = cstr;
796
+ EXPECT_TRUE(z.IsString());
797
+ EXPECT_EQ(cstr, z.GetString());
798
+
799
+ // SetString()
800
+ char s[] = "World";
801
+ Value w;
802
+ w.SetString(s, static_cast<SizeType>(strlen(s)), allocator);
803
+ s[0] = '\0';
804
+ EXPECT_STREQ("World", w.GetString());
805
+ EXPECT_EQ(5u, w.GetStringLength());
806
+
807
+ // templated functions
808
+ EXPECT_TRUE(z.Is<const char*>());
809
+ EXPECT_STREQ(cstr, z.Get<const char*>());
810
+ EXPECT_STREQ("Apple", z.Set<const char*>("Apple").Get<const char*>());
811
+
812
+ #if RAPIDJSON_HAS_STDSTRING
813
+ {
814
+ std::string str = "Hello World";
815
+ str[5] = '\0';
816
+ EXPECT_STREQ(str.data(),"Hello"); // embedded '\0'
817
+ EXPECT_EQ(str.size(), 11u);
818
+
819
+ // no copy
820
+ Value vs0(StringRef(str));
821
+ EXPECT_TRUE(vs0.IsString());
822
+ EXPECT_EQ(vs0.GetString(), str.data());
823
+ EXPECT_EQ(vs0.GetStringLength(), str.size());
824
+ TestEqual(vs0, str);
825
+
826
+ // do copy
827
+ Value vs1(str, allocator);
828
+ EXPECT_TRUE(vs1.IsString());
829
+ EXPECT_NE(vs1.GetString(), str.data());
830
+ EXPECT_NE(vs1.GetString(), str); // not equal due to embedded '\0'
831
+ EXPECT_EQ(vs1.GetStringLength(), str.size());
832
+ TestEqual(vs1, str);
833
+
834
+ // SetString
835
+ str = "World";
836
+ vs0.SetNull().SetString(str, allocator);
837
+ EXPECT_TRUE(vs0.IsString());
838
+ EXPECT_STREQ(vs0.GetString(), str.c_str());
839
+ EXPECT_EQ(vs0.GetStringLength(), str.size());
840
+ TestEqual(str, vs0);
841
+ TestUnequal(str, vs1);
842
+
843
+ // vs1 = str; // should not compile
844
+ vs1 = StringRef(str);
845
+ TestEqual(str, vs1);
846
+ TestEqual(vs0, vs1);
847
+
848
+ // Templated function.
849
+ EXPECT_TRUE(vs0.Is<std::string>());
850
+ EXPECT_EQ(str, vs0.Get<std::string>());
851
+ vs0.Set<std::string>(std::string("Apple"), allocator);
852
+ EXPECT_EQ(std::string("Apple"), vs0.Get<std::string>());
853
+ vs0.Set(std::string("Orange"), allocator);
854
+ EXPECT_EQ(std::string("Orange"), vs0.Get<std::string>());
855
+ }
856
+ #endif // RAPIDJSON_HAS_STDSTRING
857
+ }
858
+
859
+ // Issue 226: Value of string type should not point to NULL
860
+ TEST(Value, SetStringNull) {
861
+
862
+ MemoryPoolAllocator<> allocator;
863
+ const char* nullPtr = 0;
864
+ {
865
+ // Construction with string type creates empty string
866
+ Value v(kStringType);
867
+ EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
868
+ EXPECT_EQ(v.GetStringLength(), 0u);
869
+
870
+ // Construction from/setting to null without length not allowed
871
+ EXPECT_THROW(Value(StringRef(nullPtr)), AssertException);
872
+ EXPECT_THROW(Value(StringRef(nullPtr), allocator), AssertException);
873
+ EXPECT_THROW(v.SetString(nullPtr, allocator), AssertException);
874
+
875
+ // Non-empty length with null string is not allowed
876
+ EXPECT_THROW(v.SetString(nullPtr, 17u), AssertException);
877
+ EXPECT_THROW(v.SetString(nullPtr, 42u, allocator), AssertException);
878
+
879
+ // Setting to null string with empty length is allowed
880
+ v.SetString(nullPtr, 0u);
881
+ EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
882
+ EXPECT_EQ(v.GetStringLength(), 0u);
883
+
884
+ v.SetNull();
885
+ v.SetString(nullPtr, 0u, allocator);
886
+ EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
887
+ EXPECT_EQ(v.GetStringLength(), 0u);
888
+ }
889
+ // Construction with null string and empty length is allowed
890
+ {
891
+ Value v(nullPtr,0u);
892
+ EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
893
+ EXPECT_EQ(v.GetStringLength(), 0u);
894
+ }
895
+ {
896
+ Value v(nullPtr, 0u, allocator);
897
+ EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
898
+ EXPECT_EQ(v.GetStringLength(), 0u);
899
+ }
900
+ }
901
+
902
+ template <typename T, typename Allocator>
903
+ static void TestArray(T& x, Allocator& allocator) {
904
+ const T& y = x;
905
+
906
+ // PushBack()
907
+ Value v;
908
+ x.PushBack(v, allocator);
909
+ v.SetBool(true);
910
+ x.PushBack(v, allocator);
911
+ v.SetBool(false);
912
+ x.PushBack(v, allocator);
913
+ v.SetInt(123);
914
+ x.PushBack(v, allocator);
915
+ //x.PushBack((const char*)"foo", allocator); // should not compile
916
+ x.PushBack("foo", allocator);
917
+
918
+ EXPECT_FALSE(x.Empty());
919
+ EXPECT_EQ(5u, x.Size());
920
+ EXPECT_FALSE(y.Empty());
921
+ EXPECT_EQ(5u, y.Size());
922
+ EXPECT_TRUE(x[SizeType(0)].IsNull());
923
+ EXPECT_TRUE(x[1].IsTrue());
924
+ EXPECT_TRUE(x[2].IsFalse());
925
+ EXPECT_TRUE(x[3].IsInt());
926
+ EXPECT_EQ(123, x[3].GetInt());
927
+ EXPECT_TRUE(y[SizeType(0)].IsNull());
928
+ EXPECT_TRUE(y[1].IsTrue());
929
+ EXPECT_TRUE(y[2].IsFalse());
930
+ EXPECT_TRUE(y[3].IsInt());
931
+ EXPECT_EQ(123, y[3].GetInt());
932
+ EXPECT_TRUE(y[4].IsString());
933
+ EXPECT_STREQ("foo", y[4].GetString());
934
+
935
+ #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
936
+ // PushBack(GenericValue&&, Allocator&);
937
+ {
938
+ Value y2(kArrayType);
939
+ y2.PushBack(Value(true), allocator);
940
+ y2.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator);
941
+ EXPECT_EQ(2u, y2.Size());
942
+ EXPECT_TRUE(y2[0].IsTrue());
943
+ EXPECT_TRUE(y2[1].IsArray());
944
+ EXPECT_EQ(2u, y2[1].Size());
945
+ EXPECT_TRUE(y2[1][0].IsInt());
946
+ EXPECT_TRUE(y2[1][1].IsString());
947
+ }
948
+ #endif
949
+
950
+ // iterator
951
+ typename T::ValueIterator itr = x.Begin();
952
+ EXPECT_TRUE(itr != x.End());
953
+ EXPECT_TRUE(itr->IsNull());
954
+ ++itr;
955
+ EXPECT_TRUE(itr != x.End());
956
+ EXPECT_TRUE(itr->IsTrue());
957
+ ++itr;
958
+ EXPECT_TRUE(itr != x.End());
959
+ EXPECT_TRUE(itr->IsFalse());
960
+ ++itr;
961
+ EXPECT_TRUE(itr != x.End());
962
+ EXPECT_TRUE(itr->IsInt());
963
+ EXPECT_EQ(123, itr->GetInt());
964
+ ++itr;
965
+ EXPECT_TRUE(itr != x.End());
966
+ EXPECT_TRUE(itr->IsString());
967
+ EXPECT_STREQ("foo", itr->GetString());
968
+
969
+ // const iterator
970
+ typename T::ConstValueIterator citr = y.Begin();
971
+ EXPECT_TRUE(citr != y.End());
972
+ EXPECT_TRUE(citr->IsNull());
973
+ ++citr;
974
+ EXPECT_TRUE(citr != y.End());
975
+ EXPECT_TRUE(citr->IsTrue());
976
+ ++citr;
977
+ EXPECT_TRUE(citr != y.End());
978
+ EXPECT_TRUE(citr->IsFalse());
979
+ ++citr;
980
+ EXPECT_TRUE(citr != y.End());
981
+ EXPECT_TRUE(citr->IsInt());
982
+ EXPECT_EQ(123, citr->GetInt());
983
+ ++citr;
984
+ EXPECT_TRUE(citr != y.End());
985
+ EXPECT_TRUE(citr->IsString());
986
+ EXPECT_STREQ("foo", citr->GetString());
987
+
988
+ // PopBack()
989
+ x.PopBack();
990
+ EXPECT_EQ(4u, x.Size());
991
+ EXPECT_TRUE(y[SizeType(0)].IsNull());
992
+ EXPECT_TRUE(y[1].IsTrue());
993
+ EXPECT_TRUE(y[2].IsFalse());
994
+ EXPECT_TRUE(y[3].IsInt());
995
+
996
+ // Clear()
997
+ x.Clear();
998
+ EXPECT_TRUE(x.Empty());
999
+ EXPECT_EQ(0u, x.Size());
1000
+ EXPECT_TRUE(y.Empty());
1001
+ EXPECT_EQ(0u, y.Size());
1002
+
1003
+ // Erase(ValueIterator)
1004
+
1005
+ // Use array of array to ensure removed elements' destructor is called.
1006
+ // [[0],[1],[2],...]
1007
+ for (int i = 0; i < 10; i++)
1008
+ x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
1009
+
1010
+ // Erase the first
1011
+ itr = x.Erase(x.Begin());
1012
+ EXPECT_EQ(x.Begin(), itr);
1013
+ EXPECT_EQ(9u, x.Size());
1014
+ for (int i = 0; i < 9; i++)
1015
+ EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
1016
+
1017
+ // Ease the last
1018
+ itr = x.Erase(x.End() - 1);
1019
+ EXPECT_EQ(x.End(), itr);
1020
+ EXPECT_EQ(8u, x.Size());
1021
+ for (int i = 0; i < 8; i++)
1022
+ EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
1023
+
1024
+ // Erase the middle
1025
+ itr = x.Erase(x.Begin() + 4);
1026
+ EXPECT_EQ(x.Begin() + 4, itr);
1027
+ EXPECT_EQ(7u, x.Size());
1028
+ for (int i = 0; i < 4; i++)
1029
+ EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
1030
+ for (int i = 4; i < 7; i++)
1031
+ EXPECT_EQ(i + 2, x[static_cast<SizeType>(i)][0].GetInt());
1032
+
1033
+ // Erase(ValueIterator, ValueIterator)
1034
+ // Exhaustive test with all 0 <= first < n, first <= last <= n cases
1035
+ const unsigned n = 10;
1036
+ for (unsigned first = 0; first < n; first++) {
1037
+ for (unsigned last = first; last <= n; last++) {
1038
+ x.Clear();
1039
+ for (unsigned i = 0; i < n; i++)
1040
+ x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
1041
+
1042
+ itr = x.Erase(x.Begin() + first, x.Begin() + last);
1043
+ if (last == n)
1044
+ EXPECT_EQ(x.End(), itr);
1045
+ else
1046
+ EXPECT_EQ(x.Begin() + first, itr);
1047
+
1048
+ size_t removeCount = last - first;
1049
+ EXPECT_EQ(n - removeCount, x.Size());
1050
+ for (unsigned i = 0; i < first; i++)
1051
+ EXPECT_EQ(i, x[i][0].GetUint());
1052
+ for (unsigned i = first; i < n - removeCount; i++)
1053
+ EXPECT_EQ(i + removeCount, x[static_cast<SizeType>(i)][0].GetUint());
1054
+ }
1055
+ }
1056
+ }
1057
+
1058
+ TEST(Value, Array) {
1059
+ Value x(kArrayType);
1060
+ const Value& y = x;
1061
+ Value::AllocatorType allocator;
1062
+
1063
+ EXPECT_EQ(kArrayType, x.GetType());
1064
+ EXPECT_TRUE(x.IsArray());
1065
+ EXPECT_TRUE(x.Empty());
1066
+ EXPECT_EQ(0u, x.Size());
1067
+ EXPECT_TRUE(y.IsArray());
1068
+ EXPECT_TRUE(y.Empty());
1069
+ EXPECT_EQ(0u, y.Size());
1070
+
1071
+ EXPECT_FALSE(x.IsNull());
1072
+ EXPECT_FALSE(x.IsBool());
1073
+ EXPECT_FALSE(x.IsFalse());
1074
+ EXPECT_FALSE(x.IsTrue());
1075
+ EXPECT_FALSE(x.IsString());
1076
+ EXPECT_FALSE(x.IsObject());
1077
+
1078
+ TestArray(x, allocator);
1079
+
1080
+ // Working in gcc without C++11, but VS2013 cannot compile. To be diagnosed.
1081
+ // http://en.wikipedia.org/wiki/Erase-remove_idiom
1082
+ x.Clear();
1083
+ for (int i = 0; i < 10; i++)
1084
+ if (i % 2 == 0)
1085
+ x.PushBack(i, allocator);
1086
+ else
1087
+ x.PushBack(Value(kNullType).Move(), allocator);
1088
+
1089
+ const Value null(kNullType);
1090
+ x.Erase(std::remove(x.Begin(), x.End(), null), x.End());
1091
+ EXPECT_EQ(5u, x.Size());
1092
+ for (int i = 0; i < 5; i++)
1093
+ EXPECT_EQ(i * 2, x[static_cast<SizeType>(i)]);
1094
+
1095
+ // SetArray()
1096
+ Value z;
1097
+ z.SetArray();
1098
+ EXPECT_TRUE(z.IsArray());
1099
+ EXPECT_TRUE(z.Empty());
1100
+ }
1101
+
1102
+ TEST(Value, ArrayHelper) {
1103
+ Value::AllocatorType allocator;
1104
+ {
1105
+ Value x(kArrayType);
1106
+ Value::Array a = x.GetArray();
1107
+ TestArray(a, allocator);
1108
+ }
1109
+
1110
+ {
1111
+ Value x(kArrayType);
1112
+ Value::Array a = x.GetArray();
1113
+ a.PushBack(1, allocator);
1114
+
1115
+ Value::Array a2(a); // copy constructor
1116
+ EXPECT_EQ(1, a2.Size());
1117
+
1118
+ Value::Array a3 = a;
1119
+ EXPECT_EQ(1, a3.Size());
1120
+
1121
+ Value::ConstArray y = static_cast<const Value&>(x).GetArray();
1122
+ (void)y;
1123
+ // y.PushBack(1, allocator); // should not compile
1124
+
1125
+ // Templated functions
1126
+ x.Clear();
1127
+ EXPECT_TRUE(x.Is<Value::Array>());
1128
+ EXPECT_TRUE(x.Is<Value::ConstArray>());
1129
+ a.PushBack(1, allocator);
1130
+ EXPECT_EQ(1, x.Get<Value::Array>()[0].GetInt());
1131
+ EXPECT_EQ(1, x.Get<Value::ConstArray>()[0].GetInt());
1132
+
1133
+ Value x2;
1134
+ x2.Set<Value::Array>(a);
1135
+ EXPECT_TRUE(x.IsArray()); // IsArray() is invariant after moving.
1136
+ EXPECT_EQ(1, x2.Get<Value::Array>()[0].GetInt());
1137
+ }
1138
+
1139
+ {
1140
+ Value y(kArrayType);
1141
+ y.PushBack(123, allocator);
1142
+
1143
+ Value x(y.GetArray()); // Construct value form array.
1144
+ EXPECT_TRUE(x.IsArray());
1145
+ EXPECT_EQ(123, x[0].GetInt());
1146
+ EXPECT_TRUE(y.IsArray()); // Invariant
1147
+ EXPECT_TRUE(y.Empty());
1148
+ }
1149
+
1150
+ {
1151
+ Value x(kArrayType);
1152
+ Value y(kArrayType);
1153
+ y.PushBack(123, allocator);
1154
+ x.PushBack(y.GetArray(), allocator); // Implicit constructor to convert Array to GenericValue
1155
+
1156
+ EXPECT_EQ(1, x.Size());
1157
+ EXPECT_EQ(123, x[0][0].GetInt());
1158
+ EXPECT_TRUE(y.IsArray());
1159
+ EXPECT_TRUE(y.Empty());
1160
+ }
1161
+ }
1162
+
1163
+ #if RAPIDJSON_HAS_CXX11_RANGE_FOR
1164
+ TEST(Value, ArrayHelperRangeFor) {
1165
+ Value::AllocatorType allocator;
1166
+ Value x(kArrayType);
1167
+
1168
+ for (int i = 0; i < 10; i++)
1169
+ x.PushBack(i, allocator);
1170
+
1171
+ {
1172
+ int i = 0;
1173
+ for (auto& v : x.GetArray()) {
1174
+ EXPECT_EQ(i, v.GetInt());
1175
+ i++;
1176
+ }
1177
+ EXPECT_EQ(i, 10);
1178
+ }
1179
+ {
1180
+ int i = 0;
1181
+ for (const auto& v : const_cast<const Value&>(x).GetArray()) {
1182
+ EXPECT_EQ(i, v.GetInt());
1183
+ i++;
1184
+ }
1185
+ EXPECT_EQ(i, 10);
1186
+ }
1187
+
1188
+ // Array a = x.GetArray();
1189
+ // Array ca = const_cast<const Value&>(x).GetArray();
1190
+ }
1191
+ #endif
1192
+
1193
+ template <typename T, typename Allocator>
1194
+ static void TestObject(T& x, Allocator& allocator) {
1195
+ const T& y = x; // const version
1196
+
1197
+ // AddMember()
1198
+ x.AddMember("A", "Apple", allocator);
1199
+ EXPECT_FALSE(x.ObjectEmpty());
1200
+ EXPECT_EQ(1u, x.MemberCount());
1201
+
1202
+ Value value("Banana", 6);
1203
+ x.AddMember("B", "Banana", allocator);
1204
+ EXPECT_EQ(2u, x.MemberCount());
1205
+
1206
+ // AddMember<T>(StringRefType, T, Allocator)
1207
+ {
1208
+ Value o(kObjectType);
1209
+ o.AddMember("true", true, allocator);
1210
+ o.AddMember("false", false, allocator);
1211
+ o.AddMember("int", -1, allocator);
1212
+ o.AddMember("uint", 1u, allocator);
1213
+ o.AddMember("int64", int64_t(-4294967296), allocator);
1214
+ o.AddMember("uint64", uint64_t(4294967296), allocator);
1215
+ o.AddMember("double", 3.14, allocator);
1216
+ o.AddMember("string", "Jelly", allocator);
1217
+
1218
+ EXPECT_TRUE(o["true"].GetBool());
1219
+ EXPECT_FALSE(o["false"].GetBool());
1220
+ EXPECT_EQ(-1, o["int"].GetInt());
1221
+ EXPECT_EQ(1u, o["uint"].GetUint());
1222
+ EXPECT_EQ(int64_t(-4294967296), o["int64"].GetInt64());
1223
+ EXPECT_EQ(uint64_t(4294967296), o["uint64"].GetUint64());
1224
+ EXPECT_STREQ("Jelly",o["string"].GetString());
1225
+ EXPECT_EQ(8u, o.MemberCount());
1226
+ }
1227
+
1228
+ // AddMember<T>(Value&, T, Allocator)
1229
+ {
1230
+ Value o(kObjectType);
1231
+
1232
+ Value n("s");
1233
+ o.AddMember(n, "string", allocator);
1234
+ EXPECT_EQ(1u, o.MemberCount());
1235
+
1236
+ Value count("#");
1237
+ o.AddMember(count, o.MemberCount(), allocator);
1238
+ EXPECT_EQ(2u, o.MemberCount());
1239
+ }
1240
+
1241
+ #if RAPIDJSON_HAS_STDSTRING
1242
+ {
1243
+ // AddMember(StringRefType, const std::string&, Allocator)
1244
+ Value o(kObjectType);
1245
+ o.AddMember("b", std::string("Banana"), allocator);
1246
+ EXPECT_STREQ("Banana", o["b"].GetString());
1247
+
1248
+ // RemoveMember(const std::string&)
1249
+ o.RemoveMember(std::string("b"));
1250
+ EXPECT_TRUE(o.ObjectEmpty());
1251
+ }
1252
+ #endif
1253
+
1254
+ #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1255
+ // AddMember(GenericValue&&, ...) variants
1256
+ {
1257
+ Value o(kObjectType);
1258
+ o.AddMember(Value("true"), Value(true), allocator);
1259
+ o.AddMember(Value("false"), Value(false).Move(), allocator); // value is lvalue ref
1260
+ o.AddMember(Value("int").Move(), Value(-1), allocator); // name is lvalue ref
1261
+ o.AddMember("uint", std::move(Value().SetUint(1u)), allocator); // name is literal, value is rvalue
1262
+ EXPECT_TRUE(o["true"].GetBool());
1263
+ EXPECT_FALSE(o["false"].GetBool());
1264
+ EXPECT_EQ(-1, o["int"].GetInt());
1265
+ EXPECT_EQ(1u, o["uint"].GetUint());
1266
+ EXPECT_EQ(4u, o.MemberCount());
1267
+ }
1268
+ #endif
1269
+
1270
+ // Tests a member with null character
1271
+ Value name;
1272
+ const Value C0D("C\0D", 3);
1273
+ name.SetString(C0D.GetString(), 3);
1274
+ value.SetString("CherryD", 7);
1275
+ x.AddMember(name, value, allocator);
1276
+
1277
+ // HasMember()
1278
+ EXPECT_TRUE(x.HasMember("A"));
1279
+ EXPECT_TRUE(x.HasMember("B"));
1280
+ EXPECT_TRUE(y.HasMember("A"));
1281
+ EXPECT_TRUE(y.HasMember("B"));
1282
+
1283
+ #if RAPIDJSON_HAS_STDSTRING
1284
+ EXPECT_TRUE(x.HasMember(std::string("A")));
1285
+ #endif
1286
+
1287
+ name.SetString("C\0D");
1288
+ EXPECT_TRUE(x.HasMember(name));
1289
+ EXPECT_TRUE(y.HasMember(name));
1290
+
1291
+ GenericValue<UTF8<>, CrtAllocator> othername("A");
1292
+ EXPECT_TRUE(x.HasMember(othername));
1293
+ EXPECT_TRUE(y.HasMember(othername));
1294
+ othername.SetString("C\0D");
1295
+ EXPECT_TRUE(x.HasMember(othername));
1296
+ EXPECT_TRUE(y.HasMember(othername));
1297
+
1298
+ // operator[]
1299
+ EXPECT_STREQ("Apple", x["A"].GetString());
1300
+ EXPECT_STREQ("Banana", x["B"].GetString());
1301
+ EXPECT_STREQ("CherryD", x[C0D].GetString());
1302
+ EXPECT_STREQ("CherryD", x[othername].GetString());
1303
+ EXPECT_THROW(x["nonexist"], AssertException);
1304
+
1305
+ // const operator[]
1306
+ EXPECT_STREQ("Apple", y["A"].GetString());
1307
+ EXPECT_STREQ("Banana", y["B"].GetString());
1308
+ EXPECT_STREQ("CherryD", y[C0D].GetString());
1309
+
1310
+ #if RAPIDJSON_HAS_STDSTRING
1311
+ EXPECT_STREQ("Apple", x["A"].GetString());
1312
+ EXPECT_STREQ("Apple", y[std::string("A")].GetString());
1313
+ #endif
1314
+
1315
+ // member iterator
1316
+ Value::MemberIterator itr = x.MemberBegin();
1317
+ EXPECT_TRUE(itr != x.MemberEnd());
1318
+ EXPECT_STREQ("A", itr->name.GetString());
1319
+ EXPECT_STREQ("Apple", itr->value.GetString());
1320
+ ++itr;
1321
+ EXPECT_TRUE(itr != x.MemberEnd());
1322
+ EXPECT_STREQ("B", itr->name.GetString());
1323
+ EXPECT_STREQ("Banana", itr->value.GetString());
1324
+ ++itr;
1325
+ EXPECT_TRUE(itr != x.MemberEnd());
1326
+ EXPECT_TRUE(memcmp(itr->name.GetString(), "C\0D", 4) == 0);
1327
+ EXPECT_STREQ("CherryD", itr->value.GetString());
1328
+ ++itr;
1329
+ EXPECT_FALSE(itr != x.MemberEnd());
1330
+
1331
+ // const member iterator
1332
+ Value::ConstMemberIterator citr = y.MemberBegin();
1333
+ EXPECT_TRUE(citr != y.MemberEnd());
1334
+ EXPECT_STREQ("A", citr->name.GetString());
1335
+ EXPECT_STREQ("Apple", citr->value.GetString());
1336
+ ++citr;
1337
+ EXPECT_TRUE(citr != y.MemberEnd());
1338
+ EXPECT_STREQ("B", citr->name.GetString());
1339
+ EXPECT_STREQ("Banana", citr->value.GetString());
1340
+ ++citr;
1341
+ EXPECT_TRUE(citr != y.MemberEnd());
1342
+ EXPECT_TRUE(memcmp(citr->name.GetString(), "C\0D", 4) == 0);
1343
+ EXPECT_STREQ("CherryD", citr->value.GetString());
1344
+ ++citr;
1345
+ EXPECT_FALSE(citr != y.MemberEnd());
1346
+
1347
+ // member iterator conversions/relations
1348
+ itr = x.MemberBegin();
1349
+ citr = x.MemberBegin(); // const conversion
1350
+ TestEqual(itr, citr);
1351
+ EXPECT_TRUE(itr < x.MemberEnd());
1352
+ EXPECT_FALSE(itr > y.MemberEnd());
1353
+ EXPECT_TRUE(citr < x.MemberEnd());
1354
+ EXPECT_FALSE(citr > y.MemberEnd());
1355
+ ++citr;
1356
+ TestUnequal(itr, citr);
1357
+ EXPECT_FALSE(itr < itr);
1358
+ EXPECT_TRUE(itr < citr);
1359
+ EXPECT_FALSE(itr > itr);
1360
+ EXPECT_TRUE(citr > itr);
1361
+ EXPECT_EQ(1, citr - x.MemberBegin());
1362
+ EXPECT_EQ(0, itr - y.MemberBegin());
1363
+ itr += citr - x.MemberBegin();
1364
+ EXPECT_EQ(1, itr - y.MemberBegin());
1365
+ TestEqual(citr, itr);
1366
+ EXPECT_TRUE(itr <= citr);
1367
+ EXPECT_TRUE(citr <= itr);
1368
+ itr++;
1369
+ EXPECT_TRUE(itr >= citr);
1370
+ EXPECT_FALSE(citr >= itr);
1371
+
1372
+ // RemoveMember()
1373
+ EXPECT_TRUE(x.RemoveMember("A"));
1374
+ EXPECT_FALSE(x.HasMember("A"));
1375
+
1376
+ EXPECT_TRUE(x.RemoveMember("B"));
1377
+ EXPECT_FALSE(x.HasMember("B"));
1378
+
1379
+ EXPECT_FALSE(x.RemoveMember("nonexist"));
1380
+
1381
+ EXPECT_TRUE(x.RemoveMember(othername));
1382
+ EXPECT_FALSE(x.HasMember(name));
1383
+
1384
+ EXPECT_TRUE(x.MemberBegin() == x.MemberEnd());
1385
+
1386
+ // EraseMember(ConstMemberIterator)
1387
+
1388
+ // Use array members to ensure removed elements' destructor is called.
1389
+ // { "a": [0], "b": [1],[2],...]
1390
+ const char keys[][2] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" };
1391
+ for (int i = 0; i < 10; i++)
1392
+ x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
1393
+
1394
+ // MemberCount, iterator difference
1395
+ EXPECT_EQ(x.MemberCount(), SizeType(x.MemberEnd() - x.MemberBegin()));
1396
+
1397
+ // Erase the first
1398
+ itr = x.EraseMember(x.MemberBegin());
1399
+ EXPECT_FALSE(x.HasMember(keys[0]));
1400
+ EXPECT_EQ(x.MemberBegin(), itr);
1401
+ EXPECT_EQ(9u, x.MemberCount());
1402
+ for (; itr != x.MemberEnd(); ++itr) {
1403
+ size_t i = static_cast<size_t>((itr - x.MemberBegin())) + 1;
1404
+ EXPECT_STREQ(itr->name.GetString(), keys[i]);
1405
+ EXPECT_EQ(i, itr->value[0].GetInt());
1406
+ }
1407
+
1408
+ // Erase the last
1409
+ itr = x.EraseMember(x.MemberEnd() - 1);
1410
+ EXPECT_FALSE(x.HasMember(keys[9]));
1411
+ EXPECT_EQ(x.MemberEnd(), itr);
1412
+ EXPECT_EQ(8u, x.MemberCount());
1413
+ for (; itr != x.MemberEnd(); ++itr) {
1414
+ size_t i = static_cast<size_t>(itr - x.MemberBegin()) + 1;
1415
+ EXPECT_STREQ(itr->name.GetString(), keys[i]);
1416
+ EXPECT_EQ(i, itr->value[0].GetInt());
1417
+ }
1418
+
1419
+ // Erase the middle
1420
+ itr = x.EraseMember(x.MemberBegin() + 4);
1421
+ EXPECT_FALSE(x.HasMember(keys[5]));
1422
+ EXPECT_EQ(x.MemberBegin() + 4, itr);
1423
+ EXPECT_EQ(7u, x.MemberCount());
1424
+ for (; itr != x.MemberEnd(); ++itr) {
1425
+ size_t i = static_cast<size_t>(itr - x.MemberBegin());
1426
+ i += (i < 4) ? 1 : 2;
1427
+ EXPECT_STREQ(itr->name.GetString(), keys[i]);
1428
+ EXPECT_EQ(i, itr->value[0].GetInt());
1429
+ }
1430
+
1431
+ // EraseMember(ConstMemberIterator, ConstMemberIterator)
1432
+ // Exhaustive test with all 0 <= first < n, first <= last <= n cases
1433
+ const unsigned n = 10;
1434
+ for (unsigned first = 0; first < n; first++) {
1435
+ for (unsigned last = first; last <= n; last++) {
1436
+ x.RemoveAllMembers();
1437
+ for (unsigned i = 0; i < n; i++)
1438
+ x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
1439
+
1440
+ itr = x.EraseMember(x.MemberBegin() + static_cast<int>(first), x.MemberBegin() + static_cast<int>(last));
1441
+ if (last == n)
1442
+ EXPECT_EQ(x.MemberEnd(), itr);
1443
+ else
1444
+ EXPECT_EQ(x.MemberBegin() + static_cast<int>(first), itr);
1445
+
1446
+ size_t removeCount = last - first;
1447
+ EXPECT_EQ(n - removeCount, x.MemberCount());
1448
+ for (unsigned i = 0; i < first; i++)
1449
+ EXPECT_EQ(i, x[keys[i]][0].GetUint());
1450
+ for (unsigned i = first; i < n - removeCount; i++)
1451
+ EXPECT_EQ(i + removeCount, x[keys[i+removeCount]][0].GetUint());
1452
+ }
1453
+ }
1454
+
1455
+ // RemoveAllMembers()
1456
+ x.RemoveAllMembers();
1457
+ EXPECT_TRUE(x.ObjectEmpty());
1458
+ EXPECT_EQ(0u, x.MemberCount());
1459
+ }
1460
+
1461
+ TEST(Value, Object) {
1462
+ Value x(kObjectType);
1463
+ const Value& y = x; // const version
1464
+ Value::AllocatorType allocator;
1465
+
1466
+ EXPECT_EQ(kObjectType, x.GetType());
1467
+ EXPECT_TRUE(x.IsObject());
1468
+ EXPECT_TRUE(x.ObjectEmpty());
1469
+ EXPECT_EQ(0u, x.MemberCount());
1470
+ EXPECT_EQ(kObjectType, y.GetType());
1471
+ EXPECT_TRUE(y.IsObject());
1472
+ EXPECT_TRUE(y.ObjectEmpty());
1473
+ EXPECT_EQ(0u, y.MemberCount());
1474
+
1475
+ TestObject(x, allocator);
1476
+
1477
+ // SetObject()
1478
+ Value z;
1479
+ z.SetObject();
1480
+ EXPECT_TRUE(z.IsObject());
1481
+ }
1482
+
1483
+ TEST(Value, ObjectHelper) {
1484
+ Value::AllocatorType allocator;
1485
+ {
1486
+ Value x(kObjectType);
1487
+ Value::Object o = x.GetObject();
1488
+ TestObject(o, allocator);
1489
+ }
1490
+
1491
+ {
1492
+ Value x(kObjectType);
1493
+ Value::Object o = x.GetObject();
1494
+ o.AddMember("1", 1, allocator);
1495
+
1496
+ Value::Object o2(o); // copy constructor
1497
+ EXPECT_EQ(1, o2.MemberCount());
1498
+
1499
+ Value::Object o3 = o;
1500
+ EXPECT_EQ(1, o3.MemberCount());
1501
+
1502
+ Value::ConstObject y = static_cast<const Value&>(x).GetObject();
1503
+ (void)y;
1504
+ // y.AddMember("1", 1, allocator); // should not compile
1505
+
1506
+ // Templated functions
1507
+ x.RemoveAllMembers();
1508
+ EXPECT_TRUE(x.Is<Value::Object>());
1509
+ EXPECT_TRUE(x.Is<Value::ConstObject>());
1510
+ o.AddMember("1", 1, allocator);
1511
+ EXPECT_EQ(1, x.Get<Value::Object>()["1"].GetInt());
1512
+ EXPECT_EQ(1, x.Get<Value::ConstObject>()["1"].GetInt());
1513
+
1514
+ Value x2;
1515
+ x2.Set<Value::Object>(o);
1516
+ EXPECT_TRUE(x.IsObject()); // IsObject() is invariant after moving
1517
+ EXPECT_EQ(1, x2.Get<Value::Object>()["1"].GetInt());
1518
+ }
1519
+
1520
+ {
1521
+ Value x(kObjectType);
1522
+ x.AddMember("a", "apple", allocator);
1523
+ Value y(x.GetObject());
1524
+ EXPECT_STREQ("apple", y["a"].GetString());
1525
+ EXPECT_TRUE(x.IsObject()); // Invariant
1526
+ }
1527
+
1528
+ {
1529
+ Value x(kObjectType);
1530
+ x.AddMember("a", "apple", allocator);
1531
+ Value y(kObjectType);
1532
+ y.AddMember("fruits", x.GetObject(), allocator);
1533
+ EXPECT_STREQ("apple", y["fruits"]["a"].GetString());
1534
+ EXPECT_TRUE(x.IsObject()); // Invariant
1535
+ }
1536
+ }
1537
+
1538
+ #if RAPIDJSON_HAS_CXX11_RANGE_FOR
1539
+ TEST(Value, ObjectHelperRangeFor) {
1540
+ Value::AllocatorType allocator;
1541
+ Value x(kObjectType);
1542
+
1543
+ for (int i = 0; i < 10; i++) {
1544
+ char name[10];
1545
+ Value n(name, static_cast<SizeType>(sprintf(name, "%d", i)), allocator);
1546
+ x.AddMember(n, i, allocator);
1547
+ }
1548
+
1549
+ {
1550
+ int i = 0;
1551
+ for (auto& m : x.GetObject()) {
1552
+ char name[10];
1553
+ sprintf(name, "%d", i);
1554
+ EXPECT_STREQ(name, m.name.GetString());
1555
+ EXPECT_EQ(i, m.value.GetInt());
1556
+ i++;
1557
+ }
1558
+ EXPECT_EQ(i, 10);
1559
+ }
1560
+ {
1561
+ int i = 0;
1562
+ for (const auto& m : const_cast<const Value&>(x).GetObject()) {
1563
+ char name[10];
1564
+ sprintf(name, "%d", i);
1565
+ EXPECT_STREQ(name, m.name.GetString());
1566
+ EXPECT_EQ(i, m.value.GetInt());
1567
+ i++;
1568
+ }
1569
+ EXPECT_EQ(i, 10);
1570
+ }
1571
+
1572
+ // Object a = x.GetObject();
1573
+ // Object ca = const_cast<const Value&>(x).GetObject();
1574
+ }
1575
+ #endif
1576
+
1577
+ TEST(Value, EraseMember_String) {
1578
+ Value::AllocatorType allocator;
1579
+ Value x(kObjectType);
1580
+ x.AddMember("A", "Apple", allocator);
1581
+ x.AddMember("B", "Banana", allocator);
1582
+
1583
+ EXPECT_TRUE(x.EraseMember("B"));
1584
+ EXPECT_FALSE(x.HasMember("B"));
1585
+
1586
+ EXPECT_FALSE(x.EraseMember("nonexist"));
1587
+
1588
+ GenericValue<UTF8<>, CrtAllocator> othername("A");
1589
+ EXPECT_TRUE(x.EraseMember(othername));
1590
+ EXPECT_FALSE(x.HasMember("A"));
1591
+
1592
+ EXPECT_TRUE(x.MemberBegin() == x.MemberEnd());
1593
+ }
1594
+
1595
+ TEST(Value, BigNestedArray) {
1596
+ MemoryPoolAllocator<> allocator;
1597
+ Value x(kArrayType);
1598
+ static const SizeType n = 200;
1599
+
1600
+ for (SizeType i = 0; i < n; i++) {
1601
+ Value y(kArrayType);
1602
+ for (SizeType j = 0; j < n; j++) {
1603
+ Value number(static_cast<int>(i * n + j));
1604
+ y.PushBack(number, allocator);
1605
+ }
1606
+ x.PushBack(y, allocator);
1607
+ }
1608
+
1609
+ for (SizeType i = 0; i < n; i++)
1610
+ for (SizeType j = 0; j < n; j++) {
1611
+ EXPECT_TRUE(x[i][j].IsInt());
1612
+ EXPECT_EQ(static_cast<int>(i * n + j), x[i][j].GetInt());
1613
+ }
1614
+ }
1615
+
1616
+ TEST(Value, BigNestedObject) {
1617
+ MemoryPoolAllocator<> allocator;
1618
+ Value x(kObjectType);
1619
+ static const SizeType n = 200;
1620
+
1621
+ for (SizeType i = 0; i < n; i++) {
1622
+ char name1[10];
1623
+ sprintf(name1, "%d", i);
1624
+
1625
+ // Value name(name1); // should not compile
1626
+ Value name(name1, static_cast<SizeType>(strlen(name1)), allocator);
1627
+ Value object(kObjectType);
1628
+
1629
+ for (SizeType j = 0; j < n; j++) {
1630
+ char name2[10];
1631
+ sprintf(name2, "%d", j);
1632
+
1633
+ Value name3(name2, static_cast<SizeType>(strlen(name2)), allocator);
1634
+ Value number(static_cast<int>(i * n + j));
1635
+ object.AddMember(name3, number, allocator);
1636
+ }
1637
+
1638
+ // x.AddMember(name1, object, allocator); // should not compile
1639
+ x.AddMember(name, object, allocator);
1640
+ }
1641
+
1642
+ for (SizeType i = 0; i < n; i++) {
1643
+ char name1[10];
1644
+ sprintf(name1, "%d", i);
1645
+
1646
+ for (SizeType j = 0; j < n; j++) {
1647
+ char name2[10];
1648
+ sprintf(name2, "%d", j);
1649
+ x[name1];
1650
+ EXPECT_EQ(static_cast<int>(i * n + j), x[name1][name2].GetInt());
1651
+ }
1652
+ }
1653
+ }
1654
+
1655
+ // Issue 18: Error removing last element of object
1656
+ // http://code.google.com/p/rapidjson/issues/detail?id=18
1657
+ TEST(Value, RemoveLastElement) {
1658
+ rapidjson::Document doc;
1659
+ rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
1660
+ rapidjson::Value objVal(rapidjson::kObjectType);
1661
+ objVal.AddMember("var1", 123, allocator);
1662
+ objVal.AddMember("var2", "444", allocator);
1663
+ objVal.AddMember("var3", 555, allocator);
1664
+ EXPECT_TRUE(objVal.HasMember("var3"));
1665
+ objVal.RemoveMember("var3"); // Assertion here in r61
1666
+ EXPECT_FALSE(objVal.HasMember("var3"));
1667
+ }
1668
+
1669
+ // Issue 38: Segmentation fault with CrtAllocator
1670
+ TEST(Document, CrtAllocator) {
1671
+ typedef GenericValue<UTF8<>, CrtAllocator> V;
1672
+
1673
+ V::AllocatorType allocator;
1674
+ V o(kObjectType);
1675
+ o.AddMember("x", 1, allocator); // Should not call destructor on uninitialized name/value of newly allocated members.
1676
+
1677
+ V a(kArrayType);
1678
+ a.PushBack(1, allocator); // Should not call destructor on uninitialized Value of newly allocated elements.
1679
+ }
1680
+
1681
+ static void TestShortStringOptimization(const char* str) {
1682
+ const rapidjson::SizeType len = static_cast<rapidjson::SizeType>(strlen(str));
1683
+
1684
+ rapidjson::Document doc;
1685
+ rapidjson::Value val;
1686
+ val.SetString(str, len, doc.GetAllocator());
1687
+
1688
+ EXPECT_EQ(val.GetStringLength(), len);
1689
+ EXPECT_STREQ(val.GetString(), str);
1690
+ }
1691
+
1692
+ TEST(Value, AllocateShortString) {
1693
+ TestShortStringOptimization(""); // edge case: empty string
1694
+ TestShortStringOptimization("12345678"); // regular case for short strings: 8 chars
1695
+ TestShortStringOptimization("12345678901"); // edge case: 11 chars in 32-bit mode (=> short string)
1696
+ TestShortStringOptimization("123456789012"); // edge case: 12 chars in 32-bit mode (=> regular string)
1697
+ TestShortStringOptimization("123456789012345"); // edge case: 15 chars in 64-bit mode (=> short string)
1698
+ TestShortStringOptimization("1234567890123456"); // edge case: 16 chars in 64-bit mode (=> regular string)
1699
+ }
1700
+
1701
+ template <int e>
1702
+ struct TerminateHandler {
1703
+ bool Null() { return e != 0; }
1704
+ bool Bool(bool) { return e != 1; }
1705
+ bool Int(int) { return e != 2; }
1706
+ bool Uint(unsigned) { return e != 3; }
1707
+ bool Int64(int64_t) { return e != 4; }
1708
+ bool Uint64(uint64_t) { return e != 5; }
1709
+ bool Double(double) { return e != 6; }
1710
+ bool RawNumber(const char*, SizeType, bool) { return e != 7; }
1711
+ bool String(const char*, SizeType, bool) { return e != 8; }
1712
+ bool StartObject() { return e != 9; }
1713
+ bool Key(const char*, SizeType, bool) { return e != 10; }
1714
+ bool EndObject(SizeType) { return e != 11; }
1715
+ bool StartArray() { return e != 12; }
1716
+ bool EndArray(SizeType) { return e != 13; }
1717
+ };
1718
+
1719
+ #define TEST_TERMINATION(e, json)\
1720
+ {\
1721
+ Document d; \
1722
+ EXPECT_FALSE(d.Parse(json).HasParseError()); \
1723
+ Reader reader; \
1724
+ TerminateHandler<e> h;\
1725
+ EXPECT_FALSE(d.Accept(h));\
1726
+ }
1727
+
1728
+ TEST(Value, AcceptTerminationByHandler) {
1729
+ TEST_TERMINATION(0, "[null]");
1730
+ TEST_TERMINATION(1, "[true]");
1731
+ TEST_TERMINATION(1, "[false]");
1732
+ TEST_TERMINATION(2, "[-1]");
1733
+ TEST_TERMINATION(3, "[2147483648]");
1734
+ TEST_TERMINATION(4, "[-1234567890123456789]");
1735
+ TEST_TERMINATION(5, "[9223372036854775808]");
1736
+ TEST_TERMINATION(6, "[0.5]");
1737
+ // RawNumber() is never called
1738
+ TEST_TERMINATION(8, "[\"a\"]");
1739
+ TEST_TERMINATION(9, "[{}]");
1740
+ TEST_TERMINATION(10, "[{\"a\":1}]");
1741
+ TEST_TERMINATION(11, "[{}]");
1742
+ TEST_TERMINATION(12, "{\"a\":[]}");
1743
+ TEST_TERMINATION(13, "{\"a\":[]}");
1744
+ }
1745
+
1746
+ struct ValueIntComparer {
1747
+ bool operator()(const Value& lhs, const Value& rhs) const {
1748
+ return lhs.GetInt() < rhs.GetInt();
1749
+ }
1750
+ };
1751
+
1752
+ #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1753
+ TEST(Value, Sorting) {
1754
+ Value::AllocatorType allocator;
1755
+ Value a(kArrayType);
1756
+ a.PushBack(5, allocator);
1757
+ a.PushBack(1, allocator);
1758
+ a.PushBack(3, allocator);
1759
+ std::sort(a.Begin(), a.End(), ValueIntComparer());
1760
+ EXPECT_EQ(1, a[0].GetInt());
1761
+ EXPECT_EQ(3, a[1].GetInt());
1762
+ EXPECT_EQ(5, a[2].GetInt());
1763
+ }
1764
+ #endif
1765
+
1766
+ // http://stackoverflow.com/questions/35222230/
1767
+
1768
+ static void MergeDuplicateKey(Value& v, Value::AllocatorType& a) {
1769
+ if (v.IsObject()) {
1770
+ // Convert all key:value into key:[value]
1771
+ for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
1772
+ itr->value = Value(kArrayType).Move().PushBack(itr->value, a);
1773
+
1774
+ // Merge arrays if key is duplicated
1775
+ for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd();) {
1776
+ Value::MemberIterator itr2 = v.FindMember(itr->name);
1777
+ if (itr != itr2) {
1778
+ itr2->value.PushBack(itr->value[0], a);
1779
+ itr = v.EraseMember(itr);
1780
+ }
1781
+ else
1782
+ ++itr;
1783
+ }
1784
+
1785
+ // Convert key:[values] back to key:value if there is only one value
1786
+ for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) {
1787
+ if (itr->value.Size() == 1)
1788
+ itr->value = itr->value[0];
1789
+ MergeDuplicateKey(itr->value, a); // Recursion on the value
1790
+ }
1791
+ }
1792
+ else if (v.IsArray())
1793
+ for (Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr)
1794
+ MergeDuplicateKey(*itr, a);
1795
+ }
1796
+
1797
+ TEST(Value, MergeDuplicateKey) {
1798
+ Document d;
1799
+ d.Parse(
1800
+ "{"
1801
+ " \"key1\": {"
1802
+ " \"a\": \"asdf\","
1803
+ " \"b\": \"foo\","
1804
+ " \"b\": \"bar\","
1805
+ " \"c\": \"fdas\""
1806
+ " }"
1807
+ "}");
1808
+
1809
+ Document d2;
1810
+ d2.Parse(
1811
+ "{"
1812
+ " \"key1\": {"
1813
+ " \"a\": \"asdf\","
1814
+ " \"b\": ["
1815
+ " \"foo\","
1816
+ " \"bar\""
1817
+ " ],"
1818
+ " \"c\": \"fdas\""
1819
+ " }"
1820
+ "}");
1821
+
1822
+ EXPECT_NE(d2, d);
1823
+ MergeDuplicateKey(d, d.GetAllocator());
1824
+ EXPECT_EQ(d2, d);
1825
+ }
1826
+
1827
+ #ifdef __clang__
1828
+ RAPIDJSON_DIAG_POP
1829
+ #endif