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,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