From 5d650f14c4050e94ffe27601024fa58399ad2018 Mon Sep 17 00:00:00 2001 From: matzman Date: Sun, 19 Apr 2015 21:30:12 +0200 Subject: [PATCH] . --- src/hos_celix/CMakeLists.txt | 1 + src/hos_cosgi_core/CMakeLists.txt | 161 ++ .../include/hos_cosgi_core/cosgi_core.h | 25 + src/hos_cosgi_core/package.xml | 52 + src/hos_cosgi_devicerepository/CMakeLists.txt | 5 +- .../hos_devicerepository_service.h | 16 +- src/hos_cosgi_devicerepository/package.xml | 8 +- .../src/bundle_activator.cpp | 2 +- .../src/hos_devicerepository_service_impl.cpp | 8 +- .../src/hos_devicerepository_service_impl.h | 5 +- src/hos_cosgi_launcher/CMakeLists.txt | 3 +- .../hos_cosgi_launcher/hos_core_service.h | 10 +- src/hos_cosgi_launcher/package.xml | 2 + .../src/hos_core_service_impl.cpp | 8 +- .../src/hos_core_service_impl.h | 4 +- src/hos_libvariant/CMakeLists.txt | 193 ++ .../include/hos_libvariant/ArgParse.h | 302 +++ .../include/hos_libvariant/Blob.h | 63 + .../include/hos_libvariant/Config.h | 13 + .../include/hos_libvariant/Emitter.h | 226 ++ .../include/hos_libvariant/EmitterOutput.h | 87 + .../include/hos_libvariant/Exceptions.h | 88 + .../include/hos_libvariant/Extensions.h | 92 + .../include/hos_libvariant/GuessFormat.h | 23 + .../include/hos_libvariant/Parser.h | 158 ++ .../include/hos_libvariant/ParserInput.h | 104 + .../include/hos_libvariant/Path.h | 100 + .../include/hos_libvariant/Payload.h | 130 + .../include/hos_libvariant/Schema.h | 175 ++ .../include/hos_libvariant/SchemaLoader.h | 54 + .../include/hos_libvariant/SharedPtr.h | 41 + .../include/hos_libvariant/Variant.h | 816 ++++++ .../include/hos_libvariant/VariantDefines.h | 50 + .../include/hos_libvariant/VariantInternal.h | 96 + src/hos_libvariant/package.xml | 50 + src/hos_libvariant/src/.hg/00changelog.i | Bin 0 -> 57 bytes src/hos_libvariant/src/.hg/branch | 1 + .../src/.hg/cache/branch2-served | 2 + src/hos_libvariant/src/.hg/dirstate | Bin 0 -> 13370 bytes src/hos_libvariant/src/.hg/hgrc | 2 + src/hos_libvariant/src/.hg/requires | 4 + .../src/.hg/store/00changelog.i | Bin 0 -> 2605 bytes src/hos_libvariant/src/.hg/store/00manifest.i | Bin 0 -> 9454 bytes .../src/.hg/store/data/_c_make_lists.txt.i | Bin 0 -> 2608 bytes .../src/.hg/store/data/_config.h.in.i | Bin 0 -> 214 bytes .../src/.hg/store/data/_doxyfile.in.i | Bin 0 -> 18722 bytes .../src/.hg/store/data/_l_i_c_e_n_s_e.i | Bin 0 -> 528 bytes ...lib_variant_build_tree_settings.cmake.in.i | Bin 0 -> 127 bytes .../store/data/_lib_variant_config.cmake.in.i | Bin 0 -> 705 bytes .../_lib_variant_config_version.cmake.in.i | Bin 0 -> 252 bytes .../src/.hg/store/data/_r_e_a_d_m_e.i | Bin 0 -> 1530 bytes .../src/.hg/store/data/_r_e_a_d_m_e.md.i | Bin 0 -> 2499 bytes .../cmake/_modules/_find_lib_y_a_m_l.cmake.i | Bin 0 -> 424 bytes .../cmake/_modules/_find_msg_pack.cmake.i | Bin 0 -> 376 bytes .../data/cmake/_modules/_make_t_b_z2.cmake.i | Bin 0 -> 330 bytes .../store/data/examples/_c_make_lists.txt.i | Bin 0 -> 242 bytes .../.hg/store/data/examples/_r_e_a_d_m_e.i | Bin 0 -> 366 bytes .../.hg/store/data/examples/arg__parse.cc.i | Bin 0 -> 1597 bytes .../src/.hg/store/data/examples/convert.cc.i | Bin 0 -> 943 bytes .../src/.hg/store/data/examples/example1.cc.i | Bin 0 -> 478 bytes .../src/.hg/store/data/examples/example2.cc.i | Bin 0 -> 716 bytes .../store/data/examples/list__example.cc.i | Bin 0 -> 503 bytes .../.hg/store/data/examples/map__example.cc.i | Bin 0 -> 703 bytes .../store/data/examples/pretty__print.cc.i | Bin 0 -> 641 bytes .../data/include/_variant/_arg_parse.h.i | Bin 0 -> 3922 bytes .../.hg/store/data/include/_variant/_blob.h.i | Bin 0 -> 770 bytes .../store/data/include/_variant/_emitter.h.i | Bin 0 -> 2203 bytes .../data/include/_variant/_emitter_output.h.i | Bin 0 -> 1081 bytes .../data/include/_variant/_exceptions.h.i | Bin 0 -> 1313 bytes .../data/include/_variant/_extensions.h.i | Bin 0 -> 1814 bytes .../data/include/_variant/_guess_format.h.i | Bin 0 -> 398 bytes .../store/data/include/_variant/_parser.h.i | Bin 0 -> 1590 bytes .../data/include/_variant/_parser_input.h.i | Bin 0 -> 1217 bytes .../.hg/store/data/include/_variant/_path.h.i | Bin 0 -> 1415 bytes .../store/data/include/_variant/_payload.h.i | Bin 0 -> 2192 bytes .../store/data/include/_variant/_schema.h.i | Bin 0 -> 2305 bytes .../data/include/_variant/_schema_loader.h.i | Bin 0 -> 1172 bytes .../data/include/_variant/_shared_ptr.h.i | Bin 0 -> 443 bytes .../store/data/include/_variant/_variant.h.i | Bin 0 -> 7339 bytes .../include/_variant/_variant_defines.h.i | Bin 0 -> 841 bytes .../include/_variant/_variant_internal.h.i | Bin 0 -> 1106 bytes ..._j_s_o_n___p_a_r_s_e_r___r_e_a_d_m_e.htm.i | Bin 0 -> 383 bytes .../store/data/lib/json/_j_s_o_n__parser.c.i | Bin 0 -> 7647 bytes .../store/data/lib/json/_j_s_o_n__parser.h.i | Bin 0 -> 1675 bytes .../src/.hg/store/data/libvariant.pc.in.i | Bin 0 -> 479 bytes .../src/.hg/store/data/src/_arg_parse.cc.i | Bin 0 -> 12164 bytes .../src/.hg/store/data/src/_base64.cc.i | Bin 0 -> 1471 bytes .../src/.hg/store/data/src/_base64.h.i | Bin 0 -> 493 bytes .../src/.hg/store/data/src/_blob.cc.i | Bin 0 -> 1026 bytes .../src/.hg/store/data/src/_blob_magic.h.i | Bin 0 -> 369 bytes .../store/data/src/_bundle_hdr_emitter.cc.i | Bin 0 -> 833 bytes .../store/data/src/_bundle_hdr_emitter.h.i | Bin 0 -> 1070 bytes .../store/data/src/_bundle_hdr_parser.cc.i | Bin 0 -> 1568 bytes .../.hg/store/data/src/_bundle_hdr_parser.h.i | Bin 0 -> 667 bytes .../.hg/store/data/src/_c_make_lists.txt.i | Bin 0 -> 590 bytes .../src/.hg/store/data/src/_emitter.cc.i | Bin 0 -> 1535 bytes .../.hg/store/data/src/_emitter_output.cc.i | Bin 0 -> 1201 bytes .../src/.hg/store/data/src/_event_buffer.cc.i | Bin 0 -> 1794 bytes .../src/.hg/store/data/src/_event_buffer.h.i | Bin 0 -> 2109 bytes .../src/.hg/store/data/src/_exceptions.cc.i | Bin 0 -> 1845 bytes .../src/.hg/store/data/src/_extensions.cc.i | Bin 0 -> 5387 bytes .../src/.hg/store/data/src/_guess_format.cc.i | Bin 0 -> 630 bytes .../src/.hg/store/data/src/_guess_scalar.cc.i | Bin 0 -> 1549 bytes .../src/.hg/store/data/src/_guess_scalar.h.i | Bin 0 -> 324 bytes .../.hg/store/data/src/_j_s_o_n_emitter.cc.i | Bin 0 -> 2317 bytes .../.hg/store/data/src/_j_s_o_n_emitter.h.i | Bin 0 -> 1398 bytes .../.hg/store/data/src/_j_s_o_n_parser.cc.i | Bin 0 -> 2094 bytes .../.hg/store/data/src/_j_s_o_n_parser.h.i | Bin 0 -> 1179 bytes .../.hg/store/data/src/_msg_pack_emitter.cc.i | Bin 0 -> 871 bytes .../.hg/store/data/src/_msg_pack_emitter.h.i | Bin 0 -> 543 bytes .../.hg/store/data/src/_msg_pack_parser.cc.i | Bin 0 -> 1436 bytes .../.hg/store/data/src/_msg_pack_parser.h.i | Bin 0 -> 544 bytes .../src/.hg/store/data/src/_parse_bool.cc.i | Bin 0 -> 890 bytes .../src/.hg/store/data/src/_parse_bool.h.i | Bin 0 -> 784 bytes .../src/.hg/store/data/src/_parser.cc.i | Bin 0 -> 1276 bytes .../src/.hg/store/data/src/_parser_input.cc.i | Bin 0 -> 1531 bytes .../src/.hg/store/data/src/_path.cc.i | Bin 0 -> 863 bytes .../src/.hg/store/data/src/_payload.cc.i | Bin 0 -> 2983 bytes .../src/.hg/store/data/src/_schema.cc.i | Bin 0 -> 6604 bytes .../.hg/store/data/src/_schema_loader.cc.i | Bin 0 -> 5488 bytes .../src/.hg/store/data/src/_stack_trace.cc.i | Bin 0 -> 874 bytes .../src/.hg/store/data/src/_stack_trace.h.i | Bin 0 -> 910 bytes .../src/.hg/store/data/src/_variant.cc.i | Bin 0 -> 10028 bytes .../.hg/store/data/src/_variant_emitting.cc.i | Bin 0 -> 1122 bytes .../.hg/store/data/src/_variant_parsing.cc.i | Bin 0 -> 2411 bytes .../store/data/src/_x_m_l_p_l_i_s_t_defs.h.i | Bin 0 -> 723 bytes .../data/src/_x_m_l_p_l_i_s_t_emitter.cc.i | Bin 0 -> 1794 bytes .../data/src/_x_m_l_p_l_i_s_t_emitter.h.i | Bin 0 -> 1547 bytes .../data/src/_x_m_l_p_l_i_s_t_parser.cc.i | Bin 0 -> 2690 bytes .../data/src/_x_m_l_p_l_i_s_t_parser.h.i | Bin 0 -> 1075 bytes .../.hg/store/data/src/_y_a_m_l_emitter.cc.i | Bin 0 -> 2670 bytes .../.hg/store/data/src/_y_a_m_l_emitter.h.i | Bin 0 -> 1789 bytes .../.hg/store/data/src/_y_a_m_l_parser.cc.i | Bin 0 -> 1960 bytes .../.hg/store/data/src/_y_a_m_l_parser.h.i | Bin 0 -> 879 bytes .../.hg/store/data/src/argparse-schema.cc.i | Bin 0 -> 1714 bytes .../.hg/store/data/src/argparse-schema.yaml.i | Bin 0 -> 735 bytes .../.hg/store/data/src/gen-argparse-schema.i | Bin 0 -> 323 bytes .../src/.hg/store/data/src/gen-json-schema.i | Bin 0 -> 271 bytes .../.hg/store/data/src/json-schema-v4.cc.i | Bin 0 -> 2298 bytes .../.hg/store/data/src/json-schema-v4.json.i | Bin 0 -> 777 bytes .../src/.hg/store/data/src/varsh.cc.i | Bin 0 -> 2806 bytes .../.hg/store/data/test/_c_make_lists.txt.i | Bin 0 -> 861 bytes .../src/.hg/store/data/test/_test_assert.h.i | Bin 0 -> 365 bytes .../src/.hg/store/data/test/_test_common.h.i | Bin 0 -> 1191 bytes .../.hg/store/data/test/prof__msgpack.cc.i | Bin 0 -> 1250 bytes .../.hg/store/data/test/rand__test__json.cc.i | Bin 0 -> 231 bytes .../store/data/test/rand__test__msgpack.cc.i | Bin 0 -> 233 bytes .../.hg/store/data/test/rand__test__xml.cc.i | Bin 0 -> 237 bytes .../.hg/store/data/test/rand__test__yaml.cc.i | Bin 0 -> 232 bytes .../.hg/store/data/test/test__argparse.cc.i | Bin 0 -> 2144 bytes .../store/data/test/test__argparse.sh.in.i | Bin 0 -> 1195 bytes .../data/test/test__argparse__merge.cc.i | Bin 0 -> 806 bytes .../src/.hg/store/data/test/test__base64.cc.i | Bin 0 -> 18626 bytes .../store/data/test/test__bundleemitter.cc.i | Bin 0 -> 983 bytes .../.hg/store/data/test/test__bundlehdr.cc.i | Bin 0 -> 610 bytes .../store/data/test/test__bundleparser.cc.i | Bin 0 -> 994 bytes .../src/.hg/store/data/test/test__empty.cc.i | Bin 0 -> 472 bytes .../.hg/store/data/test/test__extensions.cc.i | Bin 0 -> 3480 bytes .../src/.hg/store/data/test/test__guess.cc.i | Bin 0 -> 597 bytes .../store/data/test/test__json__parser.cc.i | Bin 0 -> 625 bytes .../.hg/store/data/test/test__loadall.cc.i | Bin 0 -> 387 bytes .../store/data/test/test__memoryoutput.cc.i | Bin 0 -> 398 bytes .../.hg/store/data/test/test__numerics.cc.i | Bin 0 -> 2013 bytes .../src/.hg/store/data/test/test__path.cc.i | Bin 0 -> 1468 bytes .../.hg/store/data/test/test__payload.cc.i | Bin 0 -> 1084 bytes .../.hg/store/data/test/test__roundtrip.cc.i | Bin 0 -> 667 bytes .../src/.hg/store/data/test/test__schema.cc.i | Bin 0 -> 2945 bytes .../test__schema__data/invalid-schema.test.i | Bin 0 -> 481 bytes .../test__schema__data/invalid__path.test.i | Bin 0 -> 273 bytes .../jsonschema-tests/_makefile.i | Bin 0 -> 171 bytes .../jsonschema-tests/_r_e_a_d_m_e.i | Bin 0 -> 778 bytes .../jsonschema-tests/additional_items.json.i | Bin 0 -> 484 bytes .../jsonschema-tests/additional_items.test.i | Bin 0 -> 420 bytes .../additional_properties.json.i | Bin 0 -> 420 bytes .../additional_properties.test.i | Bin 0 -> 364 bytes .../jsonschema-tests/all_of.json.i | Bin 0 -> 472 bytes .../jsonschema-tests/all_of.test.i | Bin 0 -> 418 bytes .../jsonschema-tests/any_of.json.i | Bin 0 -> 359 bytes .../jsonschema-tests/any_of.test.i | Bin 0 -> 296 bytes .../jsonschema-tests/convert.py.i | Bin 0 -> 246 bytes .../jsonschema-tests/definitions.json.i | Bin 0 -> 264 bytes .../jsonschema-tests/definitions.test.i | Bin 0 -> 220 bytes .../jsonschema-tests/dependencies.json.i | Bin 0 -> 455 bytes .../jsonschema-tests/dependencies.test.i | Bin 0 -> 404 bytes .../jsonschema-tests/enum.json.i | Bin 0 -> 308 bytes .../jsonschema-tests/enum.test.i | Bin 0 -> 267 bytes .../jsonschema-tests/items.json.i | Bin 0 -> 333 bytes .../jsonschema-tests/items.test.i | Bin 0 -> 278 bytes .../jsonschema-tests/max_items.json.i | Bin 0 -> 259 bytes .../jsonschema-tests/max_items.test.i | Bin 0 -> 223 bytes .../jsonschema-tests/max_length.json.i | Bin 0 -> 251 bytes .../jsonschema-tests/max_length.test.i | Bin 0 -> 214 bytes .../jsonschema-tests/max_properties.json.i | Bin 0 -> 272 bytes .../jsonschema-tests/max_properties.test.i | Bin 0 -> 234 bytes .../jsonschema-tests/maximum.json.i | Bin 0 -> 304 bytes .../jsonschema-tests/maximum.test.i | Bin 0 -> 267 bytes .../jsonschema-tests/min_items.json.i | Bin 0 -> 253 bytes .../jsonschema-tests/min_items.test.i | Bin 0 -> 216 bytes .../jsonschema-tests/min_length.json.i | Bin 0 -> 250 bytes .../jsonschema-tests/min_length.test.i | Bin 0 -> 213 bytes .../jsonschema-tests/min_properties.json.i | Bin 0 -> 266 bytes .../jsonschema-tests/min_properties.test.i | Bin 0 -> 224 bytes .../jsonschema-tests/minimum.json.i | Bin 0 -> 306 bytes .../jsonschema-tests/minimum.test.i | Bin 0 -> 273 bytes .../jsonschema-tests/multiple_of.json.i | Bin 0 -> 336 bytes .../jsonschema-tests/multiple_of.test.i | Bin 0 -> 294 bytes .../jsonschema-tests/not.json.i | Bin 0 -> 356 bytes .../jsonschema-tests/not.test.i | Bin 0 -> 299 bytes .../jsonschema-tests/one_of.json.i | Bin 0 -> 357 bytes .../jsonschema-tests/one_of.test.i | Bin 0 -> 293 bytes .../jsonschema-tests/pattern.json.i | Bin 0 -> 238 bytes .../jsonschema-tests/pattern.test.i | Bin 0 -> 209 bytes .../pattern_properties.json.i | Bin 0 -> 631 bytes .../pattern_properties.test.i | Bin 0 -> 562 bytes .../jsonschema-tests/properties.json.i | Bin 0 -> 507 bytes .../jsonschema-tests/properties.test.i | Bin 0 -> 473 bytes .../jsonschema-tests/ref.json.i | Bin 0 -> 584 bytes .../jsonschema-tests/ref.test.i | Bin 0 -> 513 bytes .../jsonschema-tests/required.json.i | Bin 0 -> 285 bytes .../jsonschema-tests/required.test.i | Bin 0 -> 235 bytes .../jsonschema-tests/type.json.i | Bin 0 -> 692 bytes .../jsonschema-tests/type.test.i | Bin 0 -> 781 bytes .../jsonschema-tests/unique_items.json.i | Bin 0 -> 459 bytes .../jsonschema-tests/unique_items.test.i | Bin 0 -> 411 bytes .../negative-unique-items.test.i | Bin 0 -> 196 bytes .../test/test__schema__data/recursion.test.i | Bin 0 -> 206 bytes .../test__schema__data/sample-test.test.i | Bin 0 -> 516 bytes .../simple-test-fail.json.i | Bin 0 -> 301 bytes .../simple-test-schema.json.i | Bin 0 -> 239 bytes .../test__schema__data/simple-test.json.i | Bin 0 -> 308 bytes .../test__resolveuri.json.i | Bin 0 -> 1679 bytes .../tv4-tests/01-any-type/01-type.test.i | Bin 0 -> 257 bytes .../tv4-tests/01-any-type/02-enum.test.i | Bin 0 -> 282 bytes .../tv4-tests/01-any-type/02-enum.yaml.i | Bin 0 -> 285 bytes .../tv4-tests/01-any-type/_makefile.i | Bin 0 -> 179 bytes .../tv4-tests/02-numeric/01-min-max.test.i | Bin 0 -> 236 bytes .../tv4-tests/02-numeric/01-min-max.yaml.i | Bin 0 -> 228 bytes .../02-numeric/02-multiple_of.test.i | Bin 0 -> 154 bytes .../02-numeric/02-multiple_of.yaml.i | Bin 0 -> 152 bytes .../tv4-tests/02-numeric/_makefile.i | Bin 0 -> 79 bytes .../03-strings/01-min-max-length.test.i | Bin 0 -> 215 bytes .../03-strings/01-min-max-length.yaml.i | Bin 0 -> 209 bytes .../tv4-tests/03-strings/02-pattern.test.i | Bin 0 -> 174 bytes .../tv4-tests/03-strings/02-pattern.yaml.i | Bin 0 -> 173 bytes .../tv4-tests/03-strings/_makefile.i | Bin 0 -> 79 bytes .../04-arrays/01-min-max-length.test.i | Bin 0 -> 219 bytes .../04-arrays/01-min-max-length.yaml.i | Bin 0 -> 214 bytes .../tv4-tests/04-arrays/02-uniqueitems.test.i | Bin 0 -> 169 bytes .../tv4-tests/04-arrays/02-uniqueitems.yaml.i | Bin 0 -> 168 bytes .../tv4-tests/04-arrays/03-items-plain.test.i | Bin 0 -> 181 bytes .../tv4-tests/04-arrays/03-items-plain.yaml.i | Bin 0 -> 178 bytes .../04-arrays/04-items-tuple-typing.test.i | Bin 0 -> 187 bytes .../04-arrays/04-items-tuple-typing.yaml.i | Bin 0 -> 189 bytes .../04-arrays/05-additionalitems.test.i | Bin 0 -> 236 bytes .../04-arrays/05-additionalitems.yaml.i | Bin 0 -> 239 bytes .../tv4-tests/04-arrays/_makefile.i | Bin 0 -> 79 bytes .../05-objects/01-min-max-properties.test.i | Bin 0 -> 208 bytes .../05-objects/01-min-max-properties.yaml.i | Bin 0 -> 203 bytes .../tv4-tests/05-objects/02-required.test.i | Bin 0 -> 186 bytes .../tv4-tests/05-objects/02-required.yaml.i | Bin 0 -> 184 bytes .../tv4-tests/05-objects/03-properties.test.i | Bin 0 -> 201 bytes .../tv4-tests/05-objects/03-properties.yaml.i | Bin 0 -> 205 bytes .../05-objects/04-patternproperties.test.i | Bin 0 -> 242 bytes .../05-objects/04-patternproperties.yaml.i | Bin 0 -> 249 bytes .../05-objects/05-additionalproperties.test.i | Bin 0 -> 284 bytes .../05-objects/05-additionalproperties.yaml.i | Bin 0 -> 284 bytes .../05-objects/06-dependencies.test.i | Bin 0 -> 240 bytes .../05-objects/06-dependencies.yaml.i | Bin 0 -> 242 bytes .../tv4-tests/05-objects/_makefile.i | Bin 0 -> 79 bytes .../06-combinations/01-all_of.test.i | Bin 0 -> 180 bytes .../06-combinations/01-all_of.yaml.i | Bin 0 -> 174 bytes .../06-combinations/02-any_of.test.i | Bin 0 -> 194 bytes .../06-combinations/02-any_of.yaml.i | Bin 0 -> 184 bytes .../06-combinations/03-one_of.test.i | Bin 0 -> 218 bytes .../06-combinations/03-one_of.yaml.i | Bin 0 -> 218 bytes .../tv4-tests/06-combinations/04-not.test.i | Bin 0 -> 165 bytes .../tv4-tests/06-combinations/04-not.yaml.i | Bin 0 -> 159 bytes .../tv4-tests/06-combinations/_makefile.i | Bin 0 -> 79 bytes .../tv4-tests/07-ref/04-ref.test.i | Bin 0 -> 195 bytes .../tv4-tests/07-ref/04-ref.yaml.i | Bin 0 -> 196 bytes .../07-ref/05-inline-addressing.test.i | Bin 0 -> 278 bytes .../07-ref/05-inline-addressing.yaml.i | Bin 0 -> 285 bytes .../tv4-tests/07-ref/_makefile.i | Bin 0 -> 79 bytes .../test__schema__data/tv4-tests/_makefile.i | Bin 0 -> 167 bytes .../tv4-tests/_r_e_a_d_m_e.i | Bin 0 -> 165 bytes .../tv4-tests/submakefile.i | Bin 0 -> 215 bytes .../.hg/store/data/test/test__variant.cc.i | Bin 0 -> 5043 bytes .../store/data/test/test__xml__parser.cc.i | Bin 0 -> 423 bytes .../store/data/test/test__yaml__parser.cc.i | Bin 0 -> 642 bytes .../src/.hg/store/data/~2ehgignore.i | Bin 0 -> 113 bytes .../src/.hg/store/data/~2ehgtags.i | Bin 0 -> 495 bytes src/hos_libvariant/src/.hg/store/fncache | 248 ++ src/hos_libvariant/src/.hg/store/phaseroots | 0 src/hos_libvariant/src/.hg/store/undo | Bin 0 -> 11658 bytes .../src/.hg/store/undo.phaseroots | 0 src/hos_libvariant/src/.hg/undo.bookmarks | 0 src/hos_libvariant/src/.hg/undo.branch | 1 + src/hos_libvariant/src/.hg/undo.desc | 3 + src/hos_libvariant/src/.hg/undo.dirstate | 0 src/hos_libvariant/src/.hgignore | 10 + src/hos_libvariant/src/.hgtags | 4 + src/hos_libvariant/src/CMakeLists.txt | 244 ++ src/hos_libvariant/src/Config.h.in | 13 + src/hos_libvariant/src/Doxyfile.in | 1569 ++++++++++++ src/hos_libvariant/src/LICENSE | 16 + .../src/LibVariantBuildTreeSettings.cmake.in | 3 + .../src/LibVariantConfig.cmake.in | 25 + .../src/LibVariantConfigVersion.cmake.in | 12 + src/hos_libvariant/src/README.md | 126 + .../src/cmake/Modules/FindLibYAML.cmake | 18 + .../src/cmake/Modules/FindMsgPack.cmake | 17 + .../src/cmake/Modules/MakeTBZ2.cmake | 13 + .../src/examples/CMakeLists.txt | 21 + src/hos_libvariant/src/examples/README | 23 + src/hos_libvariant/src/examples/arg_parse.cc | 101 + src/hos_libvariant/src/examples/convert.cc | 99 + src/hos_libvariant/src/examples/example1.cc | 37 + src/hos_libvariant/src/examples/example2.cc | 50 + .../src/examples/list_example.cc | 29 + .../src/examples/map_example.cc | 48 + .../src/examples/pretty_print.cc | 40 + .../src/include/Variant/ArgParse.h | 301 +++ src/hos_libvariant/src/include/Variant/Blob.h | 63 + .../src/include/Variant/Emitter.h | 226 ++ .../src/include/Variant/EmitterOutput.h | 87 + .../src/include/Variant/Exceptions.h | 88 + .../src/include/Variant/Extensions.h | 92 + .../src/include/Variant/GuessFormat.h | 23 + .../src/include/Variant/Parser.h | 158 ++ .../src/include/Variant/ParserInput.h | 104 + src/hos_libvariant/src/include/Variant/Path.h | 100 + .../src/include/Variant/Payload.h | 129 + .../src/include/Variant/Schema.h | 175 ++ .../src/include/Variant/SchemaLoader.h | 54 + .../src/include/Variant/SharedPtr.h | 41 + .../src/include/Variant/Variant.h | 816 ++++++ .../src/include/Variant/VariantDefines.h | 50 + .../src/include/Variant/VariantInternal.h | 95 + .../src/lib/json/JSON_PARSER_README.htm | 16 + src/hos_libvariant/src/lib/json/JSON_parser.c | 1013 ++++++++ src/hos_libvariant/src/lib/json/JSON_parser.h | 162 ++ src/hos_libvariant/src/libvariant.pc.in | 10 + src/hos_libvariant/src/src/ArgParse.cc | 1855 ++++++++++++++ src/hos_libvariant/src/src/Base64.cc | 160 ++ src/hos_libvariant/src/src/Base64.h | 24 + src/hos_libvariant/src/src/Blob.cc | 123 + src/hos_libvariant/src/src/BlobMagic.h | 20 + .../src/src/BundleHdrEmitter.cc | 126 + src/hos_libvariant/src/src/BundleHdrEmitter.h | 110 + src/hos_libvariant/src/src/BundleHdrParser.cc | 217 ++ src/hos_libvariant/src/src/BundleHdrParser.h | 66 + src/hos_libvariant/src/src/CMakeLists.txt | 60 + src/hos_libvariant/src/src/Emitter.cc | 219 ++ src/hos_libvariant/src/src/EmitterOutput.cc | 100 + src/hos_libvariant/src/src/EventBuffer.cc | 283 +++ src/hos_libvariant/src/src/EventBuffer.h | 269 ++ src/hos_libvariant/src/src/Exceptions.cc | 201 ++ src/hos_libvariant/src/src/Extensions.cc | 797 ++++++ src/hos_libvariant/src/src/GuessFormat.cc | 54 + src/hos_libvariant/src/src/GuessScalar.cc | 120 + src/hos_libvariant/src/src/GuessScalar.h | 14 + src/hos_libvariant/src/src/JSONEmitter.cc | 299 +++ src/hos_libvariant/src/src/JSONEmitter.h | 105 + src/hos_libvariant/src/src/JSONParser.cc | 214 ++ src/hos_libvariant/src/src/JSONParser.h | 90 + src/hos_libvariant/src/src/MsgPackEmitter.cc | 135 + src/hos_libvariant/src/src/MsgPackEmitter.h | 51 + src/hos_libvariant/src/src/MsgPackParser.cc | 250 ++ src/hos_libvariant/src/src/MsgPackParser.h | 49 + src/hos_libvariant/src/src/ParseBool.cc | 55 + src/hos_libvariant/src/src/ParseBool.h | 37 + src/hos_libvariant/src/src/Parser.cc | 127 + src/hos_libvariant/src/src/ParserInput.cc | 164 ++ src/hos_libvariant/src/src/Path.cc | 117 + src/hos_libvariant/src/src/Payload.cc | 347 +++ src/hos_libvariant/src/src/Schema.cc | 995 ++++++++ src/hos_libvariant/src/src/SchemaLoader.cc | 570 +++++ src/hos_libvariant/src/src/StackTrace.cc | 51 + src/hos_libvariant/src/src/StackTrace.h | 48 + src/hos_libvariant/src/src/Variant.cc | 2257 +++++++++++++++++ src/hos_libvariant/src/src/VariantEmitting.cc | 110 + src/hos_libvariant/src/src/VariantParsing.cc | 345 +++ src/hos_libvariant/src/src/XMLPLISTDefs.h | 37 + src/hos_libvariant/src/src/XMLPLISTEmitter.cc | 217 ++ src/hos_libvariant/src/src/XMLPLISTEmitter.h | 133 + src/hos_libvariant/src/src/XMLPLISTParser.cc | 423 +++ src/hos_libvariant/src/src/XMLPLISTParser.h | 81 + src/hos_libvariant/src/src/YAMLEmitter.cc | 410 +++ src/hos_libvariant/src/src/YAMLEmitter.h | 170 ++ src/hos_libvariant/src/src/YAMLParser.cc | 194 ++ src/hos_libvariant/src/src/YAMLParser.h | 62 + src/hos_libvariant/src/src/argparse-schema.cc | 184 ++ .../src/src/argparse-schema.yaml | 91 + .../src/src/gen-argparse-schema | 9 + src/hos_libvariant/src/src/gen-json-schema | 9 + src/hos_libvariant/src/src/json-schema-v4.cc | 371 +++ .../src/src/json-schema-v4.json | 150 ++ src/hos_libvariant/src/src/varsh.cc | 233 ++ src/hos_libvariant/src/test/CMakeLists.txt | 114 + src/hos_libvariant/src/test/TestAssert.h | 20 + src/hos_libvariant/src/test/TestCommon.h | 103 + src/hos_libvariant/src/test/prof_msgpack.cc | 129 + src/hos_libvariant/src/test/rand_test_json.cc | 12 + .../src/test/rand_test_msgpack.cc | 12 + src/hos_libvariant/src/test/rand_test_xml.cc | 11 + src/hos_libvariant/src/test/rand_test_yaml.cc | 11 + src/hos_libvariant/src/test/test_argparse.cc | 181 ++ .../src/test/test_argparse.sh.in | 104 + .../src/test/test_argparse_merge.cc | 109 + src/hos_libvariant/src/test/test_base64.cc | 1032 ++++++++ .../src/test/test_bundleemitter.cc | 95 + src/hos_libvariant/src/test/test_bundlehdr.cc | 49 + .../src/test/test_bundleparser.cc | 93 + src/hos_libvariant/src/test/test_empty.cc | 56 + .../src/test/test_extensions.cc | 678 +++++ src/hos_libvariant/src/test/test_guess.cc | 48 + .../src/test/test_json_parser.cc | 55 + src/hos_libvariant/src/test/test_loadall.cc | 33 + .../src/test/test_memoryoutput.cc | 29 + src/hos_libvariant/src/test/test_numerics.cc | 327 +++ src/hos_libvariant/src/test/test_path.cc | 230 ++ src/hos_libvariant/src/test/test_payload.cc | 121 + src/hos_libvariant/src/test/test_roundtrip.cc | 90 + src/hos_libvariant/src/test/test_schema.cc | 410 +++ .../test/test_schema_data/invalid-schema.test | 168 ++ .../test/test_schema_data/invalid_path.test | 34 + .../jsonschema-tests/Makefile | 7 + .../test_schema_data/jsonschema-tests/README | 26 + .../jsonschema-tests/additionalItems.json | 82 + .../jsonschema-tests/additionalItems.test | 1 + .../additionalProperties.json | 63 + .../additionalProperties.test | 1 + .../jsonschema-tests/allOf.json | 112 + .../jsonschema-tests/allOf.test | 1 + .../jsonschema-tests/anyOf.json | 68 + .../jsonschema-tests/anyOf.test | 1 + .../jsonschema-tests/convert.py | 16 + .../jsonschema-tests/definitions.json | 32 + .../jsonschema-tests/definitions.test | 1 + .../jsonschema-tests/dependencies.json | 113 + .../jsonschema-tests/dependencies.test | 1 + .../jsonschema-tests/enum.json | 39 + .../jsonschema-tests/enum.test | 1 + .../jsonschema-tests/items.json | 46 + .../jsonschema-tests/items.test | 1 + .../jsonschema-tests/maxItems.json | 28 + .../jsonschema-tests/maxItems.test | 1 + .../jsonschema-tests/maxLength.json | 28 + .../jsonschema-tests/maxLength.test | 1 + .../jsonschema-tests/maxProperties.json | 28 + .../jsonschema-tests/maxProperties.test | 1 + .../jsonschema-tests/maximum.json | 42 + .../jsonschema-tests/maximum.test | 1 + .../jsonschema-tests/minItems.json | 28 + .../jsonschema-tests/minItems.test | 1 + .../jsonschema-tests/minLength.json | 28 + .../jsonschema-tests/minLength.test | 1 + .../jsonschema-tests/minProperties.json | 28 + .../jsonschema-tests/minProperties.test | 1 + .../jsonschema-tests/minimum.json | 42 + .../jsonschema-tests/minimum.test | 1 + .../jsonschema-tests/multipleOf.json | 60 + .../jsonschema-tests/multipleOf.test | 1 + .../jsonschema-tests/not.json | 73 + .../jsonschema-tests/not.test | 1 + .../jsonschema-tests/oneOf.json | 68 + .../jsonschema-tests/oneOf.test | 1 + .../jsonschema-tests/pattern.json | 23 + .../jsonschema-tests/pattern.test | 1 + .../jsonschema-tests/patternProperties.json | 110 + .../jsonschema-tests/patternProperties.test | 1 + .../jsonschema-tests/properties.json | 92 + .../jsonschema-tests/properties.test | 1 + .../jsonschema-tests/ref.json | 123 + .../jsonschema-tests/ref.test | 1 + .../jsonschema-tests/required.json | 39 + .../jsonschema-tests/required.test | 1 + .../jsonschema-tests/type.json | 330 +++ .../jsonschema-tests/type.test | 1 + .../jsonschema-tests/uniqueItems.json | 79 + .../jsonschema-tests/uniqueItems.test | 1 + .../negative-unique-items.test | 19 + .../src/test/test_schema_data/recursion.test | 16 + .../test/test_schema_data/sample-test.test | 78 + .../test_schema_data/simple-test-fail.json | 13 + .../test_schema_data/simple-test-schema.json | 20 + .../test/test_schema_data/simple-test.json | 14 + .../test_schema_data/test_resolveuri.json | 203 ++ .../tv4-tests/01-any-type/01-type.test | 46 + .../tv4-tests/01-any-type/02-enum.test | 1 + .../tv4-tests/01-any-type/02-enum.yaml | 30 + .../tv4-tests/01-any-type/Makefile | 5 + .../tv4-tests/02-numeric/01-min-max.test | 1 + .../tv4-tests/02-numeric/01-min-max.yaml | 28 + .../tv4-tests/02-numeric/02-multipleOf.test | 1 + .../tv4-tests/02-numeric/02-multipleOf.yaml | 7 + .../tv4-tests/02-numeric/Makefile | 9 + .../03-strings/01-min-max-length.test | 1 + .../03-strings/01-min-max-length.yaml | 17 + .../tv4-tests/03-strings/02-pattern.test | 1 + .../tv4-tests/03-strings/02-pattern.yaml | 7 + .../tv4-tests/03-strings/Makefile | 9 + .../04-arrays/01-min-max-length.test | 1 + .../04-arrays/01-min-max-length.yaml | 17 + .../tv4-tests/04-arrays/02-uniqueitems.test | 1 + .../tv4-tests/04-arrays/02-uniqueitems.yaml | 7 + .../tv4-tests/04-arrays/03-items-plain.test | 1 + .../tv4-tests/04-arrays/03-items-plain.yaml | 7 + .../04-arrays/04-items-tuple-typing.test | 1 + .../04-arrays/04-items-tuple-typing.yaml | 7 + .../04-arrays/05-additionalitems.test | 1 + .../04-arrays/05-additionalitems.yaml | 31 + .../tv4-tests/04-arrays/Makefile | 9 + .../05-objects/01-min-max-properties.test | 1 + .../05-objects/01-min-max-properties.yaml | 14 + .../tv4-tests/05-objects/02-required.test | 1 + .../tv4-tests/05-objects/02-required.yaml | 7 + .../tv4-tests/05-objects/03-properties.test | 1 + .../tv4-tests/05-objects/03-properties.yaml | 13 + .../05-objects/04-patternproperties.test | 1 + .../05-objects/04-patternproperties.yaml | 23 + .../05-objects/05-additionalproperties.test | 1 + .../05-objects/05-additionalproperties.yaml | 34 + .../tv4-tests/05-objects/06-dependencies.test | 1 + .../tv4-tests/05-objects/06-dependencies.yaml | 21 + .../tv4-tests/05-objects/Makefile | 9 + .../tv4-tests/06-combinations/01-allOf.test | 1 + .../tv4-tests/06-combinations/01-allOf.yaml | 13 + .../tv4-tests/06-combinations/02-anyOf.test | 1 + .../tv4-tests/06-combinations/02-anyOf.yaml | 14 + .../tv4-tests/06-combinations/03-oneOf.test | 1 + .../tv4-tests/06-combinations/03-oneOf.yaml | 23 + .../tv4-tests/06-combinations/04-not.test | 1 + .../tv4-tests/06-combinations/04-not.yaml | 11 + .../tv4-tests/06-combinations/Makefile | 9 + .../tv4-tests/07-ref/04-ref.test | 1 + .../tv4-tests/07-ref/04-ref.yaml | 12 + .../07-ref/05-inline-addressing.test | 1 + .../07-ref/05-inline-addressing.yaml | 20 + .../tv4-tests/07-ref/Makefile | 9 + .../test/test_schema_data/tv4-tests/Makefile | 11 + .../test/test_schema_data/tv4-tests/README | 4 + .../test_schema_data/tv4-tests/submakefile | 9 + src/hos_libvariant/src/test/test_variant.cc | 744 ++++++ .../src/test/test_xml_parser.cc | 32 + .../src/test/test_yaml_parser.cc | 64 + .../python/hos_huecontroller/huecontroller.py | 2 +- 547 files changed, 31680 insertions(+), 33 deletions(-) create mode 100644 src/hos_cosgi_core/CMakeLists.txt create mode 100644 src/hos_cosgi_core/include/hos_cosgi_core/cosgi_core.h create mode 100644 src/hos_cosgi_core/package.xml create mode 100644 src/hos_libvariant/CMakeLists.txt create mode 100644 src/hos_libvariant/include/hos_libvariant/ArgParse.h create mode 100644 src/hos_libvariant/include/hos_libvariant/Blob.h create mode 100644 src/hos_libvariant/include/hos_libvariant/Config.h create mode 100644 src/hos_libvariant/include/hos_libvariant/Emitter.h create mode 100644 src/hos_libvariant/include/hos_libvariant/EmitterOutput.h create mode 100644 src/hos_libvariant/include/hos_libvariant/Exceptions.h create mode 100644 src/hos_libvariant/include/hos_libvariant/Extensions.h create mode 100644 src/hos_libvariant/include/hos_libvariant/GuessFormat.h create mode 100644 src/hos_libvariant/include/hos_libvariant/Parser.h create mode 100644 src/hos_libvariant/include/hos_libvariant/ParserInput.h create mode 100644 src/hos_libvariant/include/hos_libvariant/Path.h create mode 100644 src/hos_libvariant/include/hos_libvariant/Payload.h create mode 100644 src/hos_libvariant/include/hos_libvariant/Schema.h create mode 100644 src/hos_libvariant/include/hos_libvariant/SchemaLoader.h create mode 100644 src/hos_libvariant/include/hos_libvariant/SharedPtr.h create mode 100644 src/hos_libvariant/include/hos_libvariant/Variant.h create mode 100644 src/hos_libvariant/include/hos_libvariant/VariantDefines.h create mode 100644 src/hos_libvariant/include/hos_libvariant/VariantInternal.h create mode 100644 src/hos_libvariant/package.xml create mode 100644 src/hos_libvariant/src/.hg/00changelog.i create mode 100644 src/hos_libvariant/src/.hg/branch create mode 100644 src/hos_libvariant/src/.hg/cache/branch2-served create mode 100644 src/hos_libvariant/src/.hg/dirstate create mode 100644 src/hos_libvariant/src/.hg/hgrc create mode 100644 src/hos_libvariant/src/.hg/requires create mode 100644 src/hos_libvariant/src/.hg/store/00changelog.i create mode 100644 src/hos_libvariant/src/.hg/store/00manifest.i create mode 100644 src/hos_libvariant/src/.hg/store/data/_c_make_lists.txt.i create mode 100644 src/hos_libvariant/src/.hg/store/data/_config.h.in.i create mode 100644 src/hos_libvariant/src/.hg/store/data/_doxyfile.in.i create mode 100644 src/hos_libvariant/src/.hg/store/data/_l_i_c_e_n_s_e.i create mode 100644 src/hos_libvariant/src/.hg/store/data/_lib_variant_build_tree_settings.cmake.in.i create mode 100644 src/hos_libvariant/src/.hg/store/data/_lib_variant_config.cmake.in.i create mode 100644 src/hos_libvariant/src/.hg/store/data/_lib_variant_config_version.cmake.in.i create mode 100644 src/hos_libvariant/src/.hg/store/data/_r_e_a_d_m_e.i create mode 100644 src/hos_libvariant/src/.hg/store/data/_r_e_a_d_m_e.md.i create mode 100644 src/hos_libvariant/src/.hg/store/data/cmake/_modules/_find_lib_y_a_m_l.cmake.i create mode 100644 src/hos_libvariant/src/.hg/store/data/cmake/_modules/_find_msg_pack.cmake.i create mode 100644 src/hos_libvariant/src/.hg/store/data/cmake/_modules/_make_t_b_z2.cmake.i create mode 100644 src/hos_libvariant/src/.hg/store/data/examples/_c_make_lists.txt.i create mode 100644 src/hos_libvariant/src/.hg/store/data/examples/_r_e_a_d_m_e.i create mode 100644 src/hos_libvariant/src/.hg/store/data/examples/arg__parse.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/examples/convert.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/examples/example1.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/examples/example2.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/examples/list__example.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/examples/map__example.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/examples/pretty__print.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_arg_parse.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_blob.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_emitter.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_emitter_output.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_exceptions.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_extensions.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_guess_format.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_parser.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_parser_input.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_path.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_payload.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_schema.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_schema_loader.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_shared_ptr.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_variant.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_variant_defines.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/include/_variant/_variant_internal.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/lib/json/_j_s_o_n___p_a_r_s_e_r___r_e_a_d_m_e.htm.i create mode 100644 src/hos_libvariant/src/.hg/store/data/lib/json/_j_s_o_n__parser.c.i create mode 100644 src/hos_libvariant/src/.hg/store/data/lib/json/_j_s_o_n__parser.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/libvariant.pc.in.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_arg_parse.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_base64.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_base64.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_blob.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_blob_magic.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_bundle_hdr_emitter.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_bundle_hdr_emitter.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_bundle_hdr_parser.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_bundle_hdr_parser.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_c_make_lists.txt.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_emitter.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_emitter_output.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_event_buffer.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_event_buffer.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_exceptions.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_extensions.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_guess_format.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_guess_scalar.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_guess_scalar.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_j_s_o_n_emitter.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_j_s_o_n_emitter.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_j_s_o_n_parser.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_j_s_o_n_parser.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_msg_pack_emitter.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_msg_pack_emitter.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_msg_pack_parser.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_msg_pack_parser.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_parse_bool.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_parse_bool.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_parser.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_parser_input.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_path.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_payload.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_schema.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_schema_loader.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_stack_trace.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_stack_trace.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_variant.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_variant_emitting.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_variant_parsing.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_x_m_l_p_l_i_s_t_defs.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_x_m_l_p_l_i_s_t_emitter.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_x_m_l_p_l_i_s_t_emitter.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_x_m_l_p_l_i_s_t_parser.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_x_m_l_p_l_i_s_t_parser.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_y_a_m_l_emitter.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_y_a_m_l_emitter.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_y_a_m_l_parser.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/_y_a_m_l_parser.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/argparse-schema.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/argparse-schema.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/gen-argparse-schema.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/gen-json-schema.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/json-schema-v4.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/json-schema-v4.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/src/varsh.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/_c_make_lists.txt.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/_test_assert.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/_test_common.h.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/prof__msgpack.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/rand__test__json.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/rand__test__msgpack.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/rand__test__xml.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/rand__test__yaml.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__argparse.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__argparse.sh.in.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__argparse__merge.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__base64.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__bundleemitter.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__bundlehdr.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__bundleparser.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__empty.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__extensions.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__guess.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__json__parser.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__loadall.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__memoryoutput.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__numerics.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__path.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__payload.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__roundtrip.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/invalid-schema.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/invalid__path.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/_makefile.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/_r_e_a_d_m_e.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/additional_items.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/additional_items.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/additional_properties.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/additional_properties.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/all_of.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/all_of.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/any_of.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/any_of.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/convert.py.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/definitions.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/definitions.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/dependencies.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/dependencies.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/enum.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/enum.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/items.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/items.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_items.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_items.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_length.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_length.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_properties.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_properties.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/maximum.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/maximum.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_items.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_items.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_length.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_length.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_properties.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_properties.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/minimum.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/minimum.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/multiple_of.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/multiple_of.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/not.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/not.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/one_of.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/one_of.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/pattern.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/pattern.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/pattern_properties.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/pattern_properties.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/properties.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/properties.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/ref.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/ref.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/required.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/required.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/type.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/type.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/unique_items.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/unique_items.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/negative-unique-items.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/recursion.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/sample-test.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/simple-test-fail.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/simple-test-schema.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/simple-test.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/test__resolveuri.json.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/01-any-type/01-type.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/01-any-type/02-enum.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/01-any-type/02-enum.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/01-any-type/_makefile.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/02-numeric/01-min-max.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/02-numeric/01-min-max.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/02-numeric/02-multiple_of.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/02-numeric/02-multiple_of.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/02-numeric/_makefile.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/03-strings/01-min-max-length.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/03-strings/01-min-max-length.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/03-strings/02-pattern.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/03-strings/02-pattern.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/03-strings/_makefile.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/01-min-max-length.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/01-min-max-length.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/02-uniqueitems.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/02-uniqueitems.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/03-items-plain.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/03-items-plain.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/04-items-tuple-typing.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/04-items-tuple-typing.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/05-additionalitems.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/05-additionalitems.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/_makefile.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/01-min-max-properties.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/01-min-max-properties.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/02-required.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/02-required.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/03-properties.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/03-properties.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/04-patternproperties.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/04-patternproperties.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/05-additionalproperties.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/05-additionalproperties.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/06-dependencies.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/06-dependencies.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/_makefile.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/01-all_of.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/01-all_of.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/02-any_of.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/02-any_of.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/03-one_of.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/03-one_of.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/04-not.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/04-not.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/_makefile.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/07-ref/04-ref.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/07-ref/04-ref.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/07-ref/05-inline-addressing.test.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/07-ref/05-inline-addressing.yaml.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/07-ref/_makefile.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/_makefile.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/_r_e_a_d_m_e.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/submakefile.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__variant.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__xml__parser.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/test/test__yaml__parser.cc.i create mode 100644 src/hos_libvariant/src/.hg/store/data/~2ehgignore.i create mode 100644 src/hos_libvariant/src/.hg/store/data/~2ehgtags.i create mode 100644 src/hos_libvariant/src/.hg/store/fncache create mode 100644 src/hos_libvariant/src/.hg/store/phaseroots create mode 100644 src/hos_libvariant/src/.hg/store/undo create mode 100644 src/hos_libvariant/src/.hg/store/undo.phaseroots create mode 100644 src/hos_libvariant/src/.hg/undo.bookmarks create mode 100644 src/hos_libvariant/src/.hg/undo.branch create mode 100644 src/hos_libvariant/src/.hg/undo.desc create mode 100644 src/hos_libvariant/src/.hg/undo.dirstate create mode 100644 src/hos_libvariant/src/.hgignore create mode 100644 src/hos_libvariant/src/.hgtags create mode 100644 src/hos_libvariant/src/CMakeLists.txt create mode 100644 src/hos_libvariant/src/Config.h.in create mode 100644 src/hos_libvariant/src/Doxyfile.in create mode 100644 src/hos_libvariant/src/LICENSE create mode 100644 src/hos_libvariant/src/LibVariantBuildTreeSettings.cmake.in create mode 100644 src/hos_libvariant/src/LibVariantConfig.cmake.in create mode 100644 src/hos_libvariant/src/LibVariantConfigVersion.cmake.in create mode 100644 src/hos_libvariant/src/README.md create mode 100644 src/hos_libvariant/src/cmake/Modules/FindLibYAML.cmake create mode 100644 src/hos_libvariant/src/cmake/Modules/FindMsgPack.cmake create mode 100644 src/hos_libvariant/src/cmake/Modules/MakeTBZ2.cmake create mode 100644 src/hos_libvariant/src/examples/CMakeLists.txt create mode 100644 src/hos_libvariant/src/examples/README create mode 100644 src/hos_libvariant/src/examples/arg_parse.cc create mode 100644 src/hos_libvariant/src/examples/convert.cc create mode 100644 src/hos_libvariant/src/examples/example1.cc create mode 100644 src/hos_libvariant/src/examples/example2.cc create mode 100644 src/hos_libvariant/src/examples/list_example.cc create mode 100644 src/hos_libvariant/src/examples/map_example.cc create mode 100644 src/hos_libvariant/src/examples/pretty_print.cc create mode 100644 src/hos_libvariant/src/include/Variant/ArgParse.h create mode 100644 src/hos_libvariant/src/include/Variant/Blob.h create mode 100644 src/hos_libvariant/src/include/Variant/Emitter.h create mode 100644 src/hos_libvariant/src/include/Variant/EmitterOutput.h create mode 100644 src/hos_libvariant/src/include/Variant/Exceptions.h create mode 100644 src/hos_libvariant/src/include/Variant/Extensions.h create mode 100644 src/hos_libvariant/src/include/Variant/GuessFormat.h create mode 100644 src/hos_libvariant/src/include/Variant/Parser.h create mode 100644 src/hos_libvariant/src/include/Variant/ParserInput.h create mode 100644 src/hos_libvariant/src/include/Variant/Path.h create mode 100644 src/hos_libvariant/src/include/Variant/Payload.h create mode 100644 src/hos_libvariant/src/include/Variant/Schema.h create mode 100644 src/hos_libvariant/src/include/Variant/SchemaLoader.h create mode 100644 src/hos_libvariant/src/include/Variant/SharedPtr.h create mode 100644 src/hos_libvariant/src/include/Variant/Variant.h create mode 100644 src/hos_libvariant/src/include/Variant/VariantDefines.h create mode 100644 src/hos_libvariant/src/include/Variant/VariantInternal.h create mode 100644 src/hos_libvariant/src/lib/json/JSON_PARSER_README.htm create mode 100644 src/hos_libvariant/src/lib/json/JSON_parser.c create mode 100644 src/hos_libvariant/src/lib/json/JSON_parser.h create mode 100644 src/hos_libvariant/src/libvariant.pc.in create mode 100644 src/hos_libvariant/src/src/ArgParse.cc create mode 100644 src/hos_libvariant/src/src/Base64.cc create mode 100644 src/hos_libvariant/src/src/Base64.h create mode 100644 src/hos_libvariant/src/src/Blob.cc create mode 100644 src/hos_libvariant/src/src/BlobMagic.h create mode 100644 src/hos_libvariant/src/src/BundleHdrEmitter.cc create mode 100644 src/hos_libvariant/src/src/BundleHdrEmitter.h create mode 100644 src/hos_libvariant/src/src/BundleHdrParser.cc create mode 100644 src/hos_libvariant/src/src/BundleHdrParser.h create mode 100644 src/hos_libvariant/src/src/CMakeLists.txt create mode 100644 src/hos_libvariant/src/src/Emitter.cc create mode 100644 src/hos_libvariant/src/src/EmitterOutput.cc create mode 100644 src/hos_libvariant/src/src/EventBuffer.cc create mode 100644 src/hos_libvariant/src/src/EventBuffer.h create mode 100644 src/hos_libvariant/src/src/Exceptions.cc create mode 100644 src/hos_libvariant/src/src/Extensions.cc create mode 100644 src/hos_libvariant/src/src/GuessFormat.cc create mode 100644 src/hos_libvariant/src/src/GuessScalar.cc create mode 100644 src/hos_libvariant/src/src/GuessScalar.h create mode 100644 src/hos_libvariant/src/src/JSONEmitter.cc create mode 100644 src/hos_libvariant/src/src/JSONEmitter.h create mode 100644 src/hos_libvariant/src/src/JSONParser.cc create mode 100644 src/hos_libvariant/src/src/JSONParser.h create mode 100644 src/hos_libvariant/src/src/MsgPackEmitter.cc create mode 100644 src/hos_libvariant/src/src/MsgPackEmitter.h create mode 100644 src/hos_libvariant/src/src/MsgPackParser.cc create mode 100644 src/hos_libvariant/src/src/MsgPackParser.h create mode 100644 src/hos_libvariant/src/src/ParseBool.cc create mode 100644 src/hos_libvariant/src/src/ParseBool.h create mode 100644 src/hos_libvariant/src/src/Parser.cc create mode 100644 src/hos_libvariant/src/src/ParserInput.cc create mode 100644 src/hos_libvariant/src/src/Path.cc create mode 100644 src/hos_libvariant/src/src/Payload.cc create mode 100644 src/hos_libvariant/src/src/Schema.cc create mode 100644 src/hos_libvariant/src/src/SchemaLoader.cc create mode 100644 src/hos_libvariant/src/src/StackTrace.cc create mode 100644 src/hos_libvariant/src/src/StackTrace.h create mode 100644 src/hos_libvariant/src/src/Variant.cc create mode 100644 src/hos_libvariant/src/src/VariantEmitting.cc create mode 100644 src/hos_libvariant/src/src/VariantParsing.cc create mode 100644 src/hos_libvariant/src/src/XMLPLISTDefs.h create mode 100644 src/hos_libvariant/src/src/XMLPLISTEmitter.cc create mode 100644 src/hos_libvariant/src/src/XMLPLISTEmitter.h create mode 100644 src/hos_libvariant/src/src/XMLPLISTParser.cc create mode 100644 src/hos_libvariant/src/src/XMLPLISTParser.h create mode 100644 src/hos_libvariant/src/src/YAMLEmitter.cc create mode 100644 src/hos_libvariant/src/src/YAMLEmitter.h create mode 100644 src/hos_libvariant/src/src/YAMLParser.cc create mode 100644 src/hos_libvariant/src/src/YAMLParser.h create mode 100644 src/hos_libvariant/src/src/argparse-schema.cc create mode 100644 src/hos_libvariant/src/src/argparse-schema.yaml create mode 100644 src/hos_libvariant/src/src/gen-argparse-schema create mode 100644 src/hos_libvariant/src/src/gen-json-schema create mode 100644 src/hos_libvariant/src/src/json-schema-v4.cc create mode 100644 src/hos_libvariant/src/src/json-schema-v4.json create mode 100644 src/hos_libvariant/src/src/varsh.cc create mode 100644 src/hos_libvariant/src/test/CMakeLists.txt create mode 100644 src/hos_libvariant/src/test/TestAssert.h create mode 100644 src/hos_libvariant/src/test/TestCommon.h create mode 100644 src/hos_libvariant/src/test/prof_msgpack.cc create mode 100644 src/hos_libvariant/src/test/rand_test_json.cc create mode 100644 src/hos_libvariant/src/test/rand_test_msgpack.cc create mode 100644 src/hos_libvariant/src/test/rand_test_xml.cc create mode 100644 src/hos_libvariant/src/test/rand_test_yaml.cc create mode 100644 src/hos_libvariant/src/test/test_argparse.cc create mode 100644 src/hos_libvariant/src/test/test_argparse.sh.in create mode 100644 src/hos_libvariant/src/test/test_argparse_merge.cc create mode 100644 src/hos_libvariant/src/test/test_base64.cc create mode 100644 src/hos_libvariant/src/test/test_bundleemitter.cc create mode 100644 src/hos_libvariant/src/test/test_bundlehdr.cc create mode 100644 src/hos_libvariant/src/test/test_bundleparser.cc create mode 100644 src/hos_libvariant/src/test/test_empty.cc create mode 100644 src/hos_libvariant/src/test/test_extensions.cc create mode 100644 src/hos_libvariant/src/test/test_guess.cc create mode 100644 src/hos_libvariant/src/test/test_json_parser.cc create mode 100644 src/hos_libvariant/src/test/test_loadall.cc create mode 100644 src/hos_libvariant/src/test/test_memoryoutput.cc create mode 100644 src/hos_libvariant/src/test/test_numerics.cc create mode 100644 src/hos_libvariant/src/test/test_path.cc create mode 100644 src/hos_libvariant/src/test/test_payload.cc create mode 100644 src/hos_libvariant/src/test/test_roundtrip.cc create mode 100644 src/hos_libvariant/src/test/test_schema.cc create mode 100644 src/hos_libvariant/src/test/test_schema_data/invalid-schema.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/invalid_path.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/Makefile create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/README create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalItems.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalItems.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalProperties.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalProperties.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/allOf.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/allOf.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/anyOf.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/anyOf.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/convert.py create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/definitions.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/definitions.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/dependencies.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/dependencies.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/enum.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/enum.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/items.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/items.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxItems.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxItems.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxLength.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxLength.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxProperties.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxProperties.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maximum.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maximum.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minItems.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minItems.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minLength.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minLength.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minProperties.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minProperties.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minimum.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minimum.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/multipleOf.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/multipleOf.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/not.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/not.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/oneOf.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/oneOf.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/pattern.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/pattern.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/patternProperties.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/patternProperties.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/properties.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/properties.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/ref.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/ref.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/required.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/required.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/type.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/type.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/uniqueItems.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/uniqueItems.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/negative-unique-items.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/recursion.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/sample-test.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/simple-test-fail.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/simple-test-schema.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/simple-test.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/test_resolveuri.json create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/01-type.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/02-enum.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/02-enum.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/Makefile create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/01-min-max.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/01-min-max.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/02-multipleOf.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/02-multipleOf.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/Makefile create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/01-min-max-length.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/01-min-max-length.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/02-pattern.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/02-pattern.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/Makefile create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/01-min-max-length.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/01-min-max-length.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/02-uniqueitems.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/02-uniqueitems.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/03-items-plain.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/03-items-plain.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/04-items-tuple-typing.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/04-items-tuple-typing.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/05-additionalitems.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/05-additionalitems.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/Makefile create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/01-min-max-properties.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/01-min-max-properties.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/02-required.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/02-required.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/03-properties.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/03-properties.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/04-patternproperties.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/04-patternproperties.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/05-additionalproperties.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/05-additionalproperties.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/06-dependencies.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/06-dependencies.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/Makefile create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/01-allOf.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/01-allOf.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/02-anyOf.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/02-anyOf.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/03-oneOf.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/03-oneOf.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/04-not.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/04-not.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/Makefile create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/04-ref.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/04-ref.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/05-inline-addressing.test create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/05-inline-addressing.yaml create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/Makefile create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/Makefile create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/README create mode 100644 src/hos_libvariant/src/test/test_schema_data/tv4-tests/submakefile create mode 100644 src/hos_libvariant/src/test/test_variant.cc create mode 100644 src/hos_libvariant/src/test/test_xml_parser.cc create mode 100644 src/hos_libvariant/src/test/test_yaml_parser.cc diff --git a/src/hos_celix/CMakeLists.txt b/src/hos_celix/CMakeLists.txt index fc3c5de1..64f971b3 100644 --- a/src/hos_celix/CMakeLists.txt +++ b/src/hos_celix/CMakeLists.txt @@ -95,6 +95,7 @@ ExternalProject_Add( celix_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src CONFIGURE_COMMAND cmake ${CMAKE_CURRENT_SOURCE_DIR}/src -DCMAKE_INSTALL_PREFIX=${CATKIN_DEVEL_PREFIX} + -DBUILD_SHARED_LIBS=TRUE -DBUILD_FRAMEWORK=TRUE -DBUILD_LAUNCHER=TRUE -DBUILD_UTILS=TRUE diff --git a/src/hos_cosgi_core/CMakeLists.txt b/src/hos_cosgi_core/CMakeLists.txt new file mode 100644 index 00000000..cdb3bbf3 --- /dev/null +++ b/src/hos_cosgi_core/CMakeLists.txt @@ -0,0 +1,161 @@ +cmake_minimum_required(VERSION 2.8.3) +project(hos_cosgi_core) + +## Find catkin macros and libraries +## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) +## is used, also find other catkin packages +find_package(catkin REQUIRED COMPONENTS + hos_celix +) + +## System dependencies are found with CMake's conventions +# find_package(Boost REQUIRED COMPONENTS system) + + +## Uncomment this if the package has a setup.py. This macro ensures +## modules and global scripts declared therein get installed +## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html +# catkin_python_setup() + +################################################ +## Declare ROS messages, services and actions ## +################################################ + +## To declare and build messages, services or actions from within this +## package, follow these steps: +## * Let MSG_DEP_SET be the set of packages whose message types you use in +## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). +## * In the file package.xml: +## * add a build_depend and a run_depend tag for each package in MSG_DEP_SET +## * If MSG_DEP_SET isn't empty the following dependencies might have been +## pulled in transitively but can be declared for certainty nonetheless: +## * add a build_depend tag for "message_generation" +## * add a run_depend tag for "message_runtime" +## * In this file (CMakeLists.txt): +## * add "message_generation" and every package in MSG_DEP_SET to +## find_package(catkin REQUIRED COMPONENTS ...) +## * add "message_runtime" and every package in MSG_DEP_SET to +## catkin_package(CATKIN_DEPENDS ...) +## * uncomment the add_*_files sections below as needed +## and list every .msg/.srv/.action file to be processed +## * uncomment the generate_messages entry below +## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) + +## Generate messages in the 'msg' folder +# add_message_files( +# FILES +# Message1.msg +# Message2.msg +# ) + +## Generate services in the 'srv' folder +# add_service_files( +# FILES +# Service1.srv +# Service2.srv +# ) + +## Generate actions in the 'action' folder +# add_action_files( +# FILES +# Action1.action +# Action2.action +# ) + +## Generate added messages and services with any dependencies listed here +# generate_messages( +# DEPENDENCIES +# std_msgs # Or other packages containing msgs +# ) + +################################### +## catkin specific configuration ## +################################### +## The catkin_package macro generates cmake config files for your package +## Declare things to be passed to dependent projects +## INCLUDE_DIRS: uncomment this if you package contains header files +## LIBRARIES: libraries you create in this project that dependent projects also need +## CATKIN_DEPENDS: catkin_packages dependent projects also need +## DEPENDS: system dependencies of this project that dependent projects also need +catkin_package( + INCLUDE_DIRS include +# LIBRARIES hos_cosgi_core + CATKIN_DEPENDS hos_celix +# DEPENDS system_lib +) + +########### +## Build ## +########### + +## Specify additional locations of header files +## Your package locations should be listed before other locations +# include_directories(include) +include_directories( + ${catkin_INCLUDE_DIRS} +) + +## Declare a cpp library +# add_library(hos_cosgi_core +# src/${PROJECT_NAME}/hos_cosgi_core.cpp +# ) + +## Declare a cpp executable +# add_executable(hos_cosgi_core_node src/hos_cosgi_core_node.cpp) + +## Add cmake target dependencies of the executable/library +## as an example, message headers may need to be generated before nodes +# add_dependencies(hos_cosgi_core_node hos_cosgi_core_generate_messages_cpp) + +## Specify libraries to link a library or executable target against +# target_link_libraries(hos_cosgi_core_node +# ${catkin_LIBRARIES} +# ) + +############# +## Install ## +############# + +# all install targets should use catkin DESTINATION variables +# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html + +## Mark executable scripts (Python etc.) for installation +## in contrast to setup.py, you can choose the destination +# install(PROGRAMS +# scripts/my_python_script +# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark executables and/or libraries for installation +# install(TARGETS hos_cosgi_core hos_cosgi_core_node +# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark cpp header files for installation +install(DIRECTORY include/${PROJECT_NAME}/ + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} + FILES_MATCHING PATTERN "*.h" + PATTERN ".svn" EXCLUDE +) + +## Mark other files for installation (e.g. launch and bag files, etc.) +# install(FILES +# # myfile1 +# # myfile2 +# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +# ) + +############# +## Testing ## +############# + +## Add gtest based cpp test target and link libraries +# catkin_add_gtest(${PROJECT_NAME}-test test/test_hos_cosgi_core.cpp) +# if(TARGET ${PROJECT_NAME}-test) +# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) +# endif() + +## Add folders to be run by python nosetests +# catkin_add_nosetests(test) diff --git a/src/hos_cosgi_core/include/hos_cosgi_core/cosgi_core.h b/src/hos_cosgi_core/include/hos_cosgi_core/cosgi_core.h new file mode 100644 index 00000000..cc2a94cb --- /dev/null +++ b/src/hos_cosgi_core/include/hos_cosgi_core/cosgi_core.h @@ -0,0 +1,25 @@ +/* + * cosgi_core.h + * + * Created on: 19.04.2015 + * Author: matzman + */ + +#ifndef INCLUDE_HOS_COSGI_CORE_COSGI_CORE_H_ +#define INCLUDE_HOS_COSGI_CORE_COSGI_CORE_H_ + + +class COSGI_Object_Interface { +public: + virtual ~COSGI_Object_Interface() {} +}; + + +class COSGI_Service_Interface : public COSGI_Object_Interface { +public: + virtual const char* getServiceName() = 0; + virtual void getServiceVersion(int& major, int& minor) = 0; +}; + + +#endif /* INCLUDE_HOS_COSGI_CORE_COSGI_CORE_H_ */ diff --git a/src/hos_cosgi_core/package.xml b/src/hos_cosgi_core/package.xml new file mode 100644 index 00000000..41f67a15 --- /dev/null +++ b/src/hos_cosgi_core/package.xml @@ -0,0 +1,52 @@ + + + hos_cosgi_core + 0.0.0 + The hos_cosgi_core package + + + + + matzman + + + + + + TODO + + + + + + + + + + + + + + + + + + + + + + + + + + catkin + hos_celix + hos_celix + + + + + + + + \ No newline at end of file diff --git a/src/hos_cosgi_devicerepository/CMakeLists.txt b/src/hos_cosgi_devicerepository/CMakeLists.txt index 9dd2f47e..85ce2844 100644 --- a/src/hos_cosgi_devicerepository/CMakeLists.txt +++ b/src/hos_cosgi_devicerepository/CMakeLists.txt @@ -8,6 +8,9 @@ find_package(catkin REQUIRED COMPONENTS hos_celix hos_core_msgs hos_cosgi_launcher + hos_cosgi_core + hos_libvariant + roscpp ) ## System dependencies are found with CMake's conventions @@ -87,7 +90,7 @@ find_package(Boost REQUIRED) catkin_package( INCLUDE_DIRS include # LIBRARIES hos_cosgi_devicerepository - CATKIN_DEPENDS hos_celix hos_core_msgs hos_cosgi_launcher + CATKIN_DEPENDS hos_celix hos_core_msgs hos_cosgi_launcher roscpp hos_cosgi_core hos_libvariant # DEPENDS system_lib ) diff --git a/src/hos_cosgi_devicerepository/include/hos_cosgi_devicerepository/hos_devicerepository_service.h b/src/hos_cosgi_devicerepository/include/hos_cosgi_devicerepository/hos_devicerepository_service.h index f3232447..8754d518 100644 --- a/src/hos_cosgi_devicerepository/include/hos_cosgi_devicerepository/hos_devicerepository_service.h +++ b/src/hos_cosgi_devicerepository/include/hos_cosgi_devicerepository/hos_devicerepository_service.h @@ -2,6 +2,7 @@ #define _HOS_DEVICEREPOSITORY_SERVICE_H_ +#include #include #include @@ -11,10 +12,8 @@ namespace hos { class DeviceEvent; class DeviceEventListener; -class GenericDevice { +class GenericDevice : public COSGI_Object_Interface { public: - virtual ~GenericDevice() {} - virtual std::string getDeviceID() = 0; virtual bool registerDeviceStatusListener(DeviceEventListener& listener) = 0; @@ -30,26 +29,23 @@ public: }; -class DeviceEventListener { +class DeviceEventListener : public COSGI_Object_Interface { public: - virtual ~DeviceEventListener() {} virtual void deviceEventReceived(const DeviceEvent& event) = 0; }; -class HOSDeviceRepositoryService { +class HOSDeviceRepositoryService : public COSGI_Service_Interface { public: static constexpr const char* SERVICE_NAME = "hos_devicerepository_service"; - - virtual ~HOSDeviceRepositoryService() {} + static constexpr int SERVICE_VERSION_MAJOR = 1; + static constexpr int SERVICE_VERSION_MINOR = 0; virtual GenericDevice* getDevice(std::string device_id) = 0; virtual std::vector& getDevices(std::vector& devices) = 0; virtual bool registerDeviceStatusListener(DeviceEventListener& listener) = 0; virtual bool unregisterDeviceStatusListener(DeviceEventListener& listener) = 0; - - virtual void getVersion(int& major, int& minor) = 0; }; diff --git a/src/hos_cosgi_devicerepository/package.xml b/src/hos_cosgi_devicerepository/package.xml index 8a8c761a..0486b7ca 100644 --- a/src/hos_cosgi_devicerepository/package.xml +++ b/src/hos_cosgi_devicerepository/package.xml @@ -43,9 +43,15 @@ hos_celix hos_core_msgs hos_cosgi_launcher + roscpp + hos_cosgi_core + hos_libvariant hos_celix hos_core_msgs hos_cosgi_launcher + roscpp + hos_cosgi_core + hos_libvariant @@ -56,4 +62,4 @@ - \ No newline at end of file + diff --git a/src/hos_cosgi_devicerepository/src/bundle_activator.cpp b/src/hos_cosgi_devicerepository/src/bundle_activator.cpp index bbe5f3cd..a6e92897 100644 --- a/src/hos_cosgi_devicerepository/src/bundle_activator.cpp +++ b/src/hos_cosgi_devicerepository/src/bundle_activator.cpp @@ -56,7 +56,7 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) ROS_ERROR("DeviceRepositoryService: Could not retrieve HOSCoreService."); } else { int major = 0, minor = 0; - coreService->getVersion(major, minor); + coreService->getServiceVersion(major, minor); ROS_INFO_STREAM("DeviceRepositoryService: Found HOSCoreService Version " << major << "." << minor); // Create and register hos-devicerepository-service if (myUserData->serviceReg != nullptr) { diff --git a/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.cpp b/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.cpp index 22df7dc6..84c0e2e2 100644 --- a/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.cpp +++ b/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.cpp @@ -41,8 +41,6 @@ HOSDeviceRepositoryServiceImpl::HOSDeviceRepositoryServiceImpl(HOSCoreService& c privateNodeHandle.getParam("~device_repository_prefix", deviceRepositoryPrefix); } -HOSDeviceRepositoryServiceImpl::~HOSDeviceRepositoryServiceImpl() {} - GenericDevice* HOSDeviceRepositoryServiceImpl::getDevice(std::string device_id) { return this->devices[device_id]; } @@ -75,9 +73,9 @@ bool HOSDeviceRepositoryServiceImpl::unregisterDeviceStatusListener(DeviceEventL } -void HOSDeviceRepositoryServiceImpl::getVersion(int& major, int& minor) { - major = 1; - minor = 0; +void HOSDeviceRepositoryServiceImpl::getServiceVersion(int& major, int& minor) { + major = SERVICE_VERSION_MAJOR; + minor = SERVICE_VERSION_MINOR; } int HOSDeviceRepositoryServiceImpl::getRefCount() { diff --git a/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.h b/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.h index 5e281143..930f2671 100644 --- a/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.h +++ b/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.h @@ -45,7 +45,6 @@ private: public: HOSDeviceRepositoryServiceImpl(HOSCoreService& coreService); - virtual ~HOSDeviceRepositoryServiceImpl(); virtual GenericDevice* getDevice(std::string device_id); virtual std::vector& getDevices(std::vector& devices); @@ -53,7 +52,9 @@ public: virtual bool registerDeviceStatusListener(DeviceEventListener& listener); virtual bool unregisterDeviceStatusListener(DeviceEventListener& listener); - virtual void getVersion(int& major, int& minor); + virtual const char* getServiceName() { return SERVICE_NAME; } + virtual void getServiceVersion(int& major, int& minor); + virtual int getRefCount(); }; diff --git a/src/hos_cosgi_launcher/CMakeLists.txt b/src/hos_cosgi_launcher/CMakeLists.txt index 8709eed1..92447fab 100644 --- a/src/hos_cosgi_launcher/CMakeLists.txt +++ b/src/hos_cosgi_launcher/CMakeLists.txt @@ -7,6 +7,7 @@ project(hos_cosgi_launcher) find_package(catkin REQUIRED COMPONENTS hos_celix roscpp + hos_cosgi_core ) ## System dependencies are found with CMake's conventions @@ -82,7 +83,7 @@ find_package(APR REQUIRED) catkin_package( INCLUDE_DIRS include # LIBRARIES hos_cosgi_launcher - CATKIN_DEPENDS hos_celix + CATKIN_DEPENDS hos_celix hos_cosgi_core # DEPENDS system_lib ) diff --git a/src/hos_cosgi_launcher/include/hos_cosgi_launcher/hos_core_service.h b/src/hos_cosgi_launcher/include/hos_cosgi_launcher/hos_core_service.h index 55474873..68af32ec 100644 --- a/src/hos_cosgi_launcher/include/hos_cosgi_launcher/hos_core_service.h +++ b/src/hos_cosgi_launcher/include/hos_cosgi_launcher/hos_core_service.h @@ -2,22 +2,24 @@ #define SRC_HOS_CORE_SERVICE_H_ +#include + + namespace ros { class NodeHandle; } namespace hos { -class HOSCoreService { +class HOSCoreService : public COSGI_Service_Interface { public: static constexpr const char* SERVICE_NAME = "hos_core_service"; - - virtual ~HOSCoreService() {} + static constexpr int SERVICE_VERSION_MAJOR = 1; + static constexpr int SERVICE_VERSION_MINOR = 0; virtual ros::NodeHandle& getPublicNodeHandle() = 0; virtual ros::NodeHandle& getPrivateNodeHandle() = 0; virtual void requestShutdown() = 0; - virtual void getVersion(int& major, int& minor) = 0; }; } // namespace hos diff --git a/src/hos_cosgi_launcher/package.xml b/src/hos_cosgi_launcher/package.xml index 32437d2d..5d74924f 100644 --- a/src/hos_cosgi_launcher/package.xml +++ b/src/hos_cosgi_launcher/package.xml @@ -42,8 +42,10 @@ catkin hos_celix roscpp + hos_cosgi_core hos_celix roscpp + hos_cosgi_core diff --git a/src/hos_cosgi_launcher/src/hos_core_service_impl.cpp b/src/hos_cosgi_launcher/src/hos_core_service_impl.cpp index 180e59ab..22fcd3b5 100644 --- a/src/hos_cosgi_launcher/src/hos_core_service_impl.cpp +++ b/src/hos_cosgi_launcher/src/hos_core_service_impl.cpp @@ -14,8 +14,6 @@ namespace hos { HOSCoreServiceImpl::HOSCoreServiceImpl(ros::NodeHandle& publicNodeHandle, ros::NodeHandle& privateNodeHandle) : publicNodeHandle(publicNodeHandle), privateNodeHandle(privateNodeHandle) {} -HOSCoreServiceImpl::~HOSCoreServiceImpl() {} - ros::NodeHandle& HOSCoreServiceImpl::getPublicNodeHandle() { return publicNodeHandle; @@ -31,9 +29,9 @@ void HOSCoreServiceImpl::requestShutdown() { ros::shutdown(); } -void HOSCoreServiceImpl::getVersion(int& major, int& minor) { - major = 1; - minor = 0; +void HOSCoreServiceImpl::getServiceVersion(int& major, int& minor) { + major = SERVICE_VERSION_MAJOR; + minor = SERVICE_VERSION_MINOR; } } // namespace hos diff --git a/src/hos_cosgi_launcher/src/hos_core_service_impl.h b/src/hos_cosgi_launcher/src/hos_core_service_impl.h index 50a7ce1b..85a66b13 100644 --- a/src/hos_cosgi_launcher/src/hos_core_service_impl.h +++ b/src/hos_cosgi_launcher/src/hos_core_service_impl.h @@ -20,12 +20,12 @@ private: public: HOSCoreServiceImpl(ros::NodeHandle& publicNodeHandle, ros::NodeHandle& privateNodeHandle); - virtual ~HOSCoreServiceImpl(); virtual ros::NodeHandle& getPublicNodeHandle(); virtual ros::NodeHandle& getPrivateNodeHandle(); virtual void requestShutdown(); - virtual void getVersion(int& major, int& minor); + virtual const char* getServiceName() { return SERVICE_NAME; } + virtual void getServiceVersion(int& major, int& minor); }; } // namespace hos diff --git a/src/hos_libvariant/CMakeLists.txt b/src/hos_libvariant/CMakeLists.txt new file mode 100644 index 00000000..b138e1c7 --- /dev/null +++ b/src/hos_libvariant/CMakeLists.txt @@ -0,0 +1,193 @@ +cmake_minimum_required(VERSION 2.8.3) +project(hos_libvariant) + +## Find catkin macros and libraries +## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) +## is used, also find other catkin packages +find_package(catkin REQUIRED) + +## System dependencies are found with CMake's conventions +# find_package(Boost REQUIRED COMPONENTS system) + + +## Uncomment this if the package has a setup.py. This macro ensures +## modules and global scripts declared therein get installed +## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html +# catkin_python_setup() + +################################################ +## Declare ROS messages, services and actions ## +################################################ + +## To declare and build messages, services or actions from within this +## package, follow these steps: +## * Let MSG_DEP_SET be the set of packages whose message types you use in +## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). +## * In the file package.xml: +## * add a build_depend and a run_depend tag for each package in MSG_DEP_SET +## * If MSG_DEP_SET isn't empty the following dependencies might have been +## pulled in transitively but can be declared for certainty nonetheless: +## * add a build_depend tag for "message_generation" +## * add a run_depend tag for "message_runtime" +## * In this file (CMakeLists.txt): +## * add "message_generation" and every package in MSG_DEP_SET to +## find_package(catkin REQUIRED COMPONENTS ...) +## * add "message_runtime" and every package in MSG_DEP_SET to +## catkin_package(CATKIN_DEPENDS ...) +## * uncomment the add_*_files sections below as needed +## and list every .msg/.srv/.action file to be processed +## * uncomment the generate_messages entry below +## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) + +## Generate messages in the 'msg' folder +# add_message_files( +# FILES +# Message1.msg +# Message2.msg +# ) + +## Generate services in the 'srv' folder +# add_service_files( +# FILES +# Service1.srv +# Service2.srv +# ) + +## Generate actions in the 'action' folder +# add_action_files( +# FILES +# Action1.action +# Action2.action +# ) + +## Generate added messages and services with any dependencies listed here +# generate_messages( +# DEPENDENCIES +# std_msgs # Or other packages containing msgs +# ) + +################################### +## catkin specific configuration ## +################################### +## The catkin_package macro generates cmake config files for your package +## Declare things to be passed to dependent projects +## INCLUDE_DIRS: uncomment this if you package contains header files +## LIBRARIES: libraries you create in this project that dependent projects also need +## CATKIN_DEPENDS: catkin_packages dependent projects also need +## DEPENDS: system dependencies of this project that dependent projects also need +catkin_package( + INCLUDE_DIRS include + LIBRARIES Variant +# CATKIN_DEPENDS other_catkin_pkg +# DEPENDS system_lib +) + +########### +## Build ## +########### + +include(ExternalProject) + +ExternalProject_Add( libvariant_project + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src + CONFIGURE_COMMAND cmake ${CMAKE_CURRENT_SOURCE_DIR}/src + -DCMAKE_INSTALL_PREFIX=${CATKIN_DEVEL_PREFIX} + -DBUILD_SHARED_LIBS=FALSE + -DLIBVARIANT_BUILD_EXAMPLES=FALSE + -DLIBVARIANT_BUILD_TESTS=FALSE + -DLIBVARIANT_BUILD_WALL=TRUE + -DLIBVARIANT_ENABLE_CURL=TRUE + -DLIBVARIANT_ENABLE_MSGPACK=FALSE + -DLIBVARIANT_ENABLE_XML=TRUE + -DLIBVARIANT_ENABLE_YAML=TRUE + BUILD_COMMAND make all + INSTALL_COMMAND make install +) + +add_library( Variant STATIC IMPORTED ) +set_property( TARGET Variant PROPERTY IMPORTED_LOCATION "${CATKIN_DEVEL_PREFIX}/lib/libVariant.a") +add_dependencies( Variant libvariant_project ) + +## Specify additional locations of header files +## Your package locations should be listed before other locations +# include_directories(include) + +## Declare a cpp library +# add_library(hos_libvariant +# src/${PROJECT_NAME}/hos_libvariant.cpp +# ) + +## Declare a cpp executable +# add_executable(hos_libvariant_node src/hos_libvariant_node.cpp) + +## Add cmake target dependencies of the executable/library +## as an example, message headers may need to be generated before nodes +# add_dependencies(hos_libvariant_node hos_libvariant_generate_messages_cpp) + +## Specify libraries to link a library or executable target against +# target_link_libraries(hos_libvariant_node +# ${catkin_LIBRARIES} +# ) + +############# +## Install ## +############# + +install(DIRECTORY include/${PROJECT_NAME}/ + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} +) +install(DIRECTORY ${CATKIN_DEVEL_PREFIX}/lib/ + DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +) +install(DIRECTORY ${CATKIN_DEVEL_PREFIX}/bin/ + DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} + USE_SOURCE_PERMISSIONS +) +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ + DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake + FILES_MATCHING PATTERN "*.cmake" +) + +# all install targets should use catkin DESTINATION variables +# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html + +## Mark executable scripts (Python etc.) for installation +## in contrast to setup.py, you can choose the destination +# install(PROGRAMS +# scripts/my_python_script +# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark executables and/or libraries for installation +# install(TARGETS hos_libvariant hos_libvariant_node +# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} +# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} +# ) + +## Mark cpp header files for installation +# install(DIRECTORY include/${PROJECT_NAME}/ +# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} +# FILES_MATCHING PATTERN "*.h" +# PATTERN ".svn" EXCLUDE +# ) + +## Mark other files for installation (e.g. launch and bag files, etc.) +# install(FILES +# # myfile1 +# # myfile2 +# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} +# ) + +############# +## Testing ## +############# + +## Add gtest based cpp test target and link libraries +# catkin_add_gtest(${PROJECT_NAME}-test test/test_hos_libvariant.cpp) +# if(TARGET ${PROJECT_NAME}-test) +# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) +# endif() + +## Add folders to be run by python nosetests +# catkin_add_nosetests(test) diff --git a/src/hos_libvariant/include/hos_libvariant/ArgParse.h b/src/hos_libvariant/include/hos_libvariant/ArgParse.h new file mode 100644 index 00000000..74248bec --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/ArgParse.h @@ -0,0 +1,302 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_ARGPARSER_H +#define VARIANT_ARGPARSER_H + +#pragma once +#include "../hos_libvariant/Variant.h" +#include +#include +namespace libvariant { + + + enum ArgParseAction { + ARGACTION_UNKNOWN, // Unknown action (invalid) + ARGACTION_STORE, // Interpret the option argument and store it at the path + ARGACTION_STORE_CONST, // Store const into the path + ARGACTION_STORE_TRUE, // Store true into the path + ARGACTION_STORE_FALSE, // Store false into the path + ARGACTION_APPEND, // Append the option argument to the list at path + ARGACTION_COUNT, // Make the value at path be the count of this options occurrences + ARGACTION_HELP, // Print out the help text and exit + ARGACTION_ADVHELP, // Print the advanced help and exit + ARGACTION_CONFIG, // Consider the option argument a filename to be loaded and parsed as a config + ARGACTION_CONFIG_JSON, // force parser to use jscn + ARGACTION_CONFIG_YAML, // force parser to use yaml + ARGACTION_CONFIG_PLIST, // force parser to use xmlplist + ARGACTION_PRINT_CONFIG // At the end of parsing print out the resulting config and exit. + }; + + // A constrained list of only the valid types for ArgParse + enum ArgParseType { + ARGTYPE_GUESS = Variant::NullType, // No type specification, guess, uses deserialize machinery + ARGTYPE_INT = Variant::IntegerType, // Error if it cannot be turned into an integer + ARGTYPE_UINT = Variant::UnsignedType, // Error if it cannot be turned into a unsigned + ARGTYPE_FLOAT = Variant::FloatType, // Error if it cannot be turned into a float + ARGTYPE_STRING = Variant::StringType, // store as string + ARGTYPE_BOOL = Variant::BoolType // Error if it cannot be turned into a boolean type + // it treats 0 or the strings 'false' and 'no' or any substring ignoring case as false + // and everything else as true + }; + + //! Valid values are: + // This is used for converting the enum to a Variant and back for + // ArgParse::GetDescription and ArgParse::Merge + // store -- store the value into the key (default) + // store_const -- store const (see Const) into the key + // store_true -- store true into the key (i.e. no option argument) + // store_false -- store false into the key + // append -- make the value a list of instances of the option + // count -- count the number of instances of this argument + // help -- display the help text and exit + // config -- load a file and merge it into the result (uses GuessFormat) + // config_json -- same as config, force to use json parser + // config_yaml -- same as config, force to use yaml parser + // config_plist -- same as config, force to use xml-plist parser + // config_print -- when finished parsing, print out the config and exit + ArgParseAction ArgParseActionFromStr(const std::string &action); + std::string ArgParseActionToStr(ArgParseAction action); + + class ArgParse; + struct ArgParseImpl; + struct ArgParseOptImpl; + struct ArgParseGroupImpl; + + //! ArgParseOption is a part of class ArgParse. + // ArgParseOption is the interface that ArgParse provides to the user to be able + // to conveniently set the options for an option. + class ArgParseOption { + public: + + //! Set the title of this option. The title is used + // as an argument placeholder string. + ArgParseOption &Title(const std::string &title); + + //! What action to perform when this option is encountered. + // See ArgParseAction above for a list of actions. + ArgParseOption &Action(ArgParseAction action); + DEPRECATED ArgParseOption &Action(const std::string &action); + + //! Set the type parsing and validation. + // If set and the argument is not of this type, then it is invalid. + // Default: ARGTYPE_GUESS + // If type is ARGTYPE_GUESS then ArgParse attempts to parse the + // argument with the same machinery that is used by the deserializers + // to figure out the type of a scalar. + // ARGTYPE_UINT is the same as ARGTYPE_INT but with + // Minimum set to 0. + // See ArgParseType for the list of valid types. + ArgParseOption &Type(ArgParseType type); + // Same as above but throws on invalid type + DEPRECATED ArgParseOption &Type(Variant::Type_t type); + // String version of the above + // Valid types are "string", "number", "integer", "boolean", or "null". + // Default type is "null". + DEPRECATED ArgParseOption &Type(const std::string &type); + + //! Set the const value for "store_const" + ArgParseOption &Const(Variant val); + + //! Set the default value used when the option is not set. + ArgParseOption &Default(Variant val); + + //! Set the environment variable name to check for a value for this option. + // When the environment variable is present this acts like Default was set + // to the environment variable's value. I.e., this overrides default, + // command line arguments override this. + ArgParseOption &Env(const char *env); + + //! If the resulting value is a number, require to be at least this minimum. + ArgParseOption &Minimum(Variant val); + + //! If the resulting value is a number, require to be at most this maximum. + ArgParseOption &Maximum(Variant val); + + //! Add choices. + // If a choice is added, the value of the option must be one of the choices. + ArgParseOption &AddChoice(Variant val); + + //! Set choices (old ones forgotten) from a vector. + ArgParseOption &SetChoices(const std::vector &val); + + //! Return the vector of choices set. + const std::vector &GetChoices(); + + //! Is this option required? + ArgParseOption &Required(bool req=true); + + //! Set the help text for this option. + ArgParseOption &Help(const std::string &helptxt); + + //! If this option is a string, it must match the regex in pattern. + ArgParseOption &Pattern(const std::string &pattern); + + //! If this option is a string, it must be no longer than maxLength. + ArgParseOption &MaxLength(unsigned l); + + //! If this option is a string, it must be no shorter than minLength. + ArgParseOption &MinLength(unsigned l); + + //! If this option can be specified multiple times, it must be + // specified minArgs times at least. + // A value of 0 means zero arguments is valid. + ArgParseOption &MinArgs(unsigned l); + + //! If this option can be specified multiple times, it cannot be + // specified more than maxArgs. + // A value of 0 means any number + ArgParseOption &MaxArgs(unsigned l); + + //! Specify that this argument must be present l times. + // Sets both minArgs and maxArgs to l + ArgParseOption &NumArgs(unsigned l); + + //! Adds this option to group gname. If gname does not exist, + //it will be created with an empty title and description. + ArgParseOption &Group(const std::string &gname); + + //! Sets this argument to be an advanced option + // This hides the option when not printing advanced options + ArgParseOption &Advanced(bool adv = true); + + private: + ArgParseOption(ArgParseOptImpl *i) : impl(i) {} + ArgParseOptImpl *impl; + friend class ArgParse; + }; + + //! Groups are a way to organize the option and to provide mutual exclusion + //of option. An argument may be part of more than one group, but may only + //be part of one group that has a non-empty title and description. An + //attempt is made to order the help text so that options within the same + //group appear together and if a group has a title and/or description the + //options are placed within a subsection headed with the title and + //description. + class OptionGroup { + public: + //! Set the title for this group + OptionGroup &Title(const std::string &t); + //! Set the description for this group + OptionGroup &Description(const std::string &d); + //! Set that the options in this group are mutually exclusive + OptionGroup &MutuallyExclusive(bool exclusive=true); + //! Set that at least one option in this group is required. + //Has no meaning when the group is not mutually exclusive. + OptionGroup &Required(bool req=true); + + OptionGroup &Add(const std::string &keypath); + OptionGroup &Add(const Path &keypath); + + //! Sets this option group to be advanced + // Hide the group when not printing advanced options. + // This only hides the group when it has a title or description + OptionGroup &Advanced(bool adv=true); + private: + OptionGroup(ArgParseGroupImpl *i) : impl(i) {} + ArgParseGroupImpl *impl; + friend class ArgParse; + }; + + class ArgParse { + public: + //! addhelp true causes AddHelp to be called. + ArgParse(bool addhelp=true); + ArgParse(const std::string &pname, bool addhelp=true); + + //! Add the option and configure it as an option that takes an argument. + //The default action will be "store" and type will be unspecified + // + // keypath must be a valid path as defined in Path.h + // + // For no short option, shortOpt may be 0, and for no long option, longOpt may be + // the empty string. If both shortOpt is 0 and longOpt is empty then this option + // is hidden unless Env is also set for the option. + ArgParseOption AddOption(const std::string &keypath, int shortOpt, const std::string &longOpt="", + const std::string &helptxt=""); + + //! Convenience methods for getting an existing option. + // ArgParse args(argv[0]); + // args.AddOption("key1", 'k', "key1", "how many things").Type("integer"); + // args.AddOption("key2", 'K', "key2", "what to name it").Type("string"); + // (... some intermediate code ...) + // args.At("key1").Default(42); + // args["key2"].Default("foo"); + ArgParseOption At(const std::string &keypath); + ArgParseOption operator[](const std::string &keypath) { return At(keypath); } + + //! Add the option and configure it as an option that is default false and + //if present sets to true + //i.e., same as: + // AddOption(keypath, shortOpt, longOpt, helptxt).Type("boolean") + // .Action("store_true").Default(false); + ArgParseOption AddFlag(const std::string &keypath, int shortOpt, const std::string &longOpt="", + const std::string &helptxt=""); + + //! Adds the group name. + OptionGroup AddGroup(const std::string &name, const std::string &title="", const std::string &description=""); + //! Returns the group name. + OptionGroup GetGroup(const std::string &name); + + //! Add a positional argument. + // By default the new positional argument will have NumArgs as 1. + // Arguments are processed in the order they are added. + // If maxArgs is 0, then no positional arguments after this one will + // be processed. + // Default action is store. + ArgParseOption AddArgument(const std::string &keypath, const std::string &helptxt=""); + + //! Convenience methods for getting an existing argument. + // ArgParse args(argv[0]); + // args.AddArgument("arg0", "pick one").AddChoice("AAA").AddChoice("BBB"); + // args.AddArgument("arg1", "scale factor").Type("float"); + // (... some intermediate code ...) + // args.At(0).AddChoice("CCC"); + // args[1].Default(0.456); + ArgParseOption At(size_t argumentIndex); + ArgParseOption operator[](size_t argumentIndex) { return At(argumentIndex); } + + //! When this is on, trying to add a second option with the same short option + //will cause the second option to act as though it had no short option specified. + void ConflictResolution(bool resolve=true); + + //! Add a --config and --print-config option + // --config is set with action ARGACTION_CONFIG and + // --print-config is set with action ARGACTION_PRINT_CONFIG + void AddConfigDefaults(); + + //! Add -h,--help option with action ARGACTION_HELP + void AddHelp(); + + //! Set the description text that follows the usage message. + void SetDescription(const std::string &txt); + //! Set the epilog text at the end of help. + void SetEpilog(const std::string &txt); + //! Override the default program name. + void SetProgramName(const std::string &pname, bool do_basename=true); + std::string GetProgramName() const; + + void Merge(Variant newopts); + void Merge(const ArgParse &other); + + //! Validate the argparse description against the internal schema + void Validate() const; + + //! Parse the arguments with the internal description + Variant Parse(int argc, char *const *argv); + + //! Print the help message and exit. + void PrintHelp(bool advanced=false) const; + + //! Return the Variant that describes the arguments + Variant GetDescription() const; + + //! Generate a schema for the Variant returned by Parse from the argument description + Variant GenerateSchema() const; + + private: + shared_ptr impl; + }; +} +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/Blob.h b/src/hos_libvariant/include/hos_libvariant/Blob.h new file mode 100644 index 00000000..b2706e4d --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/Blob.h @@ -0,0 +1,63 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_BLOB_H +#define VARIANT_BLOB_H + +#pragma once +#include "../../../src/include/Variant/SharedPtr.h" +#include +#include + +namespace libvariant { + class Blob; + typedef shared_ptr BlobPtr; + typedef shared_ptr ConstBlobPtr; + + typedef void (*BlobFreeFunc)(void *ptr, void *ctx); + + class Blob { + public: + + /// Reference the buffer and call ffunc when Blob no longer references it + static BlobPtr Create(void *ptr, unsigned len, BlobFreeFunc ffunc, void *context); + /// Will call ffunc on each buffer in iov + static BlobPtr Create(struct iovec *iov, unsigned iov_len, BlobFreeFunc ffunc, void *context); + /// Copy the data into a newly allocatd buffer + static BlobPtr CreateCopy(const void *ptr, unsigned len); + static BlobPtr CreateCopy(const struct iovec *iov, unsigned iov_len); + /// Reference the buffer and when done call free to free the buffer + static BlobPtr CreateFree(void *ptr, unsigned len); + static BlobPtr CreateFree(struct iovec *iov, unsigned iov_len); + /// Reference the buffer, assume static or other allocation lifetime where + // calling a free function is not required + static BlobPtr CreateReferenced(void *ptr, unsigned len); + static BlobPtr CreateReferenced(struct iovec *iov, unsigned iov_len); + ~Blob(); + + BlobPtr Copy() const; + + void *GetPtr(unsigned i) { return iov[i].iov_base; } + const void *GetPtr(unsigned i) const { return iov[i].iov_base; } + unsigned GetLength(unsigned i) const { return iov[i].iov_len; } + struct iovec *GetIOVec() { return &iov[0]; } + const struct iovec *GetIOVec() const { return &iov[0]; } + unsigned GetNumBuffers() const { return iov.size(); } + unsigned GetTotalLength() const; + + int Compare(ConstBlobPtr other) const; + + private: + Blob(); + Blob(const Blob&); + Blob(struct iovec *v, unsigned l, BlobFreeFunc f, void *c); + Blob operator=(const Blob&); + + std::vector iov; + BlobFreeFunc free_func; + void *ctx; + }; + +} +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/Config.h b/src/hos_libvariant/include/hos_libvariant/Config.h new file mode 100644 index 00000000..32f40d22 --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/Config.h @@ -0,0 +1,13 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_CONFIG_H +#define VARIANT_CONFIG_H +#pragma once + +/* #undef HAVE_CXX11_SHAREDPTR */ +#define HAVE_TR1_SHAREDPTR 1 +/* #undef USE_BOOST_SHAREDPTR */ + +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/Emitter.h b/src/hos_libvariant/include/hos_libvariant/Emitter.h new file mode 100644 index 00000000..1b113470 --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/Emitter.h @@ -0,0 +1,226 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_EMITTER_H +#define VARIANT_EMITTER_H + +#pragma once +#include +#include +#include +#include +#include "../../../src/include/Variant/Variant.h" +#include "../../../src/include/Variant/Blob.h" +#include "../../../src/include/Variant/EmitterOutput.h" +#include +#include + +namespace libvariant { + + /** + * Class to override to implement an Emitter + */ + class EmitterImpl { + public: + virtual ~EmitterImpl(); + + virtual void BeginDocument() = 0; + virtual void EndDocument() = 0; + virtual void BeginMap(int length) = 0; + virtual void EndMap() = 0; + virtual void BeginList(int length) = 0; + virtual void EndList() = 0; + + virtual void EmitNull() = 0; + virtual void EmitTrue() = 0; + virtual void EmitFalse() = 0; + virtual void Emit(const char *v) = 0; + virtual void Emit(intmax_t v) = 0; + virtual void Emit(uintmax_t v) = 0; + virtual void Emit(double v) = 0; + virtual void Emit(ConstBlobPtr b) = 0; + + virtual void Flush() = 0; + virtual void Close() = 0; + + virtual Variant GetParam(const std::string &key) = 0; + virtual Variant GetParams() = 0; + virtual void SetParam(const std::string &key, Variant value) = 0; + virtual void SetParams(Variant params); + }; + + /** + * Actual emitter class. + */ + class Emitter { + public: + Emitter(); + Emitter(shared_ptr i); + ~Emitter(); + + Emitter &BeginDocument(); + Emitter &EndDocument(); + + //Some emitter implementations require the length of the map at the + //beginning. Such implementations should buffer events if length == -1 + //Implementations are free to ignore the length. + Emitter &BeginMap() { return BeginMap(-1); } + Emitter &BeginMap(int length); + Emitter &EndMap(); + //Some emitter implementations require the length of the list at the + //beginning. Such implementations should buffer events if length == -1 + Emitter &BeginList() { return BeginList(-1); } + Emitter &BeginList(int length); + Emitter &EndList(); + + Emitter &EmitNull(); + Emitter &EmitTrue(); + Emitter &EmitFalse(); + Emitter &Emit(bool v) { return (v ? EmitTrue() : EmitFalse()); } + Emitter &Emit(const std::string &v); + Emitter &Emit(const char *v); + Emitter &Emit(intmax_t v); + Emitter &Emit(uintmax_t v); + Emitter &Emit(double v); + Emitter &Emit(ConstBlobPtr b); + + void Flush(); + void Close(); + + /// Get the value of parameters of the parser (e.g. pretty printing, + // styles, etc.) + // See individual emitter below for supported values. + Variant GetParam(const std::string &key); + /// Get a dict of all parameters + Variant GetParams(); + /// Set the value of parameters. + // See individual emitter below for supported values. + void SetParam(const std::string &key, Variant value); + /// Set all parameters from a dict + void SetParams(Variant params); + /// Internal/advanced function to get the underlying implementation + shared_ptr GetImpl() { return impl; } + private: + shared_ptr impl; + }; + + template + inline Emitter &operator<<(Emitter &e, const std::vector &v) { + e.BeginList(v.size()); + for (typename std::vector::const_iterator i(v.begin()), end(v.end()); i!=end; i++) { + e << *i; + } + e.EndList(); + return e; + } + + template + inline Emitter &operator<<(Emitter &e, const std::map &v) { + e.BeginMap(v.size()); + for (typename std::map::const_iterator i(v.begin()), end(v.end()); i!=end; ++i) { + e.Emit(i->first); + e << i->second; + } + e.EndMap(); + return e; + } + inline Emitter &operator<<(Emitter &e, bool v) { e.Emit(v); return e; } + inline Emitter &operator<<(Emitter &e, char v) { e.Emit(intmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, short v) { e.Emit(intmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, int v) { e.Emit(intmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, long v) { e.Emit(intmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, long long v) { e.Emit(intmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, unsigned char v) { e.Emit(uintmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, unsigned short v) { e.Emit(uintmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, unsigned int v) { e.Emit(uintmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, unsigned long v) { e.Emit(uintmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, unsigned long long v) { e.Emit(uintmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, const char *v) { e.Emit(v); return e; } + inline Emitter &operator<<(Emitter &e, const std::string &v) { e.Emit(v); return e; } + inline Emitter &operator<<(Emitter &e, float v) { e.Emit(double(v)); return e; } + inline Emitter &operator<<(Emitter &e, double v) { e.Emit(v); return e; } + inline Emitter &operator<<(Emitter &e, ConstBlobPtr v) { e.Emit(v); return e; } + + shared_ptr CreateEmitterOutput(void *ptr, unsigned len, unsigned *out_len=0); + shared_ptr CreateEmitterOutput(const char *filename); + shared_ptr CreateEmitterOutput(FILE *f); + shared_ptr CreateEmitterOutput(std::streambuf *sb); + + /** + * Create an Emiter that Emits the format specified by type. + * Supported parameters are dependent on type (see below). + */ + Emitter CreateEmitter(shared_ptr o, SerializeType type, Variant params = Variant::NullType); + + /** + * Create an Emitter that Emits the JSON format. + * + * Supported parameters are: + * "pretty": boolean + * "indent": integer (number of spaces to indent when pretty is on, + * default 4) + * "precision": integer (number of digits for floats) + * "strict": be more strict about emitting correct json + */ + Emitter JSONEmitter(shared_ptr o, Variant params = Variant::NullType); + + /** + * Supported parameters are (first is default): + * + * "scalar_style": "any"|"plain"|"single quoted"|"double + * quoted"|"literal"|"folded" + * + * "map_style": "any"|"block"|"flow" + * + * "list_style": "any"|"block"|"flow" + * + * "implicit_document_begin": false|true + * + * "implicit_document_end": false|true + * + * "indent": integer (number of spaces to indent) + * + * "width": integer (set prefered line width) + * + * "precision": integer (number of digits for floats) + */ + Emitter YAMLEmitter(shared_ptr o, Variant params = Variant::NullType); + + /** + * Supported params are: + * + * "pretty": true|false + * "indent": integer (amount to indent for pretty) + * "precision": integer (number of digits for floats) + */ + Emitter XMLPLISTEmitter(shared_ptr o, Variant params = Variant::NullType); + /** + * Supported params are: + * + * "precision": integer (number of digits for floats) + */ + Emitter BundleHdrEmitter(shared_ptr o, Variant params = Variant::NullType); + + /** + * No parameters supported. + */ + Emitter MsgPackEmitter(shared_ptr o, Variant params = Variant::NullType); +} +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/EmitterOutput.h b/src/hos_libvariant/include/hos_libvariant/EmitterOutput.h new file mode 100644 index 00000000..ffc5b1e8 --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/EmitterOutput.h @@ -0,0 +1,87 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + * + * The end user should not need to look at this file unless they are + * creating custom outputs for the emitters. + */ +#ifndef VARIANT_EMITTEROUTPUT_H +#define VARIANT_EMITTEROUTPUT_H +#pragma once +#include +#include + +namespace libvariant { + + class EmitterOutput { + public: + virtual ~EmitterOutput(); + /// Return the number of bytes written, or throw an exception + virtual unsigned Write(const void *ptr, unsigned len) = 0; + virtual void Flush() {} + virtual unsigned NumBytesWritten() const = 0; + }; + + class EmitterFileOutput : public EmitterOutput { + public: + EmitterFileOutput(FILE *f, bool c); + ~EmitterFileOutput(); + virtual unsigned Write(const void *ptr, unsigned len); + virtual void Flush(); + virtual unsigned NumBytesWritten() const { return num_bytes; } + protected: + FILE *file; + unsigned num_bytes; + bool cls; + }; + + class EmitterFilenameOutput : public EmitterFileOutput { + public: + EmitterFilenameOutput(const char *filename, const char *mode="w"); + }; + + class EmitterStreambufOutput : public EmitterOutput { + public: + EmitterStreambufOutput(std::streambuf *sb, bool d); + ~EmitterStreambufOutput(); + virtual unsigned Write(const void *ptr, unsigned len); + virtual void Flush(); + virtual unsigned NumBytesWritten() const { return num_bytes; } + protected: + std::streambuf *streambuf; + unsigned num_bytes; + bool del; + }; + + class EmitterMemoryOutput : public EmitterOutput { + public: + EmitterMemoryOutput(void *ptr, unsigned len, unsigned *out_len = 0); + + virtual unsigned Write(const void *ptr, unsigned len); + + virtual unsigned NumBytesWritten() const { return *out_length; } + protected: + void *data_ptr; + unsigned length; + unsigned out_length_dummy; + unsigned *out_length; + }; + +} +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/Exceptions.h b/src/hos_libvariant/include/hos_libvariant/Exceptions.h new file mode 100644 index 00000000..20c33383 --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/Exceptions.h @@ -0,0 +1,88 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_EXCEPTIONS_H +#define VARIANT_EXCEPTIONS_H +#include +#include +#include + +#include "../../../src/include/Variant/VariantDefines.h" +namespace libvariant { + + /// \brief Exception thrown when a key does not exist. + class KeyError : public std::runtime_error { + public: + KeyError(const std::string &key) throw(); + }; + + /// \brief Exception thrown when internal state is corrupt. + class UnknownTypeError : public std::runtime_error { + public: + UnknownTypeError(VariantDefines::Type_t type) throw(); + }; + + /// \brief Exception thrown when a function expects a specific type but the action type conflicts. + class UnexpectedTypeError : public std::runtime_error { + public: + UnexpectedTypeError(VariantDefines::Type_t expected, VariantDefines::Type_t value) throw(); + UnexpectedTypeError(const std::vector &expected, VariantDefines::Type_t value) throw(); + }; + + /// \brief Exception thrown when a function cannot convert the Variant to an acceptable type for the routine. + class UnableToConvertError : public std::runtime_error { + public: + UnableToConvertError(VariantDefines::Type_t sourcetype, const std::string &targettype) throw(); + }; + + /// \brief Exception thrown when trying to index a type other than map or list. + class TypeNotIndexableError : public std::runtime_error { + public: + TypeNotIndexableError(VariantDefines::Type_t type) throw(); + }; + + /// \brief Exception thrown when attempting a numeric operation on a non numeric type. + class NotNumericTypeError : public std::runtime_error { + public: + NotNumericTypeError(VariantDefines::Type_t type) throw(); + }; + + /// \brief Exception thrown from path functions + class BadPathError : public std::runtime_error { + public: + BadPathError(VariantDefines::Type_t type) throw(); + BadPathError(const std::string &msg) throw(); + }; + + class InvalidReferenceError : public std::runtime_error { + public: + InvalidReferenceError(const std::string &msg) throw(); + }; + + class InvalidOperationError : public std::runtime_error { + public: + InvalidOperationError(VariantDefines::Type_t type, const std::string &opname) throw(); + }; + + std::ostream &operator <<(std::ostream &os, VariantDefines::Type_t type); + + void AddStackTrace(std::ostream &os, int level); +} +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/Extensions.h b/src/hos_libvariant/include/hos_libvariant/Extensions.h new file mode 100644 index 00000000..a3f615bc --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/Extensions.h @@ -0,0 +1,92 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author Josh Staley + * \brief Useful extension functions for Variant + */ + +#ifndef VARIANT_EXTENSIONS_H +#define VARIANT_EXTENSIONS_H + +#include "../../../src/include/Variant/Variant.h" + +namespace libvariant { + + /// \brief Returns a default parameters for use with FlattenPath and ExpandPath functions. + Variant ExtensionParams(); + + /// \brief Sets any missing Extension parameters to 'params' for use with FlattenPath and ExpandPath functions. + void ExtensionParams( VariantRef params ); + + /// \brief Returns a version of 'var' with flat paths based on 'params' + Variant FlattenPath( const Variant &var, Variant params = ExtensionParams() ); + + /// \brief Returns a version of 'var' with expanded paths based on 'params' + Variant ExpandPath( const Variant &var, Variant params = ExtensionParams() ); + + /// \brief Flattens 'var' paths to 'flat' based on 'params' + void FlattenPathTo( VariantRef flat, const Variant &var, Variant params = ExtensionParams(), std::string prefix = "" ); + + /// \brief Expands 'var' paths to 'expand' based on 'params' + void ExpandPathTo( VariantRef expand, const Variant &var, Variant params = ExtensionParams() ); + + /// \brief Returns a string string map representation of 'var' based on 'params' + std::map + FlattenPathToStrStrMap( const Variant &var, Variant params = ExtensionParams() ); + + /// \brief Returns a variant representing elements in 'compare' that differ from 'base' recursively + Variant RDiff( const Variant &base, const Variant &compare ); + + /// \brief Sets elements into 'diff' from 'compare' that differ from 'base' recursively + void RDiff( VariantRef diff, const Variant &base, const Variant &compare ); + + /// \brief Updates 'base' with entries in 'update' recursively + void RUpdate( VariantRef base, const Variant &update ); + + /// Perform an operations on v according to RFC6901 and RFC6902. + // Note that JSON Pointer is ambiguous without the presence of a document. + // These function throw if the lookup fails because of incorrect types or + // on ambiguity. + // On return (or throw) the operation will have either succedded or no + // change will have been made. + + /// Add data to v at the spot specified by pointer + void JSONPointerAdd(const std::string &pointer, VariantRef v, Variant data); + /// Remove the element in v at the spot specified by pointer + void JSONPointerRemove(const std::string &pointer, VariantRef v); + /// Replace the value at pointer with data, error if the location does not already exist + void JSONPointerReplace(const std::string &pointer, VariantRef v, Variant data); + /// Move the value from src to dst (equivalent to get(src), remove(src), add(dst) + void JSONPointerMove(const std::string &src, const std::string &dst, VariantRef v); + /// Copy the value from src to dst (equivalent to add(dst, get(src).Copy())) + void JSONPointerCopy(const std::string &src, const std::string &dst, VariantRef v); + /// Perform a lookup into v according to RFC6901, return a reference to the value at the location + VariantRef JSONPointerLookup(const std::string &pointer, VariantRef v); + + std::string FormJSONPointer(const Path &path); + + /// Perform a patch operation on v with the patch as described by diff according to RFC6902 + // Returns true if the patch is applied and all tests pass, + // false if any tests failed and no patch is applied + std::pair JSONPatch(VariantRef v, const Variant &diff); + + /// Create a diff suitable to give to JSONPatch to transform src into dst. + Variant JSONDiff(const Variant &src, const Variant &dst); + +} // namespace libvariant + +#endif /*#ifndef VARIANT_EXTENSIONS_H*/ diff --git a/src/hos_libvariant/include/hos_libvariant/GuessFormat.h b/src/hos_libvariant/include/hos_libvariant/GuessFormat.h new file mode 100644 index 00000000..9687d863 --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/GuessFormat.h @@ -0,0 +1,23 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_GUESSFORMAT_H +#define VARIANT_GUESSFORMAT_H + +#pragma once +#include "../../../src/include/Variant/Variant.h" +#include "../../../src/include/Variant/Parser.h" +namespace libvariant { + + /// + // Try to guess the format of the input without removing any + // input from the input object. + // + // Currently only looks at the first non-whitespace character + // and if it is '<' then says XMLPLIST, otherwise says YAML + // if enabled otherwise JSON. + // + SerializeType GuessFormat(ParserInput* in); +} +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/Parser.h b/src/hos_libvariant/include/hos_libvariant/Parser.h new file mode 100644 index 00000000..b430d835 --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/Parser.h @@ -0,0 +1,158 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_PARSER_H +#define VARIANT_PARSER_H + +#pragma once +#include +#include +#include "../../../src/include/Variant/Blob.h" +#include "../../../src/include/Variant/ParserInput.h" +#include "../../../src/include/Variant/Variant.h" +#include + +namespace libvariant { + + class ParserImpl; + + class ParserActions { + public: + virtual ~ParserActions(); + virtual void BeginDocument(ParserImpl *p) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void EndDocument(ParserImpl *p) + { throw std::runtime_error("Parser: Unexpected event"); } + // If length < 0, unknown length + virtual void BeginMap(ParserImpl *p, int length, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void EndMap(ParserImpl *p) + { throw std::runtime_error("Parser: Unexpected event"); } + // If length < 0, unknown length + virtual void BeginList(ParserImpl *p, int length, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void EndList(ParserImpl *p) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Alias(ParserImpl *p, const char *anchor) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Scalar(ParserImpl *p, double v, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Scalar(ParserImpl *p, const char *str, unsigned length, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Scalar(ParserImpl *p, bool v, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Null(ParserImpl *p, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Scalar(ParserImpl *p, intmax_t v, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Scalar(ParserImpl *p, uintmax_t v, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Scalar(ParserImpl *p, BlobPtr b, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + }; + + /// The class that parser implementations override + class ParserImpl { + public: + virtual ~ParserImpl(); + /** + * Attempt to parse some actions. + * At least one ParserActions should be on the action stack. + * + * Run is not guaranteed to be recursively callable from inside a + * ParserActions callback. Do not do that. + * + * return 0 on success + * return 1 when done + * return -1 if needing more data is detected (not all parsers support this; can be treated as an error) + * throw on error + */ + virtual int Run() = 0; + + /** + * Push a new ParserActions handler onto the action handler stack. + */ + virtual void PushAction(shared_ptr action) { action_stack.push_back(action); } + + /** + * Pop the top ParserActions handler off the action handler stack and + * return it. + */ + virtual shared_ptr PopAction() { + if (action_stack.empty()) + { throw std::runtime_error("Parser: Attempting to parse an actions without any action handlers"); } + shared_ptr ret = action_stack.back(); + action_stack.pop_back(); + return ret; + } + + /** + * Access the top ParserActions + */ + ParserActions *TopAction() { + if (action_stack.empty()) + { throw std::runtime_error("Parser: Attempting to parse an actions without any action handlers"); } + return action_stack.back().get(); + } + + /** These three functiosn can be used to query the state + * later. + * Done means that a call to Process will immediately return 1 + * Error if Process threw an exception last + * Ok if everything looks good (Process never been called, or last return 0 or possibly -1) + */ + virtual bool Done() const = 0; + virtual bool Error() const = 0; + virtual bool Ok() const = 0; + /// Return a string describing the last error suitable for presentation to a user + virtual std::string ErrorStr() const = 0; + /// Reset the parser + virtual void Reset() = 0; + protected: + std::deque< shared_ptr< ParserActions > > action_stack; + }; + + class Parser { + public: + Parser(); + Parser(shared_ptr pi); + ~Parser(); + /// 0 on success, 1 when done, -1 other problem, throw on error + int Run() { return impl->Run(); } + /// Push an action handler onto the action stack. + void PushAction(shared_ptr action) { impl->PushAction(action); } + /// Pop the top action handler off the stack. + shared_ptr PopAction() { return impl->PopAction(); } + + /// Query state + bool Done() const { return impl->Done(); } + bool Error() const { return impl->Error(); } + bool Ok() const { return impl->Ok(); } + /// Return a string describing the last error suitable for presentation to a user + std::string ErrorStr() const { return impl->ErrorStr(); } + /// Reset the parser if applicable (some types will throw) + void Reset() { impl->Reset(); } + + /// Internal/advanced function to get the underlying implementation + shared_ptr GetImpl() { return impl; } + private: + shared_ptr impl; + }; + + shared_ptr CreateParserInput(const std::string &str); + shared_ptr CreateParserInput(const char *str); + shared_ptr CreateParserInput(const void *ptr, unsigned len); + shared_ptr CreateParserInputFile(const char *filename); + shared_ptr CreateParserInputFile(FILE *f); + shared_ptr CreateParserInputFile(std::streambuf *sb); + + Parser CreateParser(shared_ptr i, SerializeType type); + Parser CreateParserGuess(shared_ptr i); + Parser JSONParser(shared_ptr i); + Parser YAMLParser(shared_ptr i); + Parser XMLPLISTParser(shared_ptr i); + Parser BundleHdrParser(shared_ptr i); + Parser MsgPackParser(shared_ptr i); +} +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/ParserInput.h b/src/hos_libvariant/include/hos_libvariant/ParserInput.h new file mode 100644 index 00000000..5fa66311 --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/ParserInput.h @@ -0,0 +1,104 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_PARSERINPUT_H +#define VARIANT_PARSERINPUT_H +#pragma once +#include +#include +#include +#include + +namespace libvariant { + + class ParserInput { + public: + virtual ~ParserInput(); + // Get a pointer and length to the unprocessed data that is available + // (return null on end of data) len being an in/out parameter, + // the initial value of len is how much the parser wants. An input value of zero + // in means give whatever is currently available. + virtual const void *GetPtr(unsigned &len) = 0; + + // Tell the input that the parser is done with len bytes from the last + // GetPtr + virtual void Release(unsigned len) = 0; + }; + + class ParserStreamInput : public ParserInput { + public: + ParserStreamInput(unsigned buffer_len); + virtual const void *GetPtr(unsigned &len); + virtual void Release(unsigned len); + /// return number of bytes read into ptr, 0 on EOF + // and throw on error + virtual unsigned Read(void *ptr, unsigned len) = 0; + protected: + std::vector buffer; + unsigned num; + unsigned offset; + bool eof; + }; + + class ParserMemoryInput : public ParserInput { + public: + ParserMemoryInput(const void *ptr, unsigned len); + virtual const void *GetPtr(unsigned &len); + virtual void Release(unsigned len); + protected: + const void *data_ptr; + unsigned data_len; + unsigned offset; + }; + + class ParserStringInput : public ParserInput { + public: + ParserStringInput(const std::string &str); + virtual const void *GetPtr(unsigned &len); + virtual void Release(unsigned len); + protected: + const std::string val; + unsigned offset; + }; + + class ParserFileInput : public ParserStreamInput { + public: + ParserFileInput(FILE *f); + virtual unsigned Read(void *ptr, unsigned len); + protected: + FILE *file; + }; + + class ParserFilenameInput : public ParserFileInput { + public: + ParserFilenameInput(const char *filename, const char *mode = "r"); + ~ParserFilenameInput(); + }; + + class ParserStreambufInput : public ParserStreamInput { + public: + ParserStreambufInput(std::streambuf *sb); + unsigned Read(void *ptr, unsigned len); + protected: + std::streambuf *streambuf; + }; + +} +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/Path.h b/src/hos_libvariant/include/hos_libvariant/Path.h new file mode 100644 index 00000000..53426fd3 --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/Path.h @@ -0,0 +1,100 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_PATH_H +#define VARIANT_PATH_H + +#pragma once +#include +#include +#include "../../../src/include/Variant/Exceptions.h" +namespace libvariant { + + // A simple xpath like path functionality for Variant + // + // Map keys are specified using a "/" then the key. + // List indeces are specified using [index] + // A "/" at the end of the path is ignored. + // Characters "\/[]" must all be escaped with "\" + // + // For example: + // { + // "key1": [ 1, 2, 3, { "blork": true } ], + // "key2": { + // "subkey": [ "a", { "furple": 1 }, 2 ], + // "sub/key2": true + // } + // } + // + // Then all paths enumerated are: + // Path Value + // "/" Identity + // "/key1" [ 1, 2, 3, { "blork": true } ], + // "/key1[0]" 1 + // "/key1[1]" 2 + // "/key1[2]" 3 + // "/key1[3]" { "blork": true } + // "/key1[3]/blork" true + // "/key2" { "subkey": [ "a", { "furple": 1 }, 2 ], "sub/key2": true } + // "/key2/subkey" [ "a", { "furple": 1 }, 2 ] + // "/key2/subkey[0]" "a" + // "/key2/subkey[1]" { "furple": 1 } + // "/key2/subkey[1]/furple" 1 + // "/key2/subkey[2]" 2 + // "/key2/sub\/key2" true + // + // For all these functions PathList must act like a vector + // It may be of some other type (like deque) + + class PathElement { + public: + enum Type_t { INDEX, KEY }; + PathElement(const std::string &k) : type(KEY), key(k) {} + PathElement(const char *k) : type(KEY), key(k) {} + PathElement(unsigned i) : type(INDEX), index(i) {} + + bool IsNumber() const { return type == INDEX; } + unsigned AsUnsigned() const { + if (type != INDEX) throw BadPathError("Variant path element is not a number"); + return index; + } + bool IsString() const { return type == KEY; } + const std::string &AsString() const { + if (type != KEY) throw BadPathError("Variant path element is not a key"); + return key; + } + private: + Type_t type; + unsigned index; + std::string key; + }; + + typedef std::deque Path; + + //! + // Parse the path string into path tokens. + void ParsePath(Path &parsed_path, const std::string &path); + Path ParsePath(const std::string &path); + + //! Take the set of path tokens and turn it into a path string + std::string PathString(const Path &path); + +} +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/Payload.h b/src/hos_libvariant/include/hos_libvariant/Payload.h new file mode 100644 index 00000000..6b3a11cd --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/Payload.h @@ -0,0 +1,130 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_PAYLOAD_H +#define VARIANT_PAYLOAD_H + +#pragma once +#include "../hos_libvariant/Variant.h" +#include "../hos_libvariant/Emitter.h" +#include "../hos_libvariant/Parser.h" +namespace libvariant { + + // Serialize and Deserialize a header, null byte, and a binary payload + // + // All restrictions of the given serialization format are required. + // + // Parameters for payload data location: + // "length_path": path to where the payload length should be + // placed for serialization and where the payload length should be read + // from for deserialization + // Defaults to: +#define VARIANT_PAYLOAD_LENGTH_PATH "payload/length" +#define VARIANT_BUNDLE_PAYLOAD_LENGTH_PATH "payload.length" + // "data_path": path to where the payload is located for + // serialization and path to store payload for deserialization + // Defaults to: +#define VARIANT_PAYLOAD_DATA_PATH "payload/data" +#define VARIANT_BUNDLE_PAYLOAD_DATA_PATH "payload.data" + // The defaults are the values for compatibility with the bundle format. + // + // Serialize only parameters: + // "ignore_payload": true|false (default false) + // Don't output the payload, only the header, alignment and null byte. + // If the payload exists in the Variant, use the length for the payload length + // value, if not look in parameters for the payload length value, if not there + // look in the Variant for the payload length. + // "payload_length": num + // Payload length override, put this number in as the payload length + // regardless of what size the blob is. + // Note that unless ingnore_payload is true, the emitter will try to output the whole + // payload (and no more) regardless of what this number is. + + void SerializeWithPayload(shared_ptr out, Variant v, SerializeType type, + Variant params = Variant::NullType); + Variant DeserializeWithPayload(shared_ptr in, SerializeType type, + Variant params = Variant::NullType, bool be_safe=true); + + std::string SerializeWithPayload(Variant v, SerializeType type, Variant params = Variant::NullType); + void SerializeWithPayload(const std::string &filename, Variant v, SerializeType type, + Variant params = Variant::NullType); + void SerializeWithPayload(FILE *f, Variant v, SerializeType type, + Variant params = Variant::NullType); + void SerializeWithPayload(std::streambuf *sb, Variant v, SerializeType type, + Variant params = Variant::NullType); + unsigned SerializeWithPayload(void *ptr, unsigned len, Variant v, SerializeType type, + Variant params = Variant::NullType); + + Variant DeserializeWithPayload(const std::string &str, SerializeType type, + Variant params = Variant::NullType); + /// If the be_safe parameter is false, then it is considered OK + // to __/NOT/__ copy the payload and just reference it in the BlobPtr. + // This is only safe when you know your buffer is going to stick around + // until after your done with the resulting Variant. + // (This is to support zero copy) + // No null terminated string version provided as these formats contain nulls. + Variant DeserializeWithPayload(const void *ptr, unsigned len, SerializeType type, + Variant params = Variant::NullType, bool be_safe=true); + Variant DeserializeWithPayloadFile(const char *filename, SerializeType type, + Variant params = Variant::NullType); + Variant DeserializeWithPayloadFile(FILE *f, SerializeType type, + Variant params = Variant::NullType); + Variant DeserializeWithPayloadFile(std::streambuf *sb, SerializeType type, + Variant params = Variant::NullType); + + + /// Bundle is a simple format used internally at ARL for passing around + // a textual key value map plus a binary payload. The payload is often a very large + // array of numbers that would produce unacceptable overhead to serialize into text. + // These serialize routines assume that the passed in Variant is of MapType + // and if a key named "payload.data" exists it is to be written as the payload + // of the Bundle. + // + // If a key "payload.data" does not exist, these are almost the same as using the BundleHdrEmitter + // except it adds a null byte at the end. + inline std::string SerializeBundle(Variant v) + { return SerializeWithPayload(v, SERIALIZE_BUNDLEHDR); } + inline void SerializeBundle(const std::string &filename, Variant v) + { SerializeWithPayload(filename, v, SERIALIZE_BUNDLEHDR); } + inline void SerializeBundle(FILE *f, Variant v) + { SerializeWithPayload(f, v, SERIALIZE_BUNDLEHDR); } + inline void SerializeBundle(std::streambuf *sb, Variant v) + { SerializeWithPayload(sb, v, SERIALIZE_BUNDLEHDR); } + inline unsigned SerializeBundle(void *ptr, unsigned len, Variant v) + { return SerializeWithPayload(ptr, len, v, SERIALIZE_BUNDLEHDR); } + + inline Variant DeserializeBundle(const std::string &str) + { return DeserializeWithPayload(str, SERIALIZE_BUNDLEHDR); } + /// If the be_safe parameter is false, then it is considered OK + // to __/NOT/__ copy the payload and just reference it in the BlobPtr. + // This is only safe when you know your buffer is going to stick around + // until after your done with the resulting Variant. + // (This is to support zero copy) + // No null terminated string version provided as bundles contain nulls. + inline Variant DeserializeBundle(const void *ptr, unsigned len, bool be_safe=true) + { return DeserializeWithPayload(ptr, len, SERIALIZE_BUNDLEHDR, Variant::NullType, be_safe); } + inline Variant DeserializeBundleFile(const char *filename) + { return DeserializeWithPayloadFile(filename, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleFile(FILE *f) { return DeserializeWithPayloadFile(f, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleFile(std::streambuf *sb) + { return DeserializeWithPayloadFile(sb, SERIALIZE_BUNDLEHDR); } + +} +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/Schema.h b/src/hos_libvariant/include/hos_libvariant/Schema.h new file mode 100644 index 00000000..235627c2 --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/Schema.h @@ -0,0 +1,175 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief A schema validator. + * + * This code is based on the public domain JSONv4 validator tv4. + * tv4 is available at http://geraintluff.github.com/tv4/ + */ +#ifndef VARIANT_SCHEMA_H +#define VARIANT_SCHEMA_H + +#pragma once +#include "../../../src/include/Variant/Variant.h" +#include +#include +#include +#include +namespace libvariant { + + class SchemaResult; + + class ValidationError { + public: + ValidationError(const std::string &m, const Path &dpath, + const Path &spath); + + void AddSubError(const SchemaResult &err); + + const std::string &GetMessage() const { return message; } + const Path &GetDataPath() const { return data_path; } + std::string GetDataPathStr() const; + const Path &GetSchemaPath() const { return schema_path; } + std::string GetSchemaPathStr() const; + const std::vector &GetSubErrors() const { return sub_errors; } + + std::string PrettyPrintMessage() const; + void PrettyPrintMessage(std::ostream &os, unsigned indent=0) const; + private: + std::string message; + Path data_path; + Path schema_path; + std::vector sub_errors; + }; + + class SchemaError { + public: + SchemaError(const std::string &m, const Path &spath); + + const std::string &GetMessage() const { return message; } + const Path &GetSchemaPath() const { return schema_path; } + std::string GetSchemaPathStr() const; + + std::string PrettyPrintMessage() const; + void PrettyPrintMessage(std::ostream &os, unsigned indent=0) const; + private: + std::string message; + Path schema_path; + }; + + class SchemaResult { + public: + SchemaResult(); + + void AddError(const ValidationError &err); + void AddSchemaError(const SchemaError &err); + + bool Error() const { return !errors.empty() || !schema_errors.empty(); } + bool ValidationErrors() const { return !errors.empty(); } + bool SchemaErrors() const { return !schema_errors.empty(); } + + const std::vector &GetErrors() const { return errors; } + const std::vector &GetSchemaErrors() const { return schema_errors; } + + std::string PrettyPrintMessage() const; + void PrettyPrintMessage(std::ostream &os, unsigned indent=0) const; + private: + std::vector errors; + std::vector schema_errors; + }; + + inline std::ostream &operator<<(std::ostream &os, const SchemaResult &sr) { + sr.PrettyPrintMessage(os); + return os; + } + + class SchemaLoader { + public: + class LoaderError { + public: + LoaderError(); + ~LoaderError(); + void AddError(const std::string &uri, const std::string &msg); + std::string GetErrorMessage() const { return erross.str(); } + private: + std::ostringstream erross; + }; + + typedef bool (*MissingHandlerType)(SchemaLoader*,const std::string&,LoaderError &,void*); + SchemaLoader(); + SchemaLoader(SchemaLoader *b); + virtual ~SchemaLoader(); + // Get the schema at the uri specified. + // Internal lookup first, then call HandleMissing if the uri is not internally available. + // If the schema then is still not available return Variant::NullType. + virtual Variant GetSchema(const std::string &uri); + // Add a schema to the loader at the uri specified. + // returns the schema(s) added with the corresponding uri(s) + virtual std::map AddSchema(const std::string &uri, Variant schema); + // Forget a schema with the specified uri. + virtual void ForgetSchema(const std::string &uri); + // Called when a schema is not in the loader. + // Default implementation is to call the missing handler + // or add a not found error to the LoaderError and return false + // Return true on success, otherwise false, any errors are filled into the LoaderError + virtual bool HandleMissing(const std::string &uri, LoaderError &error); + void SetMissingHandler(MissingHandlerType, void *ctx); + + static void NormSchema(Variant &schema, const std::string &uri); + //! + // A realpath function for schema URIs. + // href is the "current working directory" and base is + // possibly a relative path. + static std::string ResolveURI(const std::string &base, const std::string &href); + + struct URIInfo { + std::string href; // EX: the whole uri if matched + std::string protocol; // EX: http:// + std::string authority; // user:host@hostname:port + std::string pathname; // The path segment + std::string search; // ?q=234 + std::string hash; // #tag + }; + + //! Break a uri into its components and store them into the URIInfo struct + //! returns true if the parsing was successful + static bool ParseURI(URIInfo &info, const std::string &uri); + protected: + + static void SearchForTrustedSchemas(std::map &m, Variant schema, const std::string &uri); + MissingHandlerType missingHandler; + void *missingctx; + std::map schemas; + SchemaLoader *base; + }; + + //! Validate data against a schema. + //! + //! The schema parameter is either a schema, a string uri to a schema, or null. + //! If it is a schema then data is validated against it. + //! If it is a string then it calls loader->GetSchema() and validates data against the result. + //! If schema is null, then look for a key "$schema" in data, set schema to it and proceed as above. + SchemaResult SchemaValidate(Variant schema, Variant data, SchemaLoader *loader=0); + + //! Add the defaults specified in schema to data if they do not exist. + //! Ignores default in some combinations and types that could match multiple entries (not, + //! additionalProperties, patternProperties, etc.) + //! schema is processed the same as for SchemaValidate + void AddSchemaDefaults(Variant schema, VariantRef data, SchemaLoader *loader=0); +} +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/SchemaLoader.h b/src/hos_libvariant/include/hos_libvariant/SchemaLoader.h new file mode 100644 index 00000000..e4edd00b --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/SchemaLoader.h @@ -0,0 +1,54 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief An advanced schema loader. + */ +#ifndef VARIANT_SCHEMALOADER_H +#define VARIANT_SCHEMALOADER_H + +#pragma once + +#include "../../../src/include/Variant/Schema.h" + +namespace libvariant { + + //! The advanced schema loader will try to load missing schemas from + //! the file system and optionally curl if built. + //! If the url begins with file:// it will always use LoadFromFile + //! otherwise if the protocol is empty it will try loading from a file + //! then try loading from curl. Otherwise if the protocol is not file:// + //! it will try to load from curl. + class AdvSchemaLoader : public SchemaLoader { + public: + + //! The advanced schema loader will search for a schema in the paths + //! added to it on the file system. If the schema uri looks like a + //! relative path, then it will be searched for in the paths set with + //! this function. If no paths are added, then only absolute paths will + //! be looked up in the file system. + // + void AddPath(const std::string &path); + + virtual bool HandleMissing(const std::string &uri, LoaderError &error); + protected: + bool LoadFromFile(URIInfo &info, LoaderError &error); + bool LoadFromCurl(URIInfo &info, LoaderError &error); + std::vector< std::string > paths; + }; +} +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/SharedPtr.h b/src/hos_libvariant/include/hos_libvariant/SharedPtr.h new file mode 100644 index 00000000..fd4cef91 --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/SharedPtr.h @@ -0,0 +1,41 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_SHAREDPTR_H +#define VARIANT_SHAREDPTR_H + +#pragma once +#include "../hos_libvariant/Config.h" + +#if defined(__GXX_EXPERIMENTAL_CXX0X) || __cplusplus >= 201103L || defined(HAVE_CXX11_SHAREDPTR) +// The C++11 implementation is available +#include +namespace libvariant { + using std::shared_ptr; + using std::dynamic_pointer_cast; +} + +#elif defined(HAVE_TR1_SHAREDPTR) +// Use the tr1 implementation +#include +namespace libvariant { + using std::tr1::shared_ptr; + using std::tr1::dynamic_pointer_cast; +} + +#elif defined(USE_BOOST_SHAREDPTR) +// Use the boost implementation +#include +namespace libvariant { + using boost::shared_ptr; + using boost::dynamic_pointer_cast; +} + +#else + +#error libvariant requires a shared_ptr implementation + +#endif + +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/Variant.h b/src/hos_libvariant/include/hos_libvariant/Variant.h new file mode 100644 index 00000000..3b0173e6 --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/Variant.h @@ -0,0 +1,816 @@ +// vim: foldmethod=marker +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= + +/** \file + * + * \brief Main implementation file for Variant and related functions + */ + + +#ifndef VARIANT_VARIANT_H +#define VARIANT_VARIANT_H + +#pragma once +#include "../../../src/include/Variant/Blob.h" +#include "../../../src/include/Variant/SharedPtr.h" +#include "../../../src/include/Variant/Exceptions.h" +#include "../../../src/include/Variant/VariantInternal.h" +#include +#include +#include +#include +#include +#include +#include + +namespace libvariant { + + /** \brief The Variant class. + * This is a variant type inspired by types from several different + * scripting languages. + * + * \author John Bridgman + * + * This class gives the power and convenience of a scripting language variable + * to C++ with all the same /downsides/ that such a variable has as well. The + * main idea is that things should be simple, lists are behind the scenes an + * std::vector and maps are an std::map. + * + * A Variant may be null, a number, a string, a boolean, a reference to a list, + * or a reference to a map. This means that const Variant of a map is not a + * const map but a const reference. Lists and maps are reference counted. If + * one wants to copy use the Copy member function. + * + * If you need a reference to a Variant to assign to it or change its type, + * use VariantRef. + * A const Variant & should be used for an immutable reference. + * E.g., void foo(VariantRef inout_param, const Variant &in_param); + * That is to say, if you think you want Variant &, you don't, you want + * VariantRef. + * The library is written so that: + * Variant v; + * void bar(Variant &); + * bar(v["foo"]); + * is a compile error. + * But + * Variant v; + * void moo(const Variant &); + * moo(v["moo"]); + * is correct. + * + * + * Note that this implementation will let you create a back reference (i.e., a + * map with itself as a member) but unless the user explicitly breaks it, it + * will result in a memory leak. Checking for this case was deemed too + * expensive. + * + * A Variant will only change its own type if the type is null. That is to say + * that a null Variant that gets treated as a map will become a map. But, a + * Variant of any other type will never automatically convert. + * + */ + class Variant : protected Internal::Data, public VariantDefines { + public: + + typedef VariantRefImpl VariantRef; + + typedef std::vector List; + typedef std::map Map; + + typedef Map::iterator MapIterator; + typedef Map::const_iterator ConstMapIterator; + typedef List::iterator ListIterator; + typedef List::const_iterator ConstListIterator; + + Variant() {} + Variant(VariantDefines::Type_t type) { Assign(type); } + Variant(bool v) { Assign(v); } + + Variant(int v) { Assign(v); } + Variant(unsigned v) { Assign(v); } + Variant(long v) { Assign(v); } + Variant(unsigned long v) { Assign(v); } + Variant(long long v) { Assign(v); } + Variant(unsigned long long v) { Assign(v); } + Variant(double v) { Assign(v); } + Variant(long double v) { Assign(v); } + + Variant(BlobPtr b) { Assign(b); } + + Variant(const std::string &v) { Assign(v); } + Variant(const char *v) { Assign(v); } + Variant(const Variant &v) { Assign(v); } + Variant(const VariantRefImpl &v) { Assign(v); } + + /// Construct a list from a std::vector. + template + Variant(const std::vector &v) { Assign(v); } + + /// Construct a map from a std::map. + template + Variant(const std::map &v) { Assign(v); } + + ~Variant(); + + Variant &operator=(const Variant &o) { Assign(o); return *this; } + + Variant &operator=(VariantDefines::Type_t v) { Assign(v); return *this; } + Variant &operator=(bool v) { Assign(v); return *this; } + Variant &operator=(int v) { Assign(v); return *this; } + Variant &operator=(unsigned v) { Assign(v); return *this; } + Variant &operator=(long v) { Assign(v); return *this; } + Variant &operator=(unsigned long v) { Assign(v); return *this; } + Variant &operator=(long long v) { Assign(v); return *this; } + Variant &operator=(unsigned long long v) { Assign(v); return *this; } + Variant &operator=(double v) { Assign(v); return *this; } + Variant &operator=(long double v) { Assign(v); return *this; } + Variant &operator=(BlobPtr v) { Assign(v); return *this; } + Variant &operator=(const std::string & v) { Assign(v); return *this; } + Variant &operator=(const char * v) { Assign(v); return *this; } + + template + Variant &operator=(const std::vector &v) { Assign(v); return *this; } + template + Variant &operator=(const std::map &v) { Assign(v); return *this; } + + // Type query functions + + Type_t GetType() const; ///< Return the type of this Variant + + bool IsNull() const { return NullType == GetType(); } + bool IsBool() const { return BoolType == GetType(); } + bool IsTrue() const { return (BoolType == GetType()) && AsBool(); } + bool IsFalse() const { return (BoolType == GetType()) && !AsBool(); } + bool IsNumber() const + { return IntegerType == GetType() || UnsignedType == GetType() || FloatType == GetType(); } + bool IsInt() const { return IntegerType == GetType(); } + bool IsUnsigned() const { return UnsignedType == GetType(); } + bool IsFloat() const { return FloatType == GetType(); } + bool IsString() const { return StringType == GetType(); } + bool IsList() const { return ListType == GetType(); } + bool IsMap() const { return MapType == GetType(); } + bool IsBlob() const { return BlobType == GetType(); } + + + // Accessor functions + + bool AsBool() const; ///< Return the value as a bool + long double AsLongDouble() const; ///< Return the value as a long double + double AsDouble() const { return (double)AsLongDouble(); } + uintmax_t AsUnsigned() const; ///< Return the value as an unsigned + intmax_t AsInt() const; ///< Return the value as an integer + template + T AsNumber() const { return static_cast(AsLongDouble()); } + std::string AsString() const; ///< Return the value as a string + BlobPtr AsBlob(); + ConstBlobPtr AsBlob() const; + + template + T As() const; + + /// \brief If the type is string, list, map or blob returns its size, + /// otherwise throws an exception + unsigned Size() const; + + /// \brief If the type is string, list or map return if size == 0 otherwise + /// throw an exception + bool Empty() const; + + /// \brief If the type is string, list or map, empty the container otherwise + /// set type to NullType + void Clear(); + + // List specific accessors + List &AsList(); + const List &AsList() const; + ListIterator ListBegin() ///< Equivalent to AsList().begin() + { return AsList().begin(); } + ConstListIterator ListBegin() const ///< Equivalent to AsList().begin() + { return AsList().begin(); } + ListIterator ListEnd() ///< Equivalent to AsList().end() + { return AsList().end(); } + ConstListIterator ListEnd() const ///< Equivalent to AsList().end() + { return AsList().end(); } + VariantRef At(unsigned i); //< Return a proxy/reference to the element at index i + VariantRef At(unsigned i, Variant def); //< sets to def if doesn't exist + const Variant &At(unsigned i) const; + Variant Get(unsigned i) const; //< Return the element at index i or throw + Variant Get(unsigned i, Variant def) const; //< Return the element at index i or return def + Variant &Set(unsigned i, Variant v); //< Set the element at index i to v + /// \brief Only valid when of type ListType Returns *this, so you can + /// do Variant().Append(v1).Append(v2)... + Variant &Append(Variant value); + + /// \brief If list return true if list is at least i in size, if map then convert i + /// to a string, otherwise throw + bool Contains(unsigned i) const; + /// \brief Return the index hat v is at. + /// If v is not contained in the list it return this->Size() + unsigned Index(Variant v) const; + + /// \brief If list set index i to null, if index at end, reduce size by 1 + /// throw if not a list + void Erase(unsigned i); + + // Map specific accessors + Map &AsMap(); + const Map &AsMap() const; + MapIterator MapBegin() ///< Equivalent to AsMap().begin() + { return AsMap().begin(); } + ConstMapIterator MapBegin() const ///< Equivalent to AsMap().begin() + { return AsMap().begin(); } + MapIterator MapEnd() ///< Equivalent to AsMap().end() + { return AsMap().end(); } + ConstMapIterator MapEnd() const ///< Equivalent to AsMap().end() + { return AsMap().end(); } + VariantRef At(const std::string &s); // Return a proxy/reference to the element at key s + VariantRef At(const std::string &s, Variant def); //< Sets to def if doesn't exist and return a reference to it + const Variant &At(const std::string &s) const; + + /// \brief If s in *this: return this->At(s); else throw; + Variant Get(const std::string &s) const; + /// \brief If s in *this: return this->At(s); else return def + /// Only works if type is map + Variant Get(const std::string &s, Variant def) const; + + /// \brief Set the key s to v + // returns *this + Variant &Set(const std::string &s, Variant v); + + /// \brief If map return true if s is a key in the map, if list then convert + /// s to an unsigned and the above Contains, otherwise throw + bool Contains(const std::string &s) const; + /// \brief Erase a key in a map, throws if type is not MapType + void Erase(const std::string &key); + + VariantRef operator[](int i) { return At(i); } + const Variant &operator[](int i) const { return At(i); } + + VariantRef operator[](unsigned i) { return At(i); } + const Variant &operator[](unsigned i) const { return At(i); } + + VariantRef operator[](const std::string &s) { return At(s); } + const Variant &operator[](const std::string &s) const { return At(s); } + + // Path related accessors + // These are the same as the non-path functions but take a path instead. + VariantRef AtPath(const Path &path); + VariantRef AtPath(const std::string &path) { return AtPath(ParsePath(path)); } + VariantRef AtPath(const Path &path, Variant def); + VariantRef AtPath(const std::string &path, Variant def) { return AtPath(ParsePath(path), def); } + const Variant &AtPath(const Path &path) const; + const Variant &AtPath(const std::string &path) const { return AtPath(ParsePath(path)); } + + /// \brief Like Variant::Get but it takes a path instead. + Variant GetPath(const Path &path) const; + Variant GetPath(const std::string &path) const { return GetPath(ParsePath(path)); } + /// \brief Like Variant::Get but it takes a path instead. The path is + /// very like xpath, /key[index]/key/key. See Variant/Path.h + Variant GetPath(const Path &path, Variant def) const; + Variant GetPath(const std::string &path, Variant def) const { return GetPath(ParsePath(path), def); } + + /// \brief Set the value at the path, creating elements if they do not + /// exist. throws if an intermediate path element exists but is not a + /// map or list. returns *this + Variant &SetPath(const Path &path, Variant val); + Variant &SetPath(const std::string &path, Variant val) { return SetPath(ParsePath(path), val); } + + /// \brief Erase a value at a path, if remove_empty is false only erase the very end + /// otherwise erase empty lists and maps in the path. returns *this + Variant &ErasePath(const Path &path, bool remove_empty=false); + Variant &ErasePath(const std::string &path, bool remove_empty=false) + { return ErasePath(ParsePath(path), remove_empty); } + + /// \brief Tester functions for paths, returns true if path is valid and exists. + bool HasPath(const Path &path) const; + bool HasPath(const std::string &path) const { return HasPath(ParsePath(path)); } + + /// \brief Just like Variant::Get except a reference to the value to + /// set is passed in and Variant does the casting. + template + void GetInto(T &lvalue, const std::string &s) const; + + /// \brief An into version of GetPath + template + void GetPathInto(T &lvalue, const Path &path) const; + template + void GetPathInto(T &lvalue, const std::string &path) const + { GetPathInto(lvalue, ParsePath(path)); } + + /// \brief Just like Variant::Get except a reference to the value to + /// set is passed in and Variant does the casting. + template + void GetInto(T &lvalue, const std::string &s, const T &def) const; + + /// \brief An into version of GetPath + template + void GetPathInto(T &lvalue, const Path &path, const T &def) const; + template + void GetPathInto(T &lvalue, const std::string &path, const T &def) const + { GetPathInto(lvalue, ParsePath(path), def); } + + /// \brief This type and other type must be MapType. + /// for (k, v) in other: this[k] = v + void Merge(Variant other); + + /// \brief Comparison operator + /// Returns -1 if we are less than other + /// 0 if we are equal + /// 1 if we are greater than + /// This function always returns 1 if Comparable returns false + /// This compare is not completely consistent + /// i.e. it can be such that two Variants are + /// both < and > (ex map and list types) + int Compare(const Variant &other) const; + + /// \brief Return true if this and other are comparable. Two types are + /// considered comparable if they have the same type or if they are both + /// number types. + bool Comparable(const Variant &other) const; + + void Incr(); + void Decr(); + void Add(const Variant &o); + void Sub(const Variant &o); + void Mul(const Variant &o); + void Div(const Variant &o); + void Rem(const Variant &o); + + Variant Neg() const; + + Variant &operator++() { Incr(); return *this; } + Variant &operator--() { Decr(); return *this; } + Variant operator++(int) { Variant tmp = *this; ++(*this); return tmp; } + Variant operator--(int) { Variant tmp = *this; --(*this); return tmp; } + Variant operator-() const { return Neg(); } + Variant operator+() const { return *this; } + + Variant &operator+=(const Variant &o) { Add(o); return *this; } + Variant &operator-=(const Variant &o) { Sub(o); return *this; } + Variant &operator*=(const Variant &o) { Mul(o); return *this; } + Variant &operator/=(const Variant &o) { Div(o); return *this; } + Variant &operator%=(const Variant &o) { Rem(o); return *this; } + + VariantRef Ref(); //< Return a new VariantRef to this Variant + Variant Copy() const; //< Return a copy of this Variant + Variant &Resolve(); //< Return *this or return the Variant this is a reference to + const Variant &Resolve() const; + /// Return *this or Variant referenced to if exists, otherwise create it with def. + Variant &Resolve(const Variant &def); + /// Return weather or not Resolve() const would throw. + bool Exists() const; + + /// Make this equal other. + void Assign(const Variant &other); + + void Assign(VariantDefines::Type_t type); + void Assign(bool v); + void Assign(int v); + void Assign(unsigned v); + void Assign(long v); + void Assign(unsigned long v); + void Assign(long long v); + void Assign(unsigned long long v); + void Assign(double v); + void Assign(long double v); + void Assign(BlobPtr b); + void Assign(const std::string &v); + void Assign(const char *v); + + template + void Assign(const std::vector &v) { + Assign(VariantDefines::ListType); + AsList().assign(v.begin(), v.end()); + } + + template + void Assign(const std::map &v) { + Assign(VariantDefines::MapType); + AsMap().insert(v.begin(), v.end()); + } + + protected: + Variant(const RefTag &, const Variant &o); + Variant(const RefTag &, Variant &o, Path::const_iterator b, Path::const_iterator e); + /// Reassing this reference, only available through the VariantRef interface. + /// The regular Assign makes what this is refering to equal the new value, this + /// function makes this reference refer to the new value. + void ReassignRef(const Variant &o); + friend class Internal::VTable; + }; + + typedef VariantRefImpl VariantRef; + + inline bool operator==(const Variant &lhs, const Variant &rhs) { return lhs.Compare(rhs) == 0; } + inline bool operator!=(const Variant &lhs, const Variant &rhs) { return lhs.Compare(rhs) != 0; } + inline bool operator<(const Variant &lhs, const Variant &rhs) { return lhs.Compare(rhs) < 0; } + inline bool operator>(const Variant &lhs, const Variant &rhs) { return lhs.Compare(rhs) > 0; } + inline bool operator<=(const Variant &lhs, const Variant &rhs) { return lhs.Compare(rhs) <= 0; } + inline bool operator>=(const Variant &lhs, const Variant &rhs) { return lhs.Compare(rhs) >= 0; } + + inline Variant operator+(const Variant &lhs, const Variant &rhs) { + Variant ret = lhs; + return ret += rhs; + } + inline Variant operator-(const Variant &lhs, const Variant &rhs) { + Variant ret = lhs; + return ret -= rhs; + } + inline Variant operator*(const Variant &lhs, const Variant &rhs) { + Variant ret = lhs; + return ret *= rhs; + } + inline Variant operator/(const Variant &lhs, const Variant &rhs) { + Variant ret = lhs; + return ret /= rhs; + } + inline Variant operator%(const Variant &lhs, const Variant &rhs) { + Variant ret = lhs; + return ret %= rhs; + } + + /// \defgroup variant_cast Template casting operators. + /// These are for use inside templates to extract the value of a Variant into + /// a templated type. + /// @{ + + template + struct VariantCaster { + static T Cast(const Variant &v); + }; + + // Default + template inline T VariantCaster::Cast(const Variant &v) { return T(v); } + + template + inline T variant_cast(const Variant &v) { return VariantCaster::Cast(v); } + + // Provide specializations for all the basic types + template<> inline bool VariantCaster::Cast(const Variant &v) { return v.AsBool(); } + template<> inline char VariantCaster::Cast(const Variant &v) { return (char)v.AsInt(); } + template<> inline unsigned char VariantCaster::Cast(const Variant &v) { return (unsigned char)v.AsUnsigned(); } + template<> inline signed char VariantCaster::Cast(const Variant &v) { return (signed char)v.AsUnsigned(); } + template<> inline short VariantCaster::Cast(const Variant &v) { return (short)v.AsInt(); } + template<> inline unsigned short VariantCaster::Cast(const Variant &v) { return (unsigned short)v.AsUnsigned(); } + template<> inline int VariantCaster::Cast(const Variant &v) { return (int)v.AsInt(); } + template<> inline unsigned VariantCaster::Cast(const Variant &v) { return (unsigned)v.AsUnsigned(); } + template<> inline long VariantCaster::Cast(const Variant &v) { return (long)v.AsInt(); } + template<> inline unsigned long VariantCaster::Cast(const Variant &v) { return (unsigned long)v.AsUnsigned(); } + template<> inline long long VariantCaster::Cast(const Variant &v) { return (long long)v.AsInt(); } + template<> inline unsigned long long VariantCaster::Cast(const Variant &v) { return (unsigned long long)v.AsUnsigned(); } + template<> inline float VariantCaster::Cast(const Variant &v) { return (float)v.AsDouble(); } + template<> inline double VariantCaster::Cast(const Variant &v) { return v.AsDouble(); } + template<> inline long double VariantCaster::Cast(const Variant &v) { return v.AsLongDouble(); } + template<> inline std::string VariantCaster::Cast(const Variant &v) { return v.AsString(); } + + // Allow things like variant_cast< std::vector >(v) to work + template + struct VariantCaster< std::vector > { + static std::vector Cast(const Variant &v); + }; + + template + inline std::vector VariantCaster< std::vector >::Cast(const Variant &v) { + std::vector ret; + for (Variant::ConstListIterator i(v.ListBegin()), e(v.ListEnd()); i != e; ++i) { + ret.push_back( variant_cast( *i ) ); + } + return ret; + } + + template<> inline Variant::List VariantCaster::Cast(const Variant &v) { return v.AsList(); } + + // allow things like variant_cast< std::map >(v) + // to work + template + struct VariantCaster< std::map > { + static std::map Cast(const Variant &v); + }; + + template + inline std::map VariantCaster< std::map >::Cast(const Variant &v) { + std::map ret; + for (Variant::ConstMapIterator i(v.MapBegin()), e(v.MapEnd()); i != e; ++i) { + ret.insert( std::make_pair( i->first, variant_cast( i->second ) ) ); + } + return ret; + } + + template<> inline Variant::Map VariantCaster::Cast(const Variant &v) { return v.AsMap(); } + + template + struct VariantCaster< std::complex > { + static std::complex Cast(const Variant &v); + }; + + template + std::complex VariantCaster< std::complex >::Cast(const Variant &v) { + if (v.IsNull()) { + return std::complex(); + } else if (v.IsNumber()) { + return std::complex(v.As(), T()); + } else if (v.IsMap()) { + T r = variant_cast(v.Get("real", T())); + T c = variant_cast(v.Get("imag", T())); + return std::complex(r, c); + } else if (v.IsList()) { + if (v.Size() > 1) { + return std::complex(v[0].As(), v[1].As()); + } else if (v.Size() > 0) { + return std::complex(v[0].As(), T()); + } else { + return std::complex(); + } + } + throw UnableToConvertError(v.GetType(), "std::complex"); + } + + /// @} + + template + T Variant::As() const { return variant_cast(*this); } + + template + void Variant::GetInto(T &lvalue, const std::string &s) const { + lvalue = variant_cast(Get(s)); + } + + template + void Variant::GetPathInto(T &lvalue, const Path &p) const { + lvalue = variant_cast(GetPath(p)); + } + + template + void Variant::GetInto(T &lvalue, const std::string &s, const T &def) const { + if (Contains(s)) { lvalue = variant_cast(Get(s)); } + else { lvalue = def; } + } + + template + void Variant::GetPathInto(T &lvalue, const Path &p, const T &def) const { + lvalue = variant_cast(GetPath(p, def)); + } + + class Parser; + /// \brief Takes a parser and produces a Variant from it. + Variant ParseVariant(Parser &p); + + class Emitter; + /// Takes a Variant and Emitter and emits the Variant. + Emitter &operator<<(Emitter &e, const Variant &v); + + /// \brief The different types of serialization supported. + enum SerializeType { + // Attempt to guess the format + // Cannot be specified as an output format. + SERIALIZE_GUESS = 0x0, + + // Built in text formats + SERIALIZE_JSON = 0x00000001, + SERIALIZE_YAML, + SERIALIZE_XMLPLIST, + SERIALIZE_BUNDLEHDR, + + // Built in binary formats + SERIALIZE_MSGPACK = 0x000000FF, + + }; + + + /// \brief An iterator that iterates over all documents that the parser will generate + class LoadAllIterator { + public: + typedef Variant value_type; + typedef ptrdiff_t difference_type; + typedef Variant* pointer; + typedef Variant& reference; + typedef std::forward_iterator_tag iterator_category; + + LoadAllIterator(); + explicit LoadAllIterator(Parser &parser); + Variant &operator*() { return Get(); } + Variant *operator->() { return &Get(); } + Variant &Get(); + void Next(); + LoadAllIterator &operator++() { + Next(); + return *this; + } + LoadAllIterator operator++(int) { + LoadAllIterator copy = *this; + Next(); + return copy; + } + bool operator==(const LoadAllIterator &that) const; + bool operator!=(const LoadAllIterator &that) const { return !(*this == that); } + private: + class Impl; + shared_ptr impl; + struct Value; + shared_ptr value; + }; + + // Some convenience functions + // A version is provided that will go to/from a string, + // a memory buffer, a file name, an open FILE*, and + // a streambuf* (usually acquired through iostream.rdbuf()). + + /// \brief Serialize a Variant to a string using format type. + std::string Serialize(Variant v, SerializeType type, Variant params = Variant::NullType); + /// \brief Serialize a Variant to a file using format type. + void Serialize(const std::string &filename, Variant v, SerializeType type, + Variant params = Variant::NullType); + /// \brief Serialize a Variant to a FILE pointer using format type. + void Serialize(FILE *f, Variant v, SerializeType type, + Variant params = Variant::NullType); + /// \brief Serialize a Variant to a streambuf* (iostrem.rdbuf()) using format type. + void Serialize(std::streambuf *sb, Variant v, SerializeType type, + Variant params = Variant::NullType); + /// \brief Serialize a Variant to a memory buffer of length len, using format type + //and return how many bytes produced. + unsigned Serialize(void *ptr, unsigned len, Variant v, SerializeType type, + Variant params = Variant::NullType); + + // The basic deserializing functions + + /// \brief Attempt to deserialize a string in format type to a Variant + Variant Deserialize(const std::string &str, SerializeType type); + /// \brief Attempt to deserialize a null terminated string in format type to a Variant + Variant Deserialize(const char *str, SerializeType type); + /// \brief Attempt to deserialize a pointer and length in format type to a Variant + Variant Deserialize(const void *ptr, unsigned len, SerializeType type); + /// \brief Attempt to deserialize the file to a Variant in format type + Variant DeserializeFile(const char *filename, SerializeType type); + /// \brief Deserialize from a FILE pointer to a Variant in format type + Variant DeserializeFile(FILE *f, SerializeType type); + /// \brief Deserialize from a streambuf to a Variant in format type + Variant DeserializeFile(std::streambuf *sb, SerializeType type); + + /// \defgroup deserialize_guess Guess format + /// These functions attempt to guess the type of the input. The guessing + /// function only looks at the first non-whitespace character to make the + /// decision. As such on sufficiently badly behaved input can select the + /// wrong format. + /// @{ + Variant DeserializeGuess(const std::string &str); + Variant DeserializeGuess(const char *str); + Variant DeserializeGuess(const void *ptr, unsigned len); + Variant DeserializeGuessFile(const char *filename); + Variant DeserializeGuessFile(FILE *f); + Variant DeserializeGuessFile(std::streambuf *sb); + /// @} + + /// \defgroup deserialize_all Deserialize all elements + /// These functions return an iterator. These are for format types that + /// support multiple documents in one stream. Otherwise same as Deserialize + /// functions above. + /// @{ + LoadAllIterator DeserializeAll(const std::string &str, SerializeType type); + LoadAllIterator DeserializeAll(const char *str, SerializeType type); + LoadAllIterator DeserializeAll(const void *ptr, unsigned len, SerializeType type); + LoadAllIterator DeserializeAllFile(const char *filename, SerializeType type); + /// File must remain open for as long as the iterator is referenced + LoadAllIterator DeserializeAllFile(FILE *f, SerializeType type); + /// Streambuf must exist for as long as the iterator is referenced + LoadAllIterator DeserializeAllFile(std::streambuf *sb, SerializeType type); + /// @} + + + // Serialize and Deserializing JSON + // + inline std::string SerializeJSON(Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + return Serialize(v, SERIALIZE_JSON, param); + } + inline void SerializeJSON(const std::string &filename, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + Serialize(filename, v, SERIALIZE_JSON, param); + } + inline void SerializeJSON(FILE *f, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + Serialize(f, v, SERIALIZE_JSON, param); + } + inline void SerializeJSON(std::streambuf *sb, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + Serialize(sb, v, SERIALIZE_JSON, param); + } + inline unsigned SerializeJSON(void *ptr, unsigned len, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + return Serialize(ptr, len, v, SERIALIZE_JSON, param); + } + inline Variant DeserializeJSON(const std::string &str) { return Deserialize(str, SERIALIZE_JSON); } + inline Variant DeserializeJSON(const char *str) { return Deserialize(str, SERIALIZE_JSON); } + inline Variant DeserializeJSON(const void *ptr, unsigned len) { return Deserialize(ptr, len, SERIALIZE_JSON); } + inline Variant DeserializeJSONFile(const char *filename) { return DeserializeFile(filename, SERIALIZE_JSON); } + inline Variant DeserializeJSONFile(FILE *f) { return DeserializeFile(f, SERIALIZE_JSON); } + inline Variant DeserializeJSONFile(std::streambuf *sb) { return DeserializeFile(sb, SERIALIZE_JSON); } + + //Serialize and Deserialize YAML + // + inline std::string SerializeYAML(Variant v) { return Serialize(v, SERIALIZE_YAML); } + inline void SerializeYAML(const std::string &filename, Variant v) { Serialize(filename, v, SERIALIZE_YAML); } + inline void SerializeYAML(FILE *f, Variant v) { Serialize(f, v, SERIALIZE_YAML); } + inline void SerializeYAML(std::streambuf *sb, Variant v) { Serialize(sb, v, SERIALIZE_YAML); } + inline unsigned SerializeYAML(void *ptr, unsigned len, Variant v) { return Serialize(ptr, len, v, SERIALIZE_YAML); } + + inline Variant DeserializeYAML(const std::string &str) { return Deserialize(str, SERIALIZE_YAML); } + inline Variant DeserializeYAML(const char *str) { return Deserialize(str, SERIALIZE_YAML); } + inline Variant DeserializeYAML(const void *ptr, unsigned len) { return Deserialize(ptr, len, SERIALIZE_YAML); } + inline Variant DeserializeYAMLFile(const char *filename) { return DeserializeFile(filename, SERIALIZE_YAML); } + inline Variant DeserializeYAMLFile(FILE *f) { return DeserializeFile(f, SERIALIZE_YAML); } + inline Variant DeserializeYAMLFile(std::streambuf *sb) { return DeserializeFile(sb, SERIALIZE_YAML); } + + inline LoadAllIterator DeserializeYAMLAll(const std::string &str) { return DeserializeAll(str, SERIALIZE_YAML); } + inline LoadAllIterator DeserializeYAMLAll(const char *str) { return DeserializeAll(str, SERIALIZE_YAML); } + inline LoadAllIterator DeserializeYAMLAll(const void *ptr, unsigned len) { return DeserializeAll(ptr, len, SERIALIZE_YAML); } + inline LoadAllIterator DeserializeYAMLAllFile(const char *filename) { return DeserializeAllFile(filename, SERIALIZE_YAML); } + inline LoadAllIterator DeserializeYAMLAllFile(FILE *f) { return DeserializeAllFile(f, SERIALIZE_YAML); } + inline LoadAllIterator DeserializeYAMLAllFile(std::streambuf *sb) { return DeserializeAllFile(sb, SERIALIZE_YAML); } + + //Serialize and Deserialize XML plist + // + inline std::string SerializeXMLPLIST(Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + return Serialize(v, SERIALIZE_XMLPLIST, param); + } + inline void SerializeXMLPLIST(const std::string &filename, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + Serialize(filename, v, SERIALIZE_XMLPLIST, param); + } + inline void SerializeXMLPLIST(FILE *f, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + Serialize(f, v, SERIALIZE_XMLPLIST, param); + } + inline void SerializeXMLPLIST(std::streambuf *sb, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + Serialize(sb, v, SERIALIZE_XMLPLIST, param); + } + inline unsigned SerializeXMLPLIST(void *ptr, unsigned len, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + return Serialize(ptr, len, v, SERIALIZE_XMLPLIST, param); + } + + inline Variant DeserializeXMLPLIST(const std::string &str) { return Deserialize(str, SERIALIZE_XMLPLIST); } + inline Variant DeserializeXMLPLIST(const char *str) { return Deserialize(str, SERIALIZE_XMLPLIST); } + inline Variant DeserializeXMLPLIST(const void *ptr, unsigned len) { return Deserialize(ptr, len, SERIALIZE_XMLPLIST); } + inline Variant DeserializeXMLPLISTFile(const char *filename) { return DeserializeFile(filename, SERIALIZE_XMLPLIST); } + inline Variant DeserializeXMLPLISTFile(FILE *f) { return DeserializeFile(f, SERIALIZE_XMLPLIST); } + inline Variant DeserializeXMLPLISTFile(std::streambuf *sb) { return DeserializeFile(sb, SERIALIZE_XMLPLIST); } + + //Serialize and Deserialize BundleHdr + // + // BundleHdr requires the root element to be of MapType and + // no submaps exist. + // + // Note that these do not add a null byte to the end. + // Use SerializeBundle for that. + + inline std::string SerializeBundleHdr(Variant v) { + Variant param = Variant::MapType; + return Serialize(v, SERIALIZE_BUNDLEHDR, param); + } + inline void SerializeBundleHdr(const std::string &filename, Variant v) { + Variant param = Variant::MapType; + Serialize(filename, v, SERIALIZE_BUNDLEHDR, param); + } + inline void SerializeBundleHdr(FILE *f, Variant v) { + Variant param = Variant::MapType; + Serialize(f, v, SERIALIZE_BUNDLEHDR, param); + } + inline void SerializeBundleHdr(std::streambuf *sb, Variant v) { + Variant param = Variant::MapType; + Serialize(sb, v, SERIALIZE_BUNDLEHDR, param); + } + inline unsigned SerializeBundleHdr(void *ptr, unsigned len, Variant v) { + Variant param = Variant::MapType; + return Serialize(ptr, len, v, SERIALIZE_BUNDLEHDR, param); + } + + inline Variant DeserializeBundleHdr(const std::string &str) { return Deserialize(str, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleHdr(const char *str) { return Deserialize(str, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleHdr(const void *ptr, unsigned len) { return Deserialize(ptr, len, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleHdrFile(const char *filename) { return DeserializeFile(filename, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleHdrFile(FILE *f) { return DeserializeFile(f, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleHdrFile(std::streambuf *sb) { return DeserializeFile(sb, SERIALIZE_BUNDLEHDR); } + +} + +/// Debug function not inside the namespace to print out a variant (calls SerializeJSON) +void VariantPrint(const libvariant::Variant v); + +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/VariantDefines.h b/src/hos_libvariant/include/hos_libvariant/VariantDefines.h new file mode 100644 index 00000000..6a6df997 --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/VariantDefines.h @@ -0,0 +1,50 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_DEFINES_H +#define VARIANT_DEFINES_H + +#ifdef __GNUC__ +#define DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define DEPRECATED __declspec(deprecated) +#else +#pragma message("WARNING: You need to implement DEPRECATED for this compiler") +#define DEPRECATED +#endif + +namespace libvariant { + class VariantDefines { + public: + enum Type_t { + NullType = 0, // Explicitly defined as 0 + BoolType, + IntegerType, + UnsignedType, + FloatType, + StringType, + ListType, + MapType, + BlobType + }; + + }; +} +#endif diff --git a/src/hos_libvariant/include/hos_libvariant/VariantInternal.h b/src/hos_libvariant/include/hos_libvariant/VariantInternal.h new file mode 100644 index 00000000..8479795d --- /dev/null +++ b/src/hos_libvariant/include/hos_libvariant/VariantInternal.h @@ -0,0 +1,96 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_BASE_H +#define VARIANT_BASE_H +#include +#include +#include +#include + +#include "../hos_libvariant/Blob.h" +#include "../hos_libvariant/Path.h" +#include "../hos_libvariant/SharedPtr.h" +#include "../hos_libvariant/VariantDefines.h" +namespace libvariant { + + struct RefTag {}; + + class Variant; + template class VariantRefImpl; + + + /** + * Action implementation for the VariantRef class. + */ + template + class VariantRefImpl : public Base { + public: + VariantRefImpl(const Variant &o) : Base(RefTag(), o) {} + VariantRefImpl(Variant &o, const Path &path) + : Base(RefTag(), o, path.begin(), path.end()) {} + VariantRefImpl(Variant &o, Path::const_iterator b, Path::const_iterator e) + : Base(RefTag(), o, b, e) {} + VariantRefImpl(const VariantRefImpl &o) + : Base(RefTag(), o) {} + + using Base::operator=; + using Base::As; + using Base::AsNumber; + using Base::GetInto; + using Base::GetPathInto; + using Base::Assign; + + using Base::ReassignRef; + }; + + namespace Internal { + + class VTable; + struct Storage; + struct MapStorage; + struct ListStorage; + struct ProxyStorage; + struct RefData; + + struct Data { + Data(); + const VTable *vtable; + union { + bool b; + long double f; + intmax_t i; + uintmax_t u; + std::string *s; + MapStorage *m; + ListStorage *l; + BlobPtr *blob; + Data *ref; + ProxyStorage *proxy; + }; + shared_ptr ref_data; + shared_ptr storage; + }; + } + + + +} +#endif diff --git a/src/hos_libvariant/package.xml b/src/hos_libvariant/package.xml new file mode 100644 index 00000000..dd1ffe74 --- /dev/null +++ b/src/hos_libvariant/package.xml @@ -0,0 +1,50 @@ + + + hos_libvariant + 0.0.0 + The hos_libvariant package + + + + + matzman + + + + + + TODO + + + + + + + + + + + + + + + + + + + + + + + + + + catkin + + + + + + + + \ No newline at end of file diff --git a/src/hos_libvariant/src/.hg/00changelog.i b/src/hos_libvariant/src/.hg/00changelog.i new file mode 100644 index 0000000000000000000000000000000000000000..d3a8311050e54c57c5be7cfe169e60a95768812c GIT binary patch literal 57 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 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/hgrc b/src/hos_libvariant/src/.hg/hgrc new file mode 100644 index 00000000..383f66f2 --- /dev/null +++ b/src/hos_libvariant/src/.hg/hgrc @@ -0,0 +1,2 @@ +[paths] +default = https://bitbucket.org/gallen/libvariant diff --git a/src/hos_libvariant/src/.hg/requires b/src/hos_libvariant/src/.hg/requires new file mode 100644 index 00000000..f634f664 --- /dev/null +++ b/src/hos_libvariant/src/.hg/requires @@ -0,0 +1,4 @@ +dotencode +fncache +revlogv1 +store diff --git a/src/hos_libvariant/src/.hg/store/00changelog.i b/src/hos_libvariant/src/.hg/store/00changelog.i new file mode 100644 index 0000000000000000000000000000000000000000..bba22b4820891d5eda760b436877a5fb158ad145 GIT binary patch literal 2605 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 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/_c_make_lists.txt.i b/src/hos_libvariant/src/.hg/store/data/_c_make_lists.txt.i new file mode 100644 index 0000000000000000000000000000000000000000..bd21e021f237ee8391188224fb671f10115a91a6 GIT binary patch literal 2608 zcmV-03eWWb0RRC20000000|%f03E*o0000000030|NsC0|Ns9;>^dXI<)zmE!P2!Y zi%{Dn7#`vP00000000000001ZoTXV=bE8NSewKbkhU^ElGq%V5Fb{L>V1#U@CC~zL zt0N|YKv0sHMxf>Bw!@+SzF7ySge3RA*n-N;%KR!TFLp`%5AiZ-5-gwHBygi_*zbE= z_X}~hK@@EBt&@=d=0QSy=~*=`&Cub)?axR=B6k@QCnISVL~9A(q$HD+sr*rOrp9PK zQJtA=Kf(3e!MlCGHz-~!bJJ9H+p&zfsi@9KGxv9F|GR1I=OIb&1}Hj+yfF8Pq-==y zMOiGYI8QvH#M@nfB*W&q#vjJGgrt;vB^BG%wgJmF)&I=p37pVn*zZxZ)P+2qO;pQ~ z^^s$%mTf^CiM5IL@GP5}jEo~gactRqRBiBM57*;e7Q~VCFxMs{$9j@Yb>twu1%rn? z2z^L5E+PwIuuKqrlHLx$7>|d25~f5tvG;0qa&wgTm7nGf(}P4lVt_~peQI1>wNLV7 z0)r*fN%#SL3$hJl8v-|<+%SYy=&n&aeb^~vq(00aJEge3A5cCw1fMMPH4~T$d%Hw( zbA?DMr4UQq4wN7;6*tsNuULUIiiEk2BV)y8M8b z6FZPkY3wgn~sPQc>XPa7&Ggw?I3%FAYxEk-iB=5N$mP0;hObZK0KBGGEAokH21@Ubxp6W|8%g9(M5SW zu`X8nJ-}1$+IN53T&wTdT5IfwJ^}#!D==0ok}!+&RQ&KZao`cWxDbCONfJRtY?1oTZfK|ZdGQlHt>=eRzT&AKiVYJXF z@#kqaFsuJE!(e8i<#J;qm2mJ%_hVHb3*2QL*B-Wr&0<#;Rn85T%gs;;3~Isw|6V zvI-*Kp=lCfrFHXS8-Cz-6giOOgEKbf`iS1jW7@I&!N_Wnlh&C%tdJa^pmH?AGWoIQ4|C?x?$^;hWW^YT`Rf!%cC6I_jSz2#eR8g+5$>Fe5vM zaD^KsKMNd_`TfAXy4&zV;8^YV9^^zN*9LEzu4nj@gC}Utfme`S4xZpRjb9=5JMj~x zX$`*<@D+7!CxXyX%(n3p?8b2)C5{4{7x;AzA(eQZ#;X!Xs|iu1^?!NgY@ z_4p~zW7HkEUBM>;-&p$<<33>+f1?|CwCQFcG{a)aV@)}IU$%a!yCu8@5&ZIN)vB*yeeel1F>&|h1O@)Mn`#zIm9vcVqQ_x6_w>d-O>@ zv$M_+Ho=ndWVvoUdSR$yGn|_&Ap~3AU7TbzG_|J)>SAV?b}`DU=BAuO;$~UR2}6Si zP39w`%+cE|jq-+zU*s!iK*N`M_ zTg!sA3+pgmx*_j&Z#Z%CI_zHw(`Z(eA62N0i{T1bZ%Q3?iq*C{!VVUgrgTz_%`ccw z>f~pJxPsvx+heyTfO)KqDp(|=lVo8fYqgn4Vvf=>3z%6ghdnD5J(PlUzqv+Z5oUf++s#1(K}0Zaf_*UZ6*xM$eg{$6Dku?ZAj_5+>PK3(=-|owr>q(JrX?*Gfk~sejGvtD4z?}fUWW?>LCDP->cqk6e z;ls)liYt5SyHUT_7X2?Owdu*%Z!OV#s3UUxdY1wZrM=(I`hLvU&hAOm<`y*OS4oWh z21^wa%oFKt_LBYk|NGchbT@1wgnpY~5d+L+=;RsP6tHXwGJ3ImXw)^dnnL&baQI!U zY@f)uyqm&7}gWUqA*^$Hkj59r?pm3+8qgQHOhG^**gDlI9j zE(6<~t1ZH!iuoU}XPXL7_OcM8n6^Da&2Xc zw>MPiES|l7^*8x~&T|nyhU|~l%nz1ak&&SudUSVfae(QBEmrwv2b5oZX*uZ6*5I>x w-^}&Vmm61R$#gq?H5JV%pTgA5>)vI5Y-ReYCwr#ba|t|7Pk+eUcEqI(05Qi`-v9sr literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/_doxyfile.in.i b/src/hos_libvariant/src/.hg/store/data/_doxyfile.in.i new file mode 100644 index 0000000000000000000000000000000000000000..04d86a430cfe6b1b2202a6d961b841ea374374a8 GIT binary patch literal 18722 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 R&`L*lSD-AyGyuP;I>m-gMfLyy literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/_l_i_c_e_n_s_e.i b/src/hos_libvariant/src/.hg/store/data/_l_i_c_e_n_s_e.i new file mode 100644 index 0000000000000000000000000000000000000000..b5d8a8435db0c5ae796ca06ae947653b6a962ddd GIT binary patch literal 528 zcmV+r0`L6*0RRC20000000Gbd00W)?0000000030|NsC0|Ns9*h9V`ezlNeY3f`o_ z?bK>BfWTV-00000000000001ZoUM~ji`y^|#n0`hc*hpJcCw+AZRo)poLxgU3ARJX zQI5y8K(T@($N1ZKe}_f z&>VyAa1<>JRnj^m%gzy`gJ`Qr8=Q0{YtC~X)wLBFxQ5`!oGf%bZeG?qtgZ!Ks3jv5 zwq2>@k&lnmT7s}R`xDzxUIv2d~a|eV|kCqTdgZFfHt1< zML4g(K%afyS8jWN67HTFa@gN&xT~!o+mYSqGb?Kt$@+V#6iPy8sqR!THr+Yw)8cir zD-f>_*vDBGuZzQ+gI%NfmM-*;lBcthOlDn1v~J+`J>f0M7O$KVKc}m-IIsvT(_)?E zIhLCYF}875q>J4u&amBO+fAN?Ku&b?*+c$gbv;gv?X1WNsqEc=_euQ`&Q^#E$B9zW z&4^m^dX+Acb)I;qy~Q5k-$`#IKM<$?IllmDdkh17dqP2M1!1eik?`OtdFKhU*(AWT zw$4Yt#h5%!r_+b&Z1O$8E{|_z$G2I_w(>L4V|$*l*G5&?%Zjk45ia&d SZ5?X!%M1V5zv(xRdmm`qDg@;K literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/_lib_variant_build_tree_settings.cmake.in.i b/src/hos_libvariant/src/.hg/store/data/_lib_variant_build_tree_settings.cmake.in.i new file mode 100644 index 0000000000000000000000000000000000000000..e3a6505b40c8120e244aceb08bcafc05978a3ea5 GIT binary patch literal 127 zcmZQzWME`~0DB;12W2z-hk|_lO&4S?MXau`UcL32$#oA&*JoWYH6Xf_t2nhp!^hJp z%rVH*(Jv(4)6dx_)WtR4#WN_Fi&M!VAjsd#)j1?S*grJL87%CepP84OQ<{>hq{#&U D8iOTI literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/_lib_variant_config.cmake.in.i b/src/hos_libvariant/src/.hg/store/data/_lib_variant_config.cmake.in.i new file mode 100644 index 0000000000000000000000000000000000000000..409a060ff8ce61c1bfcb6d68a6349d3de1496147 GIT binary patch literal 705 zcmZQzWME_f1I9iE2Btp{HUq{f9E{E`F|f z;?nE(%6aF)Q>U(b^rmiNNVkc;n)rg=SNyzAi)FPo`56ZWNKd`jSUK~vk)|5Y+tRmB z7!*!RZ)UyenQO!8cC>7}y}+j6TNM`-LlrwFTCWj_k8EyRB>b$x^1tPbrk6kGKUUj! z{&R|e?x|O5XD3b9ymR*S?U@&Hr`UYT6l}9ss{ARa|5Pk_rCEiizscNA&hpd+b}#lZ z7Ih>Ux%JyUJyBwNtw1(GbupL9qq4tCZyDNOPI_;cRM!9hsAcZY;>qD3t4f2PdX`z$ zi$?e!mP}uG;_Ja)U;EGA?|-uOaxHZ~CB;?S&Y!U5V$K;kdHvXXYd;%BGI$=pTAlai zcjV^9H;h^*&YAmeq2?N$1ZCigw7U%s{9+m!Z5KT!MoBv6ci z;t>coGcYjk2D5++5DkjZ=-lP=7ay2@>d>UH7{F4nZnxd6JzAgzc6s>elP#!m}1%A%RfT}7g^tam$$wyfAQ)pw~j4Kc0I4*;=JIuQT> literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/_lib_variant_config_version.cmake.in.i b/src/hos_libvariant/src/.hg/store/data/_lib_variant_config_version.cmake.in.i new file mode 100644 index 0000000000000000000000000000000000000000..741dcd29eb0a4cbbe17b02356a70912d058c30b5 GIT binary patch literal 252 zcmZQzWME`~fISQhj8#xJ!+$84zx%_YjniUJr|&nYS~z`$n?%>rGME|=T`{M%|14jV zfk4aoZ<=N=81FST9W@Da`1hz+L#MH$UgYt?5AVJ)v`I8gzk4>t=(Fy`8?WrPZZA1} zsfAVXd&~u&gKJyZ=IpwtFl&}$gU&%cL+itPojD(OuiB{)?1JeF@i!kT`V0udEps<|1mT^%nbtoD&lag literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/_r_e_a_d_m_e.i b/src/hos_libvariant/src/.hg/store/data/_r_e_a_d_m_e.i new file mode 100644 index 0000000000000000000000000000000000000000..a9cf861408fd19ec9edb680409befaa5fe08c3a0 GIT binary patch literal 1530 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 N5jOhO{s7HN?RG;u(~kfE literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/cmake/_modules/_find_lib_y_a_m_l.cmake.i b/src/hos_libvariant/src/.hg/store/data/cmake/_modules/_find_lib_y_a_m_l.cmake.i new file mode 100644 index 0000000000000000000000000000000000000000..2aeff885884223b67dcdc55aea7da07035c448c6 GIT binary patch literal 424 zcmZQzWME_f1I7#n2Bw7&HUq)#CH*iZ*#`{oxM3?&EXMtrDcRc3m@D#hSHg+q&EGZ@=haqUL)9R){>Gs`O{txt%=^sYl>FqZZa}Ix$jhE(1|6Fre|6! zZ~1Y7x9Y_7>o;frynkQ(7>6*^tJ@zV?X(jfvaObwSC{V=uIuHWVpO&`_R-|ZgFKN^ z-<@}O>?mAU@1Uk^u}11^!HUHfR9Gf5=2&>}=HQ0%_Ob%Fz4lLpI0hgKDW~C@U(Rcudcdut#OgL`{%T&rngvg9IZ|q$?AUS zrdB!QU4=?z5XYwfSzE6fdAH^G?#v zZ*or>WsDc?=6d+Qcy`AA^yQkD?(Oc~vENk6^z+0&&+6{|5L7njt@r(Gmt}ZiSx)P= z!hftLcOGa>%05#m~|%6)3aXwPe6A|^|6^|#J8=UX4xc*A>5@|3vmS6S1!>I;=)%#S{d R@TzqdsTTjkz;$~`5&&a%kyHQx literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/examples/_c_make_lists.txt.i b/src/hos_libvariant/src/.hg/store/data/examples/_c_make_lists.txt.i new file mode 100644 index 0000000000000000000000000000000000000000..e8da8afc8ac351e95445f6d68a993ac2d9ec0ec4 GIT binary patch literal 242 zcmZQzWME`~fK3bxOiQ6`hW}9T?5WD<&1#uf9dt61?J|;LqD1~Cz|?@~iaAqzH*y^^ z5OMupt8#(5N@hv%H~*IhGIN|iKTtL~qTYYCaDVKHvsF8*#d>NRHa6dq zn)CUg#{%c?_S+hVA`q@3X*SX5AYk7G0UsFBfCDHGK0C^{Di~s-t literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/examples/_r_e_a_d_m_e.i b/src/hos_libvariant/src/.hg/store/data/examples/_r_e_a_d_m_e.i new file mode 100644 index 0000000000000000000000000000000000000000..dfea5a7a4ace167c880a75154e6a8656ac0bfc71 GIT binary patch literal 366 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 REdO*d=j~1TFZcab1OUiK*q#6Y literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/examples/example2.cc.i b/src/hos_libvariant/src/.hg/store/data/examples/example2.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..2df50ca1c5921c302f6679a62d8b1dff23116ef4 GIT binary patch literal 716 zcmV;-0yF&p0RRC20000000N8v00kic0000000030|NsC0|NsBD*MZVHcc0W85F6=^ zHx%Rg4w_;B00000000000001ZoP|`|PTN2beYU@1NQLBtG%0;_010{%74!v)R5ew! z*kgO!%{tm$8)%h(?^$0`1FiaCdAxJxa%RqYKAF%mlZr!vAu3mthCY^srZXecd@Xe2 zxHXb9f;kVv7g8sxN|}ysgpoqKdH0?bCj+N-sVx0bSXrraQu4NLadF%QEW%J~M{6N< z3o|jR8E1MxU+7Ii`I}Qg14^@-NbNW=?kz!|w@5NebCRZ?ZDOw`+?A%_8O*DQ?yuj~c@|w3Sb(o5cx&Gsq&k>4$+l=SUzNP9-?u`;2pJaXg+9w+HWZ>f0l^ zcgzbqIFK#l9p&X{-!4Z4F7o9`CXIEoWQEEdr@(@7Qcwi1Wspl}AJ|=kQ$M>P5teD# zllR8YJr~ltoh$g)oSdneF=3pB#gE2JITMv~@snc+sd;u(^r-3CFZi$NpHTPP_6zQ@ zq)SaU5el;Oa69WWqRN&S3#48=p3HyMqX2p&pXZu^8hol&4v(N=AUHP{jIQMK_95d)4@&@lbYK+~ctSXS`a3+weDXa-b9S3smm_ literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/examples/list__example.cc.i b/src/hos_libvariant/src/.hg/store/data/examples/list__example.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..3e99f72e6fa64d5e4f1f7ce33851d008462dfb4d GIT binary patch literal 503 zcmVeizJfoJwB23Y6WjcGN?cvdg9)B_~v>GPoBEdplvENp703r ztkoy7t(iK6-K+MbE!Xp1^$-6P$p!YPhX*wUvL`UqoHK5-nF(8^$TAF?Y#ATgpV~FF zz4owLNpN1mZ&l1-5eUL4>KeXk3pxZkS>PUlFQXg|G|UZRusAy3;sPi|4JIP@niIT& zmn-p|i~-|ZK+yIg5@y24>U9StRamVdadk3~;SB-~BVX3yeGLES>@+m!=X9^nxwm*G z+aaSL$ZE#iX${D2wNynCzlYcBh`vkwBL23yw7)$_mHqTLaTgN{-L#85lpjts(+914 zPjg9<6ks1|(Uvjm%s3=QY!PJWV*DqgcOa7hR4iTinYJzf&U;}N|V z3cD&hsvgHtRLakHUzXWYPQ>M3l?0|#A*+FMvT=bTK=O~N+)&zo t5xCoIS~oH5GGtGO>M=aC7wK{tvk4--j5PjGg-4#e6;<`2)E{lx?X5I7=O+LF literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/examples/map__example.cc.i b/src/hos_libvariant/src/.hg/store/data/examples/map__example.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..8abf93d39aa0baecd406aeb6bfac206aacafebdb GIT binary patch literal 703 zcmV;w0zmx$0RRC20000000Msi00hAR0000000030|NsC0|NsAahM2l(T|>IS;S?EO zSyXJJDDqwa00000000000001ZoLy7FPTVjMJ+HrFnjV@gbhlmF%Lb52g(@o13y2Hl z;7ukQi>$q}oka-o?|rtD-NGsM8_%0JGcWV$l>RoVV?j8`-nYimZ_{eJu&Q2fq>h1= zRooDcbMaB>s_Sc}(>rOE)P6pEXYKiaLFpXZcbGEHTb7%1(L1Hr)Tz}j4NhyTV zo;FhHJRGE5SI1Pf($aK_%dVgoF&Q4?*|rpu`J8TBCjY!;G7U)@!%xb$ zG8zi{%A-l;V(3rbb+^bAlcYEY=j_S_I4_EU9in{@EceezI&x++R0Z!2xsH@4Z@?>k z42TKX?z2aJ&K~HDvYqUD&dLFTuC8_HW)5eEk zTlT%xX_JnzhC1?WrIj1@Y-jtmCNgaH7Ukk*58^O}qzu#VWSc!CHR(c6SamFS5aCSB zfin2*;2`8&^nT21k+)*jB)zw{4`jA%CA__F8Y16&IS9maO-~$Z5i(F+`Q(_(aLZEzaYPNu<#*#x zdM&qCKGh%*Z5hB;+S}ZE_EFWlKODQB^@29WEkh`<+3tRaC%DW^LYc`#dEf# lY{1eMXFuGHx9Be~0v;1t*IgN0HA!2iFQs@D{{S#df#+S`RlooM literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/examples/pretty__print.cc.i b/src/hos_libvariant/src/.hg/store/data/examples/pretty__print.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..2d53158bfd7b0285867f6bee32a44cbb2910c98e GIT binary patch literal 641 zcmV-{0)G7f0RRC20000000Kb(00iX#0000000030|NsC0|Ns9Di9L##2CHfBA!lzY z({@fQ0SkBl00000000000001ZoP|@{j@mE~eI{QqN~H=|b1m%yu$8v$KJ03HQIT4; z5FsaVh*igl90wK<|K72aWwTIG31QF0XU@!-^xAD$L|iZj@Inh6rwZ=VSi%Rz!&O41 z4fu+)2=Ll-UU3V9H3TtLz#eIm3AQYs&ONvWx6|ps9(Xv0ISj}U$QuG9kCbS}8Ko%!pDF?? z^OqnFhV_Prp|?43q6GgwoB zIGK#A)O@9FK#v&@i2r6Z)o@)?3K%g*LOk zpMCuTIz_6XNh<|dF^NS2IF^E_kb&l@Tu5Ynq?A!b6SVC)cQcFans&`Fp95TmOllh# zqIY)e;K;A5LcfTbEn?cNcVhUFvd~#W)?hLePnEhK1*58I5_`R>Hp;7GTYAt(e}s$N ztVz^PtVkGsU8&XgCY5snRq*N>Ybn8GvvjoJ3ITNI^2I?o*aj67;39hYmQAwM6s%7h(V_nAoK%Ojz b>7}+Dmv9db{+tF*qEHfW6AsQ_883`KLz*n5 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/include/_variant/_arg_parse.h.i b/src/hos_libvariant/src/.hg/store/data/include/_variant/_arg_parse.h.i new file mode 100644 index 0000000000000000000000000000000000000000..36b506ea2b67903fa504cf54650c60fc404ae203 GIT binary patch literal 3922 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 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/include/_variant/_blob.h.i b/src/hos_libvariant/src/.hg/store/data/include/_variant/_blob.h.i new file mode 100644 index 0000000000000000000000000000000000000000..33a64ce61a4fa3d8b4bb315f8d9e25cfba6a9e45 GIT binary patch literal 770 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 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/include/_variant/_emitter_output.h.i b/src/hos_libvariant/src/.hg/store/data/include/_variant/_emitter_output.h.i new file mode 100644 index 0000000000000000000000000000000000000000..478230989306df35db51d9f7d358a87a6078b0bf GIT binary patch literal 1081 zcmV-91jhRS0RRC20000000a2|01BJ{0000000030|NsC0|NsA`GpQXmGpFrK;?Gre zr}zaDS2&pf00000000000001ZoYj@zZ{j!*$DfD`WF^z3lD+dXapfTmfY92d_z%4MDhDt-BQl62Y^-@lzsKMq47Ik4jW#!M8 z!36F$8+<{Dnh6-XSn!0*2}*;&3@p6G_6l=eC`W_<=4)WZAKDeN@}W_PYFT6PG-F548iEVXmBpv-cTr2JQ02#67! z!OV$f8ML!7?MJr{lL$J4N0@d-qs}0DY|~JFjqYan^)uWvpL)-+{AF=jZ1i&o9n?ZNg;S*=}3*X2xaeYof~V zyv9^%k;0Ux2vdxKN|sx@xD3P9YSqe2)>3-z6aUGlsnLMHJe&Y%z#J7_!yhV_aIJYd zFPJPRV$CrF8u~wv9VvY3BMpYSgyNRUf<$T$!YGvb+sAKxf0p2#6ljdkbPa^nizFI} ztDHmP2v`BsYYS&hS!-VhEV!kfr&>cJ3{H7Q2Q`B~JEJ}|+pK%vkD~5~+IBdJX1Bp9 zO>&9H=NFn$GK4!p5|fE=#QAq)Q?6S1=RFfwCR?SSgFvzZ&BB+Mj@XiEPE8L_L2!}? zM!9sW_#Voz$$nB^2FYb`aJJG_3-nb=4M?(sTPYhaQ!A!{V~K7n5%xdgE2=_3ygS$eIuAUX;&pp(~nC`qcP?DVKDkeYGgncW$hj{g2^`U++n6agUTEs5<@#?;EtOzF+MKmA$_PUAi+e`BPo@LA)39 zyLfJQpWFN`(P}SxdfALNe1UP}vTxcc%~Dqs>lc&z`&6)>gHw9HcozH%f>(fw>Escp literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/include/_variant/_exceptions.h.i b/src/hos_libvariant/src/.hg/store/data/include/_variant/_exceptions.h.i new file mode 100644 index 0000000000000000000000000000000000000000..be10ff44da659704afc63a2ca576c3acdfa794f2 GIT binary patch literal 1313 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 E{Owa$>i_@% literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/include/_variant/_guess_format.h.i b/src/hos_libvariant/src/.hg/store/data/include/_variant/_guess_format.h.i new file mode 100644 index 0000000000000000000000000000000000000000..c84269aa86654fcf33ab0e32df4f382fe2064611 GIT binary patch literal 398 zcmZQzWME_f14cgv1}07jn}Oj!6j<^lOy4W}`XkH!#4{%ss=s>ql06cp21HlPDGj*o zcgR7Yc3Zq5C%;DEFGe9@lO}<@jZ-s{oTimc>)WHi|2)lnnSQk!@BMKPE_j&OEq2W81_C_M9KjW=yo6J1fO2QvOoX; literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/include/_variant/_parser.h.i b/src/hos_libvariant/src/.hg/store/data/include/_variant/_parser.h.i new file mode 100644 index 0000000000000000000000000000000000000000..3b38320994beed1041a651d16a643a361457f117 GIT binary patch literal 1590 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 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/include/_variant/_path.h.i b/src/hos_libvariant/src/.hg/store/data/include/_variant/_path.h.i new file mode 100644 index 0000000000000000000000000000000000000000..872e23416fcdeef416a27be7c713fce1ea28c56c GIT binary patch literal 1415 zcmV;21$g=Z0RRC20000000l)gdPxk8o00000000000001ZoUK-EZ`w!@{tUlj>Pi(vE)GPe(}im!Cr29Y5`us< z7o}0O*z2&0@w&U~5ESv>Z)Vqk+t9n}R6c;2muF_4nb~y^eE6B4dJxnmGoc|BQ^nL0 z@G()GgO-U|FvYvDlm$dA1I1&ZjS|zsa1aJq76($nT*e|nKSNMO7IOt=#=&qk*B}%7 z=i}fC&dUHFdBzn>VOUI45urHZndZPWB7Kue{yztHGyz&1J~hb6b>dgT{Jc`iCX@|9h8{osX%0`OR>x>F?~X~ z=#5U!&?P+XpZ6y>SOlE*CxhO245ybP2w@nGCjFDE^Kb;itI_as+-m`hIbZWkApb#i zV!MWP#@sNG>Ma4TQ{R{)73>M^*fiy9A`*em=lzr3VB907iDH7FIaw%y17hUA_RoiY z7PWl%gfcD&;oxB3hhwP?Szm;(-)Xno@7o9azxr@B4%cDrY$hU$ zsVCB=M;O;qr7>KKn8P)n0=8^sOnw*yi^Zaq=%gjp0~P+0w`p$=J`*{0zz0@f(-r(F zXBiwT5kJgXW))KP;i!*&zaNH^v-`99Ta<~6zY^z)Aqv(Radge1 zw7>#?kNKB^A5{c2x!FTi@`)*da~AZTBW^cAw`NE6jLo^uiFh3RCuagL^?EG`aMrZ2 zoq5ignW4cW2m6#1Swsjd6*#vvO(i(FS=S4e!y{kf;9%2r&Lfe~tQQ)S0tQ~-QJdT- zpn6Q>=_XGveUT3SR6tfQLD^y+gQ#whtX24t#h4Z<~Ht)tV_EpYdcw| zD(g7eK~;9(WUoSeZ4)>p8g9t&96hzt`-kX#MJrSTb%GMaR{vd;*A9*Vbl9P?JbVMQ z(<~@0sx)rYmbuP1iqC5X)|_l6nC1aDgUY8-L?qvqKkq`ZR=fLa(WmDfIQAm`}NCG{HrC!Pg{HsLZkR;e)HKOMR|wutR-S zK5qR`j~iVR2{f$ho6@z3%~Ns#$1JvaDkW9JE2(zJ9WNQiV=t4~PRMLdUX!@2mHF80 zNwC`HKDLB@KX;_cWxk^c;VW+nR!yIX{vXNH(tVXV3d+25C7$p&qX8;shhlZB)NabG zChHJzwCXi-pzGGE-Pl&ze`F`NYwy1|<$0+z-`*@Gpvds`#tMvl#Fr$zW}c*ooi#x; z=nLNE^gq5QOCNTSND8XeT5p}dZ)p>Q343%oX>MpKE1A$+Ik<)!mnN%bUjK?03RZT} Vgpj! literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/include/_variant/_payload.h.i b/src/hos_libvariant/src/.hg/store/data/include/_variant/_payload.h.i new file mode 100644 index 0000000000000000000000000000000000000000..f69a4fe2150d4c408297f92d09c50b3a97f85eab GIT binary patch literal 2192 zcmV;B2ygcQ0RRC20000000zzg02hq_0000000030|NsC0|NsA!l`B2Qw5iTHWb5^A zHJ%!7j<<>c00000000000001Zob6a`Z`(Ey{v7{`LkbK{;Mz@#VVKhnP#UN4<~oM$ zG{`W(pd`xXDw7&X*>#Kl_uY|_oy4zb(tTPG#Fof=zkB#F_4?bV{HfII2ZOONkcv<< zJqP@nXwJc?#Lk%Jr!ZGJL`;I_u`pJPFt;3p1t#OV(lAl6NKnp_s$9lggB^3QTu%(B z#67(4TtmAs@SaPqSqj}eOhtsRBQ6aGW+02MS`^S z`czBV&;kqA` zW?gS4LdH}R<=i73H%g~5+=!UN4G#fJHnuiv)a$d^td^Lhru2vcf8uF6K8C+2ITgS! zEXSg2_+5=9oM{n{CQQ18Pz#;_eyvxYi3DdRfsaA2g>@fxgWL91a6Y`OJj2&Q@^vej zW~d9JjW{ZhQJQ0zZ$2_Du$Ah?XKno3n#JZsSZx0Fi(RITUz2RYO-2>LiJ1Cj_*$tP z)a%%7_?U_>oFD+sxmiBLm@`CxD#)CMV{UN{X%mA`NNUN9%~Qo<(&KamxJ`2!w20bb zffyq}gHmdCEkk`f!8%eSY5q?x5RhsMMd&)ZjFB1F--R8(Zex(D$Z2S}orfuxBRd{u z%#IHmKp)htGei?VMWw9Y2L=ZhTPfsDI-@p?osIk6QJA}Rpyxh%L|HX)YGQs*ky||H z3CmM!(6I(=?1Xl+^L}uNkAq7%EG*W&#lsb$v+K@zySY`iR?50GQR;Rli7=DW>vQ5H zSMySe<1Fi?=sv-3jQux7hj+%kDp&JzWSI~!F0Hd7(kV-G?z<{d6AVR!A{B_( zgz0Wah^UtGqCaamBvU2g<(S;yzOJ|R+>B9eJj|?qQ%vGjZnNC}26#GDp%_G%R+r*~ zIUPFqr&>8U0DyyXQ${Us;B6_@XmoJuX#3G=WwGndd~R^WPkl=|H-vng=_-Uu(YZJ@ zEa7jh&dHm~fw6I;L31ug>oc=Gbl5NG&54f?TrAx6;wQps!nr3+`(_U=TJ0trC;ySP zGE&YaVV=OT37^z(E{zyTzQMS2>lk~h3X6@H>!)~vNHx~#jg+~#>EDrqwX&%*m zdstn7%#Sv-4qqN)v*L&A%paw6=Kv$z#h{>lc+H}F81|B6DRw-*3VQ8=>={E{b*HBp zHr;2NrqYQdw`MTFf*tDV9#~D(93Lbc<}|u4qg3m$5E5k+Z=+Qy$%a8seCWwzyM3 zkq|EF0w82cd~Yqm@QRn*;;2Fg%vZ!Tn`^n@@WMuJB6n=J{%jWP@$$TPbPC@Vw(cLh zg^~RjM(M#?)64ze>%=O_*lzIqEo~(jTaD7rJ*=)$jKcD6cCk;HoxBs<;>*IBHHf&m z?D+Y>gH0sd5t2=L_@8Y2II`idY^yY5&vI{U!Bw_U+1UllPF&Lp)wP_&8@M+v8(rSW zM)vAaCw+&%>=@eZUKHqb1bZ2MthH5y+CO4PXEuStx5_g-dPGwB7ZYslod5s;00zzg z00001LI407761SM000000{{R30RR90|7W{NS(3Mg>`+ZRi;+|5jy1zgTmS$700000 z000000C=2rQ87*fK@5y&5WK=lLn56>pPGgSAtBL5KArDw#ojvddJ}^90Po{x>>Dm?ZFF)L+?HaIQRo>QE(t7iR)6HyDqTMW{U^U*v!|U zlIXKV9|;x>wV1p@`7R6Lfy12wC*39m?Fo*|YShn2PuP%DU}L*5P*A|oKuF$0eNehD zI*;u+8|d9djo?B-U(rkltst3;40sBi_Rz9SSR-8YcIXpT;93Z*;F;gD*zdX*xPN%o zAXM~D3TJjMNR0c;kKkqm?T{f2rSd!-$U72ojm;b{=wj}yN%Ay|m-Z9tP#RA$0=Ka5 zQ6c73b9?Q%1{X&oPplcWdJ3i8g-OKLSTe2(l?JDF9@sleN5ul<^Kkb)`|%zp_M&9T SFqq`>KUb5D%+n8i#Ngnhv@E^= literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/include/_variant/_schema.h.i b/src/hos_libvariant/src/.hg/store/data/include/_variant/_schema.h.i new file mode 100644 index 0000000000000000000000000000000000000000..70c99b2d3e17d1816ebb1100210616b71b088e96 GIT binary patch literal 2305 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 b(4Y_DJH{^b9f-fRpKzSLlJ@@qO;Cue`hROt literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/include/_variant/_schema_loader.h.i b/src/hos_libvariant/src/.hg/store/data/include/_variant/_schema_loader.h.i new file mode 100644 index 0000000000000000000000000000000000000000..acb7b99a4965cf4ef945d56a88e649d53a60dd02 GIT binary patch literal 1172 zcmV;F1Z(>M0RRC20000000Y7R00=Pv0000000030|NsC0|NsBuCn&QiX>|)Gly=e6 zzsCouluI}O00000000000001ZoUK*cZreBzeYU=076pQ|aHXWdVzG8xKnd(d3&$~h zStG!{P!bgprAdRNWEe&NeP>A7ady+oL;YaOzURTwts*0CPgCA#j2B23l?` z{)cymSRG&=v>}{x<|qRLdP{zKEOJi&(rDhVTi`A)_BWX9-zc#D+MBBUWO^RNBV?tH=5tv zqDy+6O|s}Xb52UVq)lklo zJ0_%k5+GFSKjtU}YtfG7k{^Vq1U^r)o6&SJBBe=Uf}lRx8G#Mr^mpsmhfEc5AAbK6 zmK>$vFq5p{@Rm>(4Ix}zUG(8vTSwM+DO|j}yu5sSd3EteA6AR>5Z3o*B~(c@(ViY* zthJFPtVPLT&2zw#)y{1PNwVAR;>uRBHjk9}FP^41Z{QyiCjxw64Hn(NU%FOsZAAIF zVai|RM(_$!1*~kDDzFV~QS%K0sTmGXj7CWmy%MUB4JPpZZ)OBGNwV-(as4rh6x(pS zCCRX5+i(wGqNtZ7zX4V9W$4hg4x0lDL`Sd@)(Z95nbGv?O+Yyo+U~968yfg-ikOsp zC>kR{RFF49x;VIGVFu|Y=Z`{J-}oK{r9Vy$lRLJzG&wLq4r2^CCeb{Grn%k;>b!uq zHQMPyOX@`I6}La)P#%;7@h9HEe5fOR^?wUu9mDVllpchIR=~5SyDQZ8p>~PD5bSQ@7ZWL{R?gtG|c3t3tafr<+3A}N>)*X(cWm+|=pmvEVw$hy? zEdo!rgVze1iRD&Hda(o>iq|1wRN{#-o9(mp(-p{XEGQ!)x>Y8RL&ZL$vuijJ`(y0tA$$?EnA(00Y7R z00000QUCx5g8%>k000000{{R30RR90|IIDxXE69P2?Kn)c1!t*>L8d(NdN!<00000 z000000C=2ZU|@d50LBd7%9&|-DXD1+VU9tbj(#EW!OkA8zK%ZrjxMf2@g7{tK)KAk mRGiWUMTzOTi3<67$*Ein3>=0K%)qXknwOH9#svWXCL6Qsvkqwh literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/include/_variant/_shared_ptr.h.i b/src/hos_libvariant/src/.hg/store/data/include/_variant/_shared_ptr.h.i new file mode 100644 index 0000000000000000000000000000000000000000..a46b91c06fe15f9d1bbfe130115e55089452e78c GIT binary patch literal 443 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 Ry}i$2iV0_X{|jRG3a=G98TbGI literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/include/_variant/_variant_defines.h.i b/src/hos_libvariant/src/.hg/store/data/include/_variant/_variant_defines.h.i new file mode 100644 index 0000000000000000000000000000000000000000..5c1bf16d4f62b9f9a66cc55b06a9380c38b207d4 GIT binary patch literal 841 zcmV-P1GfAC0RRC20000000RjC00r#;0000000030|NsC0|NsAz%>y8#fJG|x4>HLd zQEF0jTN>v800000000000001ZoUK$*YvV`^evW^I*uJDoHg2~Z$F=N(lRB-JG!3@X zP&hDSTTTWhGiGMoTsZc>pX4^_a+JH5^@AB{q)*Z(X~OW^ul#~A9OPT+K*`bydjL8% z77?6j{9ahRfrIIw5*jSl(s?V(&Lc<uWr)#v}w+J5X&Vgxq;cl^l z`CEWH)M$l*WmhU$k-9?d5QKx4HExSFBbA5VbH=%3Z@IwCPypej(KmpS?k&8abtJ>r zW2`s85g5xjL*cms3#Mhib4vRFO89rzF`0ct!+W(gNZn&^O-q$+36kpHOQoPh=o~hk z8udwc9@a^I|G3H_T0Fx#O4DeOKi`nC-x|8b7kq`1yH-g;rn;=q{y^z7!b6-+@5v>a zB=aPHrXpaL&;H+{-U%J z8=zwtoXLiErh%s@O{nk1Z9Ge;-Nk)yMrx_?gBx~YpQ504O^f1WdK)j(cpByLE!_$K zHoiqM9M;%ctZ3}(^Yh>gm2BYErydp$*|d0y)ANsEYOIuNvHBT;5gZ0*trb)g?9e%} z!Qm&G_eHX}yM|}#i$)r68Uvnm+@bbAKYIEW&;1=(`#}P9z=UOPn0QH Tp!1KLAmHDRW8MD%l^)g9+m@sg literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/include/_variant/_variant_internal.h.i b/src/hos_libvariant/src/.hg/store/data/include/_variant/_variant_internal.h.i new file mode 100644 index 0000000000000000000000000000000000000000..d3d765ad3e7ebd7b8beec895803c76ab52bf375c GIT binary patch literal 1106 zcmV-Y1g-l30RRC20000000a^M011u&0000000030|NsC0|NsApjR0vVC<2|jT@!8S z#uV4$p>@ju00000000000001ZoUK-EYa&Sy{yg(53IdCYtI3ArIL!veY+gJPBWgAT z4y0$MMjOU%>F&{$CI9`Zdd4$GbNglUA?bdq>Z$jhwA){Q=TF#f2a~z9kjvNzvjIA0 z1`({z+*%my!bTU62n7aHX`PXA;Si()q0+WCu+XW@$j&iUp;9#9<_HeW!h+8H<#zA{ z_mzWNRA@vF!y?XQLU4l0A_xmhM(i9@W{Nl7@`hs>SFym2CI`Yvt-64clQ?1Z|k7CLCvAKrh*@PGN5#7j9?TBDG^>*kzl7RGxdTmz3F@C@KH7%yWnl3X55h zH+|5BgXjL_?(t~?(clH1qtPfDOkTRA?B<%JxWbZ3E|$3@X3EP5h_?7k0Xd+7>y?VtEc;D1jDD%@Ns&zs-D0Sw$M&(S= z37Okn0m@FjQ>Rjh73qmM$88}pN$30i)%9R}&6Va7GX>Ad+DIA@r~kKqP3Wtn)r3F( zf(cS75Qe!(5I!@@xL}6!^V25uv~{fg5W(q}v$M0$XXmGXHsNU;ZQc6W%%n=WC)$U{ z9M9V1DLl&*;TdC~md%}8cG~Urdfm!w*3xFiiT~zpYBb;}FB~pVIX{1X33xzvh9y&rZQ38Ydly&b4?5-Jm3SpeDJZXcJsV6Ij@aaV8Z5{)Q^8)qm}R z$vYkIXiDp71T`As4{-c20J6a2&h{!%ffr>@sVv9&JQIluOGDSmD8m&7gb3v>A#w6n)>4GD^w(x YV0YzY78<`Wd<{=%i)0r53uFxZqH3iWm;e9( literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/lib/json/_j_s_o_n___p_a_r_s_e_r___r_e_a_d_m_e.htm.i b/src/hos_libvariant/src/.hg/store/data/lib/json/_j_s_o_n___p_a_r_s_e_r___r_e_a_d_m_e.htm.i new file mode 100644 index 0000000000000000000000000000000000000000..ed0de58754342d6bd38d40ed1bf45e583863d63f GIT binary patch literal 383 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 Nxnbm{@V}rvY6Ra@>{Loo8gv+g+PkHh!g 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 G3+S)1ixgM@ literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_base64.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_base64.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..5a7909ce42fb036bc4955b069f949dea5bc04324 GIT binary patch literal 1471 zcmV;w1wi@$0RRC20000000n;l01y@c0000000030|NsC0|NsAX8~ZJ@hkraUv?i{y zd-T`cQgRCb00000000000001ZoTXQLbJIo;|J(i)+c1+z@+Q{XHpZDD4@xO5v;q1c zOh%T^v5F$Ol58F!-@SXMlX5~%0;$K5b$h$NecV1SeZzp$c@(oQ&`Yo?7HJ00(nSIX zSu{Jp2okX|%_24jdhK@~L`fL0W(>9tf}Hv8-eRlUO@a%SFN2Ul98K3j76nNGm)&k> zmE_TR!e&r1A17ftV_LWfGBDCru`Du#Fir9T)@d{YBT59R7K>S;tioli6KtoG7uhN- zAWGLPGeth9`H^y2d!Mf{)DS| z%VFPfr_Q)Dr3lGzvXJOV_6e9`%~e(hXB3Ml=hT)RiWyN-NZ2L^A=dJwP!kJ%tiY!w zG(ALCR+wN^u2p7eB5e&_YdSQgywag31E$w#(=?51w8`YA16NgO92F)LD32Mox1ov) zr)|^_*?N3%cy#>a z$EQC%`}z4VzrJ|++wUi@UcdR{&%gc-rs0gu&lk}@@8gRkUH+Tp#cKWGY&N%y?IEZH83bs58(^XQJj*JQ|%gBto56HkMVesNXb3ckZn+DLmng4mht(18mk7U%4GqYjTKyi)j` zWW55JJ*Hk)RmoA?H_w9e3zi6iWTt~-GB5jmI3d5_ab;Y@^Plg+G-JVgnS&JwPu!^2 zlQk{en1ELAZiD&Jd~&G6{yx}(Ne#rUQYOXX(Iarjs#OOqt3(59fp(M_Zd{kX)ZOkD zcfPbNo14NP_dETW3xDi}KZp1A=l|FrmiGI%+23hNIddUpZkD2PQddJghN#3TsZHKW z)moYG+V8uSvz2S7iS(^qSHj7w?t@iA<)qY7x1mR^9S$ZkRaE27skx)vMpD?V3siK_ zjXmxp`pmSu?m~2s$7_~-0tcp_3YG&`Ko^*#NWm>hYRjPD^2{JG!`1svPvj6`yjrk~ zK|p^tu#ZI+NHiv}4_`hP_O1#^UdF4u;>;l^pja?IT-x#A3VRc<4c=t>e4_`JUWP_? z71|&UtE9;Y5p8p5j+kiw<$bZ){>$dK;SMPx)#&n76uHEVDb4=Uw{h2!U*AE`MvtB@ zdLDW{dIR)^=#9`f(YLNScNHlUEws@=l0hE_IK&ZJM6}Sd(Q?po(elvp(HfvNL~De$ zi8jgDXgg@TXnP89^|gJp2WSt`9-(8RW1&Mz9CTcCJal|?2IvgY8KG;UYoTkSOE$RZ zdg%J-4$vK$;GNQZ^ zG`4uzXbqgYVpKk5n5g7x8rETt7UkzJjuTD`ha0#n5ZEI%ICkF2wgS8otG99YVO#{T)G(Zl% z5v@H19CeDxwpkt9x0oa6ncJRc_cJF{E(!NBr@Sus4Rem}Z_ZrbWQj6`RM=ZuWowF* Z=}`UC!6$*E_g&tWMaRAB{s$K1kFzW=%a8y7 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_base64.h.i b/src/hos_libvariant/src/.hg/store/data/src/_base64.h.i new file mode 100644 index 0000000000000000000000000000000000000000..21e083022493bfdfc63c98f30840b4728c883177 GIT binary patch literal 493 zcmVF00000000000001ZoRyMIOCv!LhR^n|D99y-;J_m8L0w2#VfEl)6;DFw z>8Y71Xsd_*h(y`{zSYxF6Nv|J-SzR-+x2uco55pC78S@rr`S6WH?C(`dTP2S&10hW zge}OiQWI*qk;}v4@AcyLezjcOU7ek-{-}vWiSa;U@LH6>u|a8PV^f205jLSp}wBBA410{k}wQb}5R?3EY3ww6c{FhS0lY8>kU<6bm{;SdL?g z(K~v|>HnPbs_H*zUljkrF)+Q!xx2gP+9L(}5s-wh#Iu<{>s#DWz53^!n4#u&J zT{~)EHokcd?`@*Gb2Ed5OZfTY`20J{van<#kXxgX32wckD7V!&XN)`f+Tdkr&9Hyt z2>YGfh)k-s1Pk=Mw9LLB{`eDFVq}*8$1_=*A+ZCieJ2cKuX$^$jM+nVfKQP88=a#6 j>2*bBS~%=)ux#}Jn*&SQar3G2pPC>y)GGBKrBXYCGXw4B literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_blob.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_blob.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..4a32c6af6bf749072be4f655585b5f1421726c3f GIT binary patch literal 1026 zcmV+d1pWH}0RRC20000000Y7R01O@g0000000030|NsC0|Ns9U`JyV3%o|R=Z4YV9 zN!mUpJ9x$b00000000000001ZoV8YMZ__Xk{+#}bLzAYY4eO8)AIesVjTZ?Gm=NL% zpvX&{##7=%jg)GuB}HhqrU6=eUaIzR zHF!Sp?v-~&1Wh7bIZ?Eipq`7xxu8V$KpI}N6{iX0l!w|%g?ZiZ7}6As);4A@`lFh38!!e8V_OM9!YqD%0_S)67f+V9mYRIzYv~;ZJahjn}RaBl%mhP z7kH`>x(x6w8kvRG%rdlbHpDb)2eyOVUV+cc>bs8~wS*l~8wOit)Tc8IwyNpCTlw~> z<F{+zU)&tW!W=&pTcr)v2N`*zgr-Xn(5At90&)B~0# zSZY!9;_~w1RTQDgd=8&Jy!^0$kF-FZaGN0&|1uu0OBnJ90K%@s)^U0%MD616;_c};(d zuLT>8$P<=s7gF77%$y4&?3&PU+AiRMQR!jA zXzroO^$+UVRP&}+g(%Lbav3(Zk%h9SLNwxt3ek3>YvZ>P^gG92DDjb|R8St%YaVB{S<>I6L%`6YFX`@x78n>U~TP)XpY$n$x z+)o|PkXNPNx!9W9*Yu8R_Jd+|J09&Bf+0LF}jE$V33oz17cJ7{Ft zG5iQ>vn(o1-#=G;+RIwXjEb!s%SJ?Hn$}ddOgCFH+qGpo@pZd#o8gxt_$nV1=6zF~ zH7S-vjk+8jqS=XI@OU}cwb>44s2N3!`)FwJnr^1R-g5xUdQCvDd;ds?{d-Z{IjpP%0DIB|?= z!_wyw&!@gPcvCnva^B`?wU>!o|X? z*~G7YnG!PRVB)MA0ojOdvDwlVhdcx`g*h7c1pIJ!Ei>D@U5o8tNK4rUJ+-;#c6VPm zx=3~5OO@r8E+5}nUg5ZST4KQ(x1(V{rMGmwdK#Cyd|m&NepQ~M!CR6e&lpN2^eGOz%ktS72ea=1iJa=bb4)*uqZp=bz0{$V1o(c(H#FRr@ zvS1Pso^6aIqhr9o2j(8*ewYLltaieKkX{7Ri0I`PU%elOHOivbXH+UCxK;A5VOWiN z!!k`yBC2BIQwZ5;MkFI#!=q^$>nb`?9J=l{tF5L)(qI^C*(}VLiH;N90#SoOff*A? zBITHd;eyDvZQ;~#sWj2lZeMuAoBqjlKeO>9qLTT;SW=&*I&4gc>(0%2BAS6nMj>sv zZonqEK5TsWz{ z(FtI=V69ahtUI22=CC=*w)eTy%N4&Q*yBN|+~c|2%c~u!U5d8Qy39I_mD7p;uVa53ny$>sTpOa9nxi|j7-S!1n8ho5cus>Udnbk0F zGNjy|IaR^1DI@YQ)KDO0g%SwE_#_|WAe2h;j1OowVRrN!4=r_k$9C%eFniWuVL}=c zjki`+BFTTlB%isJX=E=bsuzQNW3)Sq_om`L7AW;C1)Qc0(hkMwN=q2!GAbNHU<$a< zKvMNufI<;?7=PhnN@0X}pnt~Hsz9TdSnybU2YqbKXBfQVS$v(8eQP`q-<454zZzBs L<&*grX_$BS^6ZKv literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_bundle_hdr_emitter.h.i b/src/hos_libvariant/src/.hg/store/data/src/_bundle_hdr_emitter.h.i new file mode 100644 index 0000000000000000000000000000000000000000..2bab3ea48ede841c0fc06884efc1e1f1cc141efb GIT binary patch literal 1070 zcmV+}1kw8d0RRC20000000Zs-018F`0000000030|NsC0|NsAJBoaniUW>twW|Apm zAkm&!vspu z0(mN;o_+p>GqA)iYwH~-Vv@o!gX(mN$0HP`qOo&`UhSAi~5m<6bj5Y5=7^IwNUH8Uq zrs{%Bu$5o{WtDK2LR0u73<8S4Fusjvh8VgqP8Q&PF`JJb=H1ubIQ~4DZg+pj|8Cb$ zqr1m=yStmr=6kMIwB5who9^2QU+;1KG7JMx4&x3Ev5$04u*QqhsLP!$y9U{Xy8mqH zNTJ(9?4@AMl&P>VKM%s~+N>qZU`(+^Ze&^&SW|1Tr;kN;LhHQ0kTPP(gHy3G`9TP4 za>V-oq*&HBmW1Ci-AL5OwxvJ<9)hELBF*dXJA{D*yW%%D1J zkx48*J*xg_S&X?%?u~-vK=hw@rSk(ZeB{!{)=<3m%4cfab*p34CL0X=kb*zH)91Fo z25bot?%?XGc^6TM7v5A#*h@(jOBY+^5MHcft*%cS3~X`c&n2}SUrx}`Q3JeIM(y5= zny5jb`}?_VfACKHv(quYT^u)}&W8NknQ-Mjdn5fQ{EUuj9{4L2TjN9-xa?axPu6y~ zr@Bzpj<)M-271FxnnR@RK&oXa(G=>zV~0c#{G*tm5h7T}VMBzYvQ-Nl0md~s+3ewYky4I$BzjtFBZ;I#OJF1_R#p^VflRRYZAWbuch{knx)3Rt4ry1xbGsc zLdtgCZV%4`9PE~@2-|b9QI@=I%ny#$CdUshh?=U)hHubRyt}GDD&AjjDZ;xZtV=Mw oZ;JMUKk-bte{0=%YF%QjtQo}KJPGad_!3@Fk+Eg?3kBjjWk3}O?EnA( literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_bundle_hdr_parser.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_bundle_hdr_parser.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..3195171a67cf4757a37161eeb70be1256a708f5c GIT binary patch literal 1568 zcmV+*2H*Jr0RRC20000000rOx01mR@yJ)?J9i7@U zG0>jKM+jj600000000000001ZoRwI6Pvb@q|J(T#lb{|p1PE1Cso_z9NUv!*?gZRP z)j=c2+29q99j({7UXS#%cV>6JUONU_gpfTu&)>Y(9PI4C-JB<^1NaaYGR_42mc=QY z3qE^TgsD213eM(m2Fp<7Ou!tOWX#~aNM{Lyn1wSY_L1|Tv&GXWDP|0M`taA8_@IRL z<6d=m{3#SXOyz+-8>h=c?#HJNLoNkRAL_I)dB_Bp@uJ3voGh%7BKdX6YNEZj1}-NM~!t<~+p+K3-j1jwYW**Ei$$SCijIe|WvAa(sWqM9#AmnbUB=@?{t?NceQ6 zJ%?|djtBc7t3Tgyhcba(SRQyqvs{~I7wIvConj|_ae>tL&|30(7wc&2JodQ zm=;n}cHn1iAT{hB2#%$aXp-GxI1f*W50ak4bcvZUP-7DnpWIXHk{c#^;)`wC$?gH@Om zOwlR!JV)-ivfhUteE0d!A>7HWdl=I5)_t!JZ&32{;2s~8C_V;odV*f+FbsfYh6YFm z4H?YCBxgrJcqw<2EL&m-R1_4ITL}@;NllZ^3>{%9tq=>kv>zdG!dF-+$6SIbKc1^f z_jjTI-n@Ybx+g&Oh=mYozZxzXIYo5^DC7ATE~6NfGDV0mZ?HYw9#${lzT8RuRvOW8 zD9RMO{PCz_-7=gt;D~~q9Tthyrxf+F$m7X0j2_7kt&DsG)-pui$-D> zh3$Ouls~BJ=Jx#uBT!;+Xx`VI8t3`w?f7c)?yO|L&6Z~>Za>&NJ!cO*y~v_s!BXkV znCF2r{F^4O8HB8qU)60&xr9+l>+Y3?{+Bq|qh_>SkmCGcF`G0YmKVcZ9- zkW4TjEYxr_GD?vY(PHV_(Yv|XgL2p!DXJ~W(}I;@t}7R=*&s06j*+1Lr~scx-dqxRCq-tD6XE+@&w`&F=!b{}?(ipC*{tmr(}r0;rK-R*R4Wucs4tlen@{4Y|nGe^g4-mbh)X+v;o6y z)8f_T_~y0}+PDX_l$M%7m*{`{5NfgAXebqXwRTokaCeu#UTfs=&|W>eN?Co)xCvLs z*sM5+OEcPhww%<-F7_*n`RY}y>&R{i@&TUG+9EEhui8bGnS zo@&iC6}2s`hBgweU9}E3uUSlpOyp`kH^2LaFivS>BM4{*luJErNX8=jf|S{CC<+|K z3pP=T{8C*|yO|mD<#qn04~Lvdb4jTnzzfGK9|^DCk()hSu0ZD_qt&4nqMu{Mve^W$ zCCAQ3@G0;B6%RpOYIsI>1-akICqFeJs)u{fL#0w7H S$X1`qYSy~eoqqwLcg)US#|r@f literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_bundle_hdr_parser.h.i b/src/hos_libvariant/src/.hg/store/data/src/_bundle_hdr_parser.h.i new file mode 100644 index 0000000000000000000000000000000000000000..c13707fdf9134d01a33bcec9f3c9a6a76812f8fb GIT binary patch literal 667 zcmV;M0%ZLF0RRC20000000LV800jB~0000000030|NsC0|NsBr2%npn>2do0jpnS` z^ezG(WYRkT00000000000001ZoPATlPUA2TJtto=5*Mfty|<`Rsz%V=QmOJYy{s{Oa)?X z1a2UKni-1*HWcJagmI&|L@1GQG*=YakI%$Laf)3g*)*9ytj3S?$t=B{WQ!!r(`Q@Dj&Szt@W+YBT{Ws+wB*zEKJd;de|Z#}p%yy)ZN6mhpH5NM@xg%H2(@kVb9X3lwCTWtH{^OJ0Ur-pE2Z9ACC=Ys)gocM3@xV%=@?dCTM=rIw z_TeLV!hffU9g_|2sqhmArZ*zRb}+{!=xy)AyD6cc5}gV6PxCcCL&e1=egm2*k|!K! BGN1qe literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_c_make_lists.txt.i b/src/hos_libvariant/src/.hg/store/data/src/_c_make_lists.txt.i new file mode 100644 index 0000000000000000000000000000000000000000..ad87db599e7b9dce9db26f1a173254baf08b98c9 GIT binary patch literal 590 zcmV-U0F`LVpE3FSjOp zk#nRWZ}?XL00000000000001ZoQ;!BZ{jczhR@_zL{$&rP`Ir2?i4TeZU~X>Mf4OI z$3Pa7AlpH$D*pRAj-l47NP9`<Ngnf*}NHxeqemz_CvZkm3$ zpJbVbBF70$)OfX%2Il_wIjV7i3<5=U;co3vEx99|E|Ke93RP>?%=KwG!O4suntV2=Bs! z6|t%+Z9p;gp7`q>KYsXrmvLl&kOUcDgCEf(@4BJSNob7h|*gf5fU&98KN4ovBVNxa(;5nq^ zni)9u8m)^Zrg2tpd?Fi;VJ1%Y2z4~VzjKNfFrGm|Q4Z*^9m)v>SyrYfFJ}l}+`nn( c#sI(Gk=pF16yWCgy}G79Ua)9L6|2^h5OfFc6d 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 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_extensions.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_extensions.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..d7aa1adb70354d66742498eccf6d505978663b7f GIT binary patch literal 5387 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 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_guess_format.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_guess_format.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..d8ca6ff00e491ccbd90a061884f916e9d8412ac2 GIT binary patch literal 630 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 Mv}1o5V!f)R0CWzO#sB~S literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_j_s_o_n_emitter.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_j_s_o_n_emitter.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..f70cc7b53a6824f7054612e215ecb80b7e5fbd6a GIT binary patch literal 2317 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 Ec$w#_YXATM literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_j_s_o_n_parser.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_j_s_o_n_parser.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..2c19a05012eec87201bd12f24ca0a502f53462c4 GIT binary patch literal 2094 zcmV+}2+{Wd0RRC20000000-^>02nU-0000000030|NsC0|NsA9j9;dJ8CY?D8=8w& zATT4XD3x*m00000000000001ZoV8f}Z`w!`{+aw0)0~tuDIei_@4Y%`A^{YrnR#};OtpIXBmYjS)xvn;Mc{kW zkcCfxkF$_-h{Q~;S;!mkBw}z_03mn1NQT}tmK;0@EO4tLgr#u38J?2_6$dU4K`uB* z9xfvgGxeoAxP!h?(B%OSnGd(|)b|`*c6bnRU=gfnC0cNokfu-SI2M!SK?q_+=Za|d6ZlL%AFZHR9u3dly5I#0dm&cn z*#aTa|F!4)Fy#=+Z>I1?Yn++1h;pi+o9d5 z0N9)-JQK((RL|6{A)PLl%=4pX0`yJoh$9v35#`v_=Lr!r51;$Jc4uIBh-spjASh1O zp@#t?#f$e>f?nWMO7NfGVa$;V4!1sYIFt#+jtSx2yNeREL?lW2a}zFpsnu%b+PjPY zmf+5ACTdk|&b+{-I}yq}!nhZq@4~(3a=7PHz$;rwxvE#I>-D-ai)IxO&dKo~oK5HF z@CT7|0{FmUyz~%0ibVje&~xWY7T`wpq1{1{C;{b&ydw=9f!SXrEA)?2=qer9ve zq2-f+EqSyeelR{CS?FQJz_*i=f`^~a5IrQaUbiJO?6jHhPnq+@dK8`u=Z^eZ0+NH1oz?4VxDY8~d zcbbJ5m`JXIKoZeC%w8UlkC^Kf48ama90LR^fm)&fiZYAs?(_`Kra|UeHII6ged**Ghol zeNogWrXgov8u|JYZT;g*c>KrH@;m+N_?sW&9>*F-WIVxie z(0Rb!<8|Kjht2VE3ZK=?e8HsFafFJ&UB7=&!yxv3ga0bfcy!k}&Qz>7$5?jL?Au2o z&X^w^1No`*@V#teb*vaJw-b((eqq z;}39lrVbSfOTKiLD=XKk%&~E^TiS;yQaQdbrL9oVy{MHZ&`Ny_n~UT@`kQxXn)7xqQZAU)Fb)No<2d6ZSc3oLoVYm zP8=OIQ=a230RFTt4%f>vxF;^}5UcjxI zdUS*zF9Rd$AgqJqq%_}ECo#_+X|PCva;-`6rgf{R%QO0aJ63B}T<&wpCn|Z3q54Bn zZYB_&Is~fHX%~6Kaqcj9Dz`KMe1jLzVY7>0$XtzLr(wv!m0BZZCy`F+Nfs18$(KAv za*f{-Ovk|q&Q~*U4*Ek)eSs$@nJw!~e-^c6^jLAsL`p7fji@;?6PzYdPU0(BW;gMn zT+1v{HCdzD_Jj?x(q!f zypCcDPl6_*x4I>*Z#(+D_czIZo&U5CZ?fLynsN{WnRvcH6Qd)naoEZ&2g(#0txi?wNzN{q{X5ZILiPWuc|K;UcI5AZVi|UK%o*Ac995pgwndGU4&b%<0 zLXkW15nIPdDGIfqxn(sd3HtFVnB)JPEkQ()i9vjV_wTbm9Mqv1=vP?~juVI2ZRvLq z)f-MpRz1-fFcGa*P1I^sbv#lf2NlqSkZX zoyPu!;5%O4br|AnS*8e~zQ4OQ=lnei>DPn(Uk$JZB6Ib866;wO)kg93ACUQ~F_qIS z&ztROEEz!ZehP}C$$p+;>(G0cZMrLb1B0cnOy%@c2!HSBHC3Dgr*xH2H+}GYNBR3A zz;ji}MHqg0`S|b?ojuV(pkpB43R~tFlH8ugNSkF2gMBZL3DqLV_Lq*f^(eb{IMYgA YI^KGcysd`ceT1~NA;{+B|6C$4XTn+nqW}N^ literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_j_s_o_n_parser.h.i b/src/hos_libvariant/src/.hg/store/data/src/_j_s_o_n_parser.h.i new file mode 100644 index 0000000000000000000000000000000000000000..dd42cab19466a59fb5cd92d83362319d2c6023ab GIT binary patch literal 1179 zcmV;M1Z4XF0RRC20000000dhA012J|0000000030|NsC0|NsBH;JVgErb1Vy?;7ff zl*t3p{TSH*00000000000001ZoUK-EZ`w!@{)~UcsQHpa1oCp%DkN742ubLrfNZ!Z zQYEz5<9M%T*WDK=I`w}0&8|&idgbm*^C20}%d<1j%3`e5a*0ObG}eaZA$-Qqxf@X;IMxLXP1}nPR>tH-vZnze3ohhgBEo2 z90f3uz%)ac3BE$5x!HhBVTxawCLo73&G-v8keDh&&@we^rtk_j(n8DxC``CEiZ84| z;Kl*BrGlkQcuH}`L0OTY0z=0cR7>qnavyi289Y=6+@V0_YP5@-$E1!?XauIAa2lOq z;*b^_A9?F?iK<-SR?-2Uq$@y9b_KpBDd2p2Rt4AusT|HBGp+&!vT$)nl=cR4W?n;E zduVvAHUTa?b|wp|EF(y&f6en876?{jYV)Q~+8THqPVdLFDRf6q@YoH*?r8dSMb0LZ zWW^PhP<&bBoRFz5#e{E)L-;rd`}Y*m?F}D>(mm7)OU^OOwcf%>sJEGPJQQ2RInBKu|~UXMFYpQ zqu4>XIaw=C17hTV_OA&;5x1J~>m`jMQGqbYS&VSvP$KIPE-p@+(39FY?~h$LJwH1; zJ2|^Jebp8FuI>+}IL&Z-Qk}BjHWYNr{n#POXhM>S@$o?**b;T&MuJjUl|JxS&>)6` z29evX?nJ+hC}LJ<>(*NPv8xsBSI;ZU6ljEL`BOr6IPIWO;<$(^M;b@yl($g~H65K^ zDmy`=fx<2!q8r=lxlgRoi009hwzFBvy}{jZRLSGtD`60Z<8UjFZYt?!JQ|Sn?TUWw z=5eS!EAzsr>l%aafgd^N6<5a6g8%(p6d7w)Di}g5Dy=8bG5ATLv8vo>?F-pnq1Ci_ zHzKISZ;A%YL3BwmB_W#smyR(eqPl_p`4f<9&@69M-h9@ tcU3gcu_Jm%n_yuwr`bF1?vHnEI^Ti=6!fo1@DDjT4HyPyHa!3U literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_msg_pack_emitter.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_msg_pack_emitter.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..bebe6b12dbb7d068f6eec34462f99ec12dc03f1c GIT binary patch literal 871 zcmV-t1DN~(0RRC20000000Sog01NE^0000000030|NsC0|NsAg`zV5GOS>m*fbp1^ z$zx*O0yl>M00000000000001ZoXu8EZ`wc*J=?!xluD5ykmOMH5E4rvB{UTz98i0y zWUcXHR<+k?KS-m9{`T&NZEOWFNm{8FjCbD5do#11-LrNZe#}XNT~L3J6pM_(*K9$d z&qx%fh#Eu42%dxbd*-?y2%RM|!f-U^@dV9&4pJfnW~Ymzimjhy;TXkark7nVkRUTy zWh8=>$4liEm>(_}p|Mw8!wlN?*@0O`xq#UMsWk=dfTWzn6i1L?+Ja}-sYPSx(JNdv zp!d=qgjw`df=o<{T)QqsDdx(AAtB)kF@mU29IivuGf#G6Jijv{u&2{$LxcpXDs4k3 z=M|;exlrpcEF_~~>k-Tl7ngbY9;8@G(e^zZuhsP}g$b3Xq7*vylHaAvfwFJr0Br6JhvrcDCI4s>p~k8z*7(PuBFy{5)ev+cU%PYb;3|2~F-^T525L+TE z;~Gq46REb%Q-wROd7mJF*>3Y5{eL3RBh79+gEx|x?(WsXjDFK*KFb-v)fJ%viGCl-WT!}@@HOwmS!i`TTz;QvkkYN7Wv5HW_H-r7RL(%eG} z`~RD$U+!g+Y)h%^+y+!>*>nAk zucP*=C+@0Ag16d3pC9ezE?$}AR_$fwb*LKk-KOYQAmDvcRG3d6D@qQfmw$<0zEwb! z$uPn1WVb=yz<#6mg1*R21cR_qLs--BVyNlMS*am3lV+L;l#I-DQ``Ln#@EBUo1i~> z=m(?0{c!rlj*0DexH4A7YkEEG?20m1H(PTM5H+#RJ3wWsN0$+DFH<|wxc;Ds8u7~7 xgOd|d48R5rHjJv1M_R>Oo)~EzKJ4;qiQ%+Ytge6HRVBYW?RH(ee*oKJ(A&z}r`rGk literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_msg_pack_emitter.h.i b/src/hos_libvariant/src/.hg/store/data/src/_msg_pack_emitter.h.i new file mode 100644 index 0000000000000000000000000000000000000000..c82822b841e0a4728c316ebdc6f3f1b365356cd9 GIT binary patch literal 543 zcmV+)0^t1s0RRC20000000G|s00kWY0000000030|NsC0|NsA-?JgYKWH63ZH)!#m z`j;MJx^X;wB(9k@EnDs)z{_{pgyD^Sw{ zLGY+PxxvBnMzLU8!%k-bDO>w(Q3>#&vXS61oNpey(P`KBMx*yh6P+`KNmvNuD%@FD~mnomI>X*CUGgXftXGlrge{oDlXXX&_JKS zUQ{F{{c!BXYgffelu=+5L>=AV3aj&u9@e5f^>zkc?#CUPz+I8HM{N?{*G6%f!G|Y& zzJ>!RG*-!%4BvMLynn864#xpQJ^BCKrpkxmN?xyY&4fiVCx=S$ni+H>GB^(u=l^J4 hCwT!;6P==+@X{S~uQGiY zCgT`Ac2hzB4SY7@g6&LtC6gpklDT2ews&{oK8#a1f_qnTS13StAVKDpvm!P*PeE(&e8BMhR^6;8afT=fET4gIeQIwp4wK*g*x~+ zP}yu2W;4qIOl|{{TNd3BZpa$&y}TK0ZURle=sHS;=SZenkbC1`IakjOf+0Q>`|5P^ z*;m~S4J8g|iMv+N~*l9xAu%7{|m`VW^g>_*%AGN?;L?hY#Q3=-qJ%=#;RyiOd#hp;7 z?H&oe-MfwAV^8r&IE{Ai8%A`cV-~X*BxlEOv|tbaVvd$Uxrgdr4%z-e4Yd7(-vZl* z_cho)y#Fn*9ek|8rf-*Di>*d%YtY&{U@a(Z9YR|Numzc|LuKm#wxF?fNbJqPMnUAN zIbeG3O|bkZ9R_T5RK~vwE1UeKxC9U8KrIdBDh+}ekd=1F-{$k2tjq+(T2(S`kgN@d z4z?l?S4#J3{^Ax19}DJdbMYU5ov<+%7d%ljY+{BhYWMVeCcXg+9P$x30*;P=UPkfF zr9R}D@XG-y&UBR&2VAl6XM}r|u}RZ2klSqo*ei1Q|8a+Iyw<{8V!U*RDV<6YgW4ie4gvIz;PUwV%jw|c;`(H8advfn z`x&;jAY`Ez#!hMN_V~Po!57UNuQD)qm!O>m0F|zjn%_?66x&$EPNVqAiD7$js}=;% zu0b%<*%TPwQ_Ewaj7r!1d}Us2!%Myf7_rJ30!n=O*dld(Gl#S(ktqP;ge!{7j9e6xxjVL zh)z3WhJ6$zOd;Am($x;}fyYx#c%qr8h5yeYe%gSnNoqA7{S*%yJW z>{CF2kNghHur#13QId;s_ALvdBrzTqKEmN)@$IYw#}JdiKtqSf^HMxOfUm+Nds0J! z8*CVF3tb8JHWY^<53K!@Oi{SW4n8_L&Z69B{r+{o`x<|FsDiKAJ*2ggZ%vg&GVcuCLB&g-#1uICE9*mv$nu qvc)B-BEa--cJ1n`M}Oz4yG>X^>e7VdNcBnXu5`yu?SBEp!RGyDIk*%6 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_msg_pack_parser.h.i b/src/hos_libvariant/src/.hg/store/data/src/_msg_pack_parser.h.i new file mode 100644 index 0000000000000000000000000000000000000000..23673f238089d174956d64a84b983a280efe0026 GIT binary patch literal 544 zcmV+*0^j`r0RRC20000000H0t00Y_p0000000030|NsC0|NsA9lMHxOZqeiTH9v%} zU+Kq&y4^Ma00000000000001ZoPASGZ`&{oJzKwmKrc-()c2$fkTt>91x*4c=xKl< z+e{+VrVM=q9g6I?kCNNMOPiiV^YJ}BQgnKC1;4kdMgbg1@AlfjFTE%DZdA2vBt@Vw z3b(*vD#V4_QpI17lk9%7*yIoEAFIjTd^O3|vn>B9E*MmV=keA^76wfvvKW=MuMln? zrBRYxx{}7Cxu@2<>;3p_!T(recdaa+LQ+^~eCgoOv_3C2Iec~_AxJi8xdx$D#i5ge z7a@|eme#_9-K|*Q_41~zVF;}+YE?on_ac%mITT5PYikP&61Z;h>E3vWCAOnS-eKR-m}K z%+pD>(7J}HCcGQ~PsXxsFzCD?u%QpQy@g%ouIHpvA^M;VqxOAT8$|BTZAt zI!rQZ6z!lwTN+h_(CzurBr9Mr0oE%giyC3eAFV-)#DYo_IL&;|6Y06It{M(sHDeQN z_emd7nXCGKEV_7g8;9JJJZM#Qc$ja}8g<}?!b-etL+mg-*!lP5;x15 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_parse_bool.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_parse_bool.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..6091c17a881d4c753a4100241fc39af123ea066f GIT binary patch literal 890 zcmV-=1BLtm0RRC20000000TMz00;m80000000030|NsC0|NsBs4!v!X2WzfJJrAH% zvKLoql~XkU00000000000001ZoV`@r{XG7PTPL-^7(Z4`(_li@oT0)(w}lcs6;KpgwMcX#j3v|9at`BYl1XFe5Ww4W;iCJ`ZM>ABo~! zjK-tjhKhjUD3}aIca7|f(K0Sf zX+Y7bU*Kc~yC)nA1@4SUIIYK{%fZASIH#S(PQuN}T5}o@tA5+R28?9XY`~j$5FlBB zFcmC9c;!_5%qg6ow;OPwjCJVG9<*O~I-OUY^Y+^Y%zbYcHlNLe%h>fq<>@(%h0-F1 z1&_#1Xyvwz9MK*&(|yVE=j4wV$a!d-j)BAG7;= zIWYMs9b%8P;-F`R0~EXco6@+Xf8erPPbOZdec`um@9b;)%xymE#vXMTv5ZPDUdH)v QRu#X$nDtQk0rU@DIF?VT?f?J) literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_parse_bool.h.i b/src/hos_libvariant/src/.hg/store/data/src/_parse_bool.h.i new file mode 100644 index 0000000000000000000000000000000000000000..a89095b9002b6acece46cc8e8c7eeb04fb0a602d GIT binary patch literal 784 zcmV+r1MmC*0RRC20000000Phe00nOV0000000030|NsC0|Ns9E160^lTvuI_I%enX zmCX0p)AHLD?kWEJ&aB$dQra)^i|g#0H#2YE8bx1T^V5i;H;Ym_P%^W^9)OO8MFeLG zzZVvJa4l`ik62YV0Ixt1}aX(qY_*CE? zHCmxyR%c4CDZEDQ5QKw@Bd)}pnX*I39C0t{sTUX-Dj>Wxx(6uf-og&8qu+3Iu5}`8 zfw9bUDLhYL!Bm`gMQtBI3ICGXCfMI(c$qc_sRMUuDw?b$N}7K!m4XbRc39M^6`HO+ ztdhmUbh&_d@&v1RK947hryhZQY3LSrc%+isN=ag-xvbFsK|ujFZI^ z4FRKMF&U;QjHYvlVHVF9$zVB-=P+B&XVY}p21pUlIy1?Cq%OkNNX{I+kjlLXaNN`% zaFRmo2q!XyXCVqn=W#L^PSPPO%@Q*O`($q=8N{1^?ym)jUbkED;S(&7q(GP{u|{~$ zENRUQx3`@Z^o{e3evF}W)9rTOcW*l%Td+*ybJ^g{Lh77%VnTb&u`*WWu#!2#3NxUU zmEKo(QMBLh+l4FI#%_4`*YM2ZG=L7Grlni>W=aixEA!1(Xu60R7qXy-Qt&d< zVShRue}8CPP(W(@JyuykNi^0PDM_zYP4j$aU+T?Qt`_QKRx+8e4jmjX!;%GL#wa9x zc0$$ICNSd%Mmy5QI?$#Cg;4xjI{co);}Ds}oeW!Iw30s%ngCEVd8uUhkil1+L58*m zUvf#L@Co8=jc|Evn64PiZlFz*(~liqaXXM~G&#}1zND4AiYySq6GH}QhC+}jQ8w9y zO!_tqY|+eU9Hr{h>2gh4cmn2kcPI2a`o8Kl OE>P3|TH`0T5Vcvm8F6C( literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_parser.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_parser.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..c1ccc7de7111a5d1356c95918963765b813dae4e GIT binary patch literal 1276 zcmV0000000030|NsC0|NsBCO{a3k%0O+t=8qH} znN~~hfyy zIh_<4dyH2#UTb$9%2nxazgfS4O(7Azg{%I5-uqhuB`m$qGuB!VL$);lslPb1A%sb)`ev2!la<7B{5j7R5yjLro- zqL8$PcZIDSunAmf9K%uC0|7kNdJUqzg3wVL)fS2E3d6=*4_K692RtUv0)iy}mn;ln zhLA|~ldzeRP88f(lbhS=1kB+*+?nICIh@>|lduXno#G>AP;3#0jF8DM;Y4ah^fkhu zJHEOh74y>STa$Zo0(#bD*tKow-HyS8kvX1NSJS>ZhS799y0yD402{H0vj%w~)P9;Z z3a5w4VWHdvAj{O2IEBJ_BspgmVi5?R(Rbgv>JII$j`7$VH7$p!ds1ECmP}G?4${oTq-R+FyZ9g>FMd))3cL5nlQD^!faZbK8rk^ z6Q0u37ExqIy{p#fWb8md2Ng0OOjlQ( z>~wxq)W%pctVqdELW|1)0&szgLPlt`lGKG3hxXo6mZ7|m5+ zGzupVweONV9B&)mgJMLu%=0rqYHh1Esgw+H(cg`n%)wmJ^dH9>Er}$XN7T0o^M5c) zu{6Y?jC#~tDiPAnM%Vs_RuMmsz8FCo6V$+`)_-YtjIwh7+=XakA1c1p3LCNSga@0LEs=b!ep8-LYl%t-sTr zns(6+9TmK*oz-BP)3%=O>}8!zr{67qIURoNcW*w9%Su~)cDLsBlpY^tt#VA#CcIlO zZ~SG=O6T9LrN@v~p$Xz7p(<-{CRDEav^P~5t-blmGVycH-~*JViosfQ-Q-hSJA5}N z?`dAEB~!}83j}h^XFGgatQ*L5D6w@T%T1Od^Q_4o4}b$$Y^;=6yunc7vqP{nj`a+5 z`68yf>!mN^6tftM=|Ifi0ww3RZo>f%emTs)s-f5Ok>2^#t-me8J&vwD-M)^mRX$s| m)f!q`uU^gr!d$%Y4q#NV^?H$B$T__LzwU|iQ~f{xqz&vhre~A@ literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_parser_input.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_parser_input.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..610bbea5f82edc55591454ee3dc0786a562b8fc2 GIT binary patch literal 1531 zcmVx90a&l zlvdWk?fF(ZcIoaOlqTf2clPCuJHSaQ#Yi@{vop`k&O9@>v|9Zi`Kh*Am03(BBy=tU zu?2jL1R)@Kq&9&dUD)yz76Ai6LMoM@^HdR_3IZ0kxPT=OX@qu4L!~Sv0#r;u5wVoO zBeQsOa|_qb!5hMe2oe~l^Mo!?ydX>x2qdhuM8+i4Nb{|+ywb5uT`X|L(LtanXI&r^ z_XVtpkhq5DnJ)+E0~Z>{3zR;A0KU?8H4J+TNuc(oO;kIThW%+npv+*$e1#{A5fab8 zp-BRB0;wcXn)oK@RKeY7_V)el3Nwcib({ruwMqH*z}{i_eR z(?RCea5JJT)HUHIJdJV3MH0dt4GG+lIbg|RrB8tKMS%_WuYL!a-K#dp_Lx!QT9*VLt+ZN=AM(*i zP&gSv7gn9lm%_@c!KdBR_@0`)lp`p}I-MhtmoiBo7`7_rI3nUcA*@!dR61_$6~sQu zS-SMv=7~pIBtcu9SAD((XHvnM(-7(>LU}{fSc$#=bL|3)QmN1gJOs3h z3W}i*=(np^dJmtW--k9T;Mi8FV9@TuPH(&AxsCdxjqxvSxpTl8u4nMz{M>w98l+=a z--q=x*bRiSicLxXC0@-zW@@K*E6DjyXH6E0i{2s*#3eAYahccoFo9H-WVz&P;+^N4 zAKQQVhmrX@a%W+1hYUz z#e#3ZR9mD>(IvUZsmFzPb_|VY+~SPX?=E4T*!Lv9@$t2WH#(QWAunNZ-B+reBSKsU2%pUA?9^+XrzcgtmgOSvx!NHC@^;u4yFmL=G9IV>A&Z`f zGFLdgEMY1cV{%c(mt5dojjo4KkL;WB_@(;W#mnc&2YprYBJ)Z#VdsZC!Z&m5G4h!- zoSJ@-{`QQ)g|AhuOH&7mHypzZ)H4^M!q{@N&y}Y*=(Iv)31yHR4Gi75y<^$C7jP+U z`%4ME9-Ix0FO8#TOeFZy#L|JYqM9}~=;ps2&5zD7v}vLNzAZEE76|o(G|;!j^6V%{ zi)_e+u0wQZATQjG4@D{dlq5yM?Aa9I4=?8Jt&FCnjj6~pQ;Y8|#Vs>GW^m4HTsYIh z4E%p)eD_!izMRT|4KZ3I96LE<;*(x=an7B(?PlWgg*TIW_I8xXpf2a%XyjbiGpeWC h`Ox*Zd)m=CM{iup2clRuV2zc#1@5Zo@jp`$B;R8Q=N|w7 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_path.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_path.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..9b9842b2e0cbf4ddecaf93fc9df07bf5e27317cc GIT binary patch literal 863 zcmV-l1EBl>0RRC20000000SQY00|QS0000000030|NsC0|Ns94*68ze=j(-3H)5K; z1ZqBGNe8e100000000000001ZoTXOZZ`v>rehz=dHIqgt9c-_(MOvjkY!6eVse2&^ zndBf=gA>_KyRPDY-`P%rNoiJTFLAiL?|%CW)AMtPH$2Ay&WCCs^Pq#ZJ ztYR%WZh&5=gAZIJd6gnu{bG_cp{I9DXOnF1X_V3u*={}<2)092vIHUL>qiHGm%$)- zEO-icOe!?+$UNX2x+DcU)|ZUS}hM2Z2*28Iy3Hz%>}nBw3MR zG`j5Qk@N|SolTBnOYy9c?|UQJ*2vaHkprrPl?Jw9xx!Y=MT);)Ngwdpmpx_FO^6aW zy9RX027CjN^H~c56K=xF5=9y%7x2aA69lgV2YWzz1>?fTZ#)=*Dg7FT%V8sQC2?1i z8v<~pA``9-5mZ9)t-uuWg6g&pP7y!XYUB4TA`r~yz(=j;KxeXea`TXt(0qq0l(LXf zcxw(Y!!w<%*TS}Y25}ft>rH$*!Z@UKKolAnh-$Y+ISHG*_U`a@U{Y2pTdi605b?&! zHZIAL)q^$}cgNB;?Zv~qZuY*@UK(Umt$N}*$xMSANy5l#I33RVvh>@0BGEO?kpYQGCn`QNtu;@Yex8Oug{|Nr> zy3J!ePK?OB+iPUOxGVK@WG)i)jTs2FCt|crcp%1J7PPjW(@QIBphs+KK}Ii8S5kCP zCa@pF;D6fJI)R3to5-d-TZUI%?Kzx=wixHIIO3v0DU-v7=)zL|Y-ZiBxJJn|NxAd7 z#w{1*^#ZUCL+u|?leneTOBj#2$F2O+{F|!tZ5gY}?mHw>x(2fS+S1;`rt?_Fk>0K>L$CYp3yl-LTXw)2;g& p-HQiNJPEt;WQ%t0`nkmVOS7+UXuYl!c+&iBplh%n`~`*baz@qjq;UWM literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_payload.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_payload.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..8a3ea0b4017dc6a66aa41122fe377119444a1914 GIT binary patch literal 2983 zcmV;Y3t0330RRC200000017hz04D(e0000000030|NsC0|Ns9WGL4oT&2%}wPW@jA zHg%Thy?f;V00000000000001Zob6d{ZyUK0{w)29i4S#FvaBTSH~Hn@#CGDs=NPur zLwgAXN}?=YR$O(-mF+wDetT#5w%ql~maokLMH?8=E;%!NW;k!;zUp@2^Hij~4fwzc zJ?ekvYT^l4udw+_Vs2Zx0Mz-`S*NtVaOsFz*}H>`P>X z4jHeNb6w=p8SB1WCqScxEc9|EZ)3YuWu3DkO_Q2vl-u@77kW`>S|0Xb%2LH?zK}{> zOFjW1(ZO)$b!8N(uMvnD#&LBc^mqozvj3jztGfkHIu^*7DegCJFd!r}J9q@*2tEAk z&I8uB2sN;hL6-dkMT35&s=%wf;7;H@aMY=R=9qN#M2{?eA~nC}c_VNG0|^ktW9UCQ zyRDYtDV`8?jIN?rOF7JnQOci?acQ!{Y9V(12_dIKl{kVoEc=(@7jM(%@F2q7JsT+7 z`xV9E*V3;V=3xuo?7)4D`7OT|lAt7((Jnm2&`tuma}ec$0)UJ9cgMvdP6+ z8@_jG2<-&}`;0o;$r`yq@x9L`mchPQ4tkDQZ1yW7W>p5PZQL$YEO;}+stL&&l&g|N ztK~Muz8NeAjFGwZhPJOE1LHqmMD%>&BvDNO$!|yj&)=(YJ5proUvf2PEc+NPnhB}O?Fspy4A8AD7l=)zDUwk- zaf6WU?WSl(+)o8Fl2l?D->adF0}YY9UI1_JPeqR1MjXQ){7&#Q%SF0W$|v?t+$r^B zphpWmG*h_}ya;hxmVFA;hSJ{{Hi=)U6CA$GA2_EtwpSAuTOz(tqb#6Q>up-rlT+j0C20qEJGP{u^KGL+3rft9ExNeFG=0~At&dU-tV>zD;7dqc{$A^z*XZI;`dZDRb_DXgV4;ud~ zrxz?|a~1X7n5j;bF@W1uix-bWgF#+ME#`d44dRXRfHMedpvwUEtTTTEft>%d5II+n zXPL(R;d4$7lEH`rgE?FDH#(tjHr_I!o%g35Nc|guBkUBPmq!;T2d5|hI2ykFbar@p z^x^Qrp*?50;>Lw0)`6^oWZYyU9+Gf@#gr6Rry}$a2tn8^G(1ISe{Hwwxbk zUB~ddMc!=KMw@RwS;Dv5Sqh%#G@`AU9QaVnVQgEJU zw|6HJ3nd2D0#Ef~3??_`b`T-jQ7YCYaa?XA@_i6yiKWPO!BY4w;;2m6n>JI;yUtj_ z3Y)$i@x+Gg0&68U9Z7sOL{y7hEHP#Y-YQHZfwSE?5Ey9_UR;fo18O*I5Bo2M$Bs zj-?I9H+=r7)awg%ye3oljyX(`V=A3XTsPUQarJ1+w#xyVI<1e|8esC(9P=^t{!pQ` zboO2m0=m!=##U?e6oWLvxowVJCILoP^Q_KnB;I$1hg?0;c2<2uuG45@KBQh@#D|Ja z{dMpEyT1R*u5Yy`P^9AtE^^XD$c}4Nh>~Eas8_S2iQ%-(nj!YSgYHj_0TH>O#0m(_ z$OXrSgULH2oiib+$)N5+L9w7dgh{$@r;j)^!vNbEj5?<2&9oxuW(z!|V9(R{{cM_L z3xD%a_5n0nFVQxZ-|Re@W}w><@c=fv8^bLxt7c!x$H6{NiM9#Bk3-@9uo>b+Kxlr0M=Nx+^F2|URW}I3v ze8oqm&AV|ouqjsc;cAA$@Gq0;o#SV)#C(R`(TqF=9chx;Dt#Oxf+M zme#I0dJ_@3?qz)J46+*Pva6cL`1bQ~^L5Sh?qh8ACYhNPYCljzrW8SFTmk3$`GgKU z*pw|B&b$sZ(V@7+7yQ*%Ox8PN)i&w7JbmJR>Vm0lziTwAwff?!et5SNiC?ro9va}C z)i!9<{BbRhPfm}ZJN;ud`p>H1w+LMX_aC}y^oMGrM!!d$kR2QOLQd>KoJRi*y@Hr5 zd{!_g{O9XyP#G|rPS$hv53y+3*K55S!ch^Db@Pc^b5&!nb01%HEtL0DcLCMBduw4` zxryuUT>ZR26g3~M_MWwt(l(!dzhcX;z%8oU_QKL@seO!zs?zV3>2mF){~XQCdVY=P zYxfMLLX!N3dVEs_no{Jq)5T@P-=oZZ`(K7gPzwM6000Uz000000Q3L=C@KH|00000 z00RI300960|Nn1>hS&x>C&J#Fdsw2hA0Z+J$`}9u0000000000004NLZI7`|!$1s% zt!~Z&v=X!F5E8XS-K$oj3kyOFWsV&6QX*Y*QSXY1Dh8g2XW=z?3VaDjiJHM4Z2zDC zAK>B(>Vh0GGe%RfEzMq~6~Al48(L7sd*0dPLAhw$U5=-ev$iTu?(IsnQ9KV24@K#A zd`unvouyipTlXrc**pNaylo0T5%KIK(e`6u6!f9q zyys^Yy{@EBY37Z-lvdwxf}G5-CBLE*#5B5N zJzwHnPQ_fv%M=C(iZD%f2o2$RMy_d=!*}vnjwKNGNtz*^UQi$f8A)f@Zw;n>N1~w6 zT?YW>V}qu4Lc)aMzDj36*%hD!`ftK0A|p!5oKDNA&n8_K=LjAu~@n1QY=NQyg{K4N%taPs13=(6|x@b%%@uRsKOd3bho zaC%B!9-ojs@^=EfK@^_GX_vPxAty-|Ugi$6H%l>s#BKKlI7F(>*yX)6Hp^Oi(5%n;znL zpJvg7ybmXoyr&}qBD*Sz*>Gdy=H_NF&8LGjyF|j5Y)uazl8?xo6#^fE5`>jN;#7YAf(bMqm94Tnh?(<~fcaI{aO zG`R$(1M}(ba7br)2ra!eh3Dkp#k-T!!{eii*N1No&k)bbN)p60pP>rFu-BYl}O;H-aG68M;1CH|f%SvTV{M%~=Lmoy5 zhBIOKHZ4q%Msb~n6S6m%9AsIV39=ZExgwF(82P3Ev`F~(xUWg=6O))V#?uz~`=o}M zjP1xyXHY`3rh#{mPyiXgsHf$K51bA%nwL?*pQ`x)7`EUbwcKz=U&T&pZXE5v#n|aE zrE}D{=N*g_K34!HnE5$wLn zZ`yT@UUcX%%2MH^n2#fAp0nN^_&}aMC0#xR!8HnV3!q^Ff5#<{U6|h)ba^jl&VXb9 zh>bdXJ&xP9s+Ze0+^0MVaowcC*`2K%wCO!DwDff+LlJIYQ^7?TCBb+a;9 z_IJnjLwjYB?!$m=9GsTf&~r>?EKLa?9z-;z;8Ry;Yv4V{#cgkll7+e@^w%su4e{)S2nJ!C zXJpfQ3aJvkt+X=uL-P@)i9I2j;Sl+B2w5}BJi?yKNPPU9UWTw1t@R1@K0in%Y8ea3 zgJ*>9kVlWgKK_FPvmj1eg4CJ39GUi_4aP5c4&LWviqRa?k{}O5!=9vuuxB3gu$cPj z5m&tyR`^9m61A9_W?0dk1uDEJH(pz^u$Id}#F8JQoyP=(Mwr7_`tItkZDJUvwvc2p z1SGgbgDiLzp}2ws9OUeH2BE=2HkmPu*kuSifX$dI;>Jo6{0krTyloHU1VLX+cjj_r z)3#+5`K3IL{o?Udd&%9BJyn1h7xGl1N5xa|_LiQC0slFkN{U$wc|S)LF6?h4JL>$6 z`TYO3zcKZut(%$aNrc4xwo$cJ}1#53>7YMwtU3`t2irLkwsqwtE zn$~m4&^<@>s(R;hfG^T`6ediW@_WkL))^ymHHNnRZ8Hpy9-Cn>!1qE_W6{wkIxZj^ zp}?tR9Mb$}8qH|tCDv23fXug6$?>aJae$P%*s!juWmV4Tj!c6v0$p1tztKCcsPq=J zW5`!VK)X{})$C=_C)g_8Ut!J_Yn~W*yOL_vm(DQulp1frp6@j4vx8X`V;&$PJl0`OxHAP40Eb80Et)N*i$&HrOJ#W%>ganD>SL^PvYv6O@IRpN~b-xfpk%br85NN5XmT4fng1(9{`QhcxE7gu?FJ{<~IA}A-E*nIjg)2XJ$2oj{L=-N4V`mNSp#heqzD=VaEC z*-WxBDZ-du(59U0U#{R)q3IIO4JbydSaX!75jmrI;Zu>{tTGiRg^o>WX<2RZ|F5wm zPvoLWMZJs1pXjl;F4RmLN8VmOTzu1|9V7-iPg1cNMf}#Qdfvh-q5i_4cuPLNUK*x%0IwS|%p_7YQkv(JR3KI0(GX5}Iw?mX1C%Pvxw{ZF#RE-f%rHSXaXPPqFNR=!#mb_y z(oUy>!q`7hi$;S0G*Bm@H?E$l2*p_Q)^rd3Q7?g3vRd^mWR>c*wSBbXTTJPI?~MCa zKXWDa=Ywapx@Ik`hi zm)RKAVrc3{wW6&iPgP4bbM(wRuwyR~=eB5Rk20d%o!FkB%j8e8E@ zZ3tfV5_vTgXIymwA&_3*WlQ)X$x5x)ZRE0laJgbj1U1a}bH5Iw3>Ye+(9tsrfmy#7syT&W`twhj?6zTyL|)71pOw7=^HokM0NzIsVNe3^fGL7HdoYsn!DDgvp!W z_S@KB94?qyI2|fkh5Z~eilZ_f(M+pU874&>V7dpeGsk1Q-S_f$!XfkwRb`sS>uRvh zOEk95)+w9RwX-xOQwaWNW@LfKT_>c+E70a3&;jfaMhfFH=E^9C-C3EhkZt30i+sz+ zB#etrXzmxOsVl8SYImrL)OtQgq`_@Pq)zwwBHdMJ78hxZJGKkSG`KZnD#rcy$+X4? ze9fjLBU+?f})FR zZL*TgQv;H7RE!sAm*?B>G zf$b^`_ZJv@&9QYJuzYz5oQtObjEE&<0RAY{=NRT3XLA?37T^tl6?%Db>1CS5!E#?{ znKG0Mt)a3@W%(2j&h1l37Fx4*#=#BsSN-i`nrAD#?U4|3H~|aa*u?c&5u`!RXWrs~iSiuk?aP)g6LNyYaSvx)dGvz?y5g)p zOty@Ij8I7BY0fS@5Ub|ABlb0CItpz}5|Mb@3&zA9dn|~H(T)Mq819s^Dy!Mm)-+%w~SI!P2 z4RT1TQo|Kuh-+RMP0)3TF6or~3jeLYd9%L1-=8T#xMv)E{4^cM)!FZa*;*wnP`s zuAjK59)JJC_a>^xtxF#1 zJ?mz4Tj0oBt21x+KJ?ZuP^lh!6a2GIyBT_1f9TD3>dhCERCY~_ttyex8;5R?@73dK zwd;U9yjHi{DcrjAx{aW@OCE`j?uL#yXfqfL6k@N_?udhaCNX}%x}b|sP#g_fY7`=d zUnmSweJXK?d~#kr4&8VL$O=Qba(eUkr3WNN45a672SHA}vRrd-VeI!b^%n0x)Shl# z+|H|3KHtV|(JJfyO50u_jC1T=5)WjrNY_=Ny=C;~aSncqSB^obcLk)z7krbV2}jzp zY9fJsWfSqtmxinT=~oo&D#5FlRBbH_*pVLgPV4BdprZY!nzD&+Kr?$^EISuU!P4{Q zf(pA8C^yS0daau`rzIC%_!#%Ex-1}Z4eYDC{23D8CB6ZdCGm!ej25`8%XkD{Go>Y0 zZCVPv#%nC0Zc|rZ@VckwT8tglw1E|6n0A#LzF)j#7m4Cm=Hhrg_RMDiQju++#lhR` z>8WuS3F6s{PQ+KJ(8}9I<&P-zU>0bViK~QFPFl@ZYCj+8?Kmp)@ES$L3DYMoKUAOU z%^5LsvG;-L+`af&9e+8DC6cA|cf3Ll0xLDroVDWq9Jbs>dmXA>Q4r|<>q)(Nh-Z!F zVLA8(%tMa*P0ZsG5EOEavI_H6+P;B>NZR}sVvIc3LKb0Zb^LF_Tc4dQox`my#3r?N z32tQ})zzqsif|U)|5he5fsFx~IDhK5L^YT)M$rXJj>c1?rtE*oJiHF`a1_z!cRoz! zW4AnQr+4*y7wE)l I(Os6_Q7jWmQ=%9fNpMqz~jNVVxjWjLtVUh1j`b4s;4+Dt4K^I;w%CAn=xZaortzxMk%{`)S^na>%Efqlw1YZ?4_hI&%yd2tfulL z@iZ70{N`kKB2nD9idz);Ds-5zi*L!+CY}Ni_%JP|x6m)b7cFt~f+pfFX1uHdlJzN0 zfmKt|FewJ2-)Y*%*A){g3JZAHSiirCg#*AKZgs`!ZDK#;&Q}rxSAaKQ=&zx5pEU|& zH^G?ZrC5nE_%f$Ykw!ENk}-u|&ULgqs@faFDx?9?>7wEUqa2>B%VF0{phYSVEn)}0 zeI%(u9x1I!H53t%E4v zf(rlO*&_D%Ets|76&^?2RF;r889|RXZ!*@0=1fSWHSKbs1F-d_){AK(0z8KZ-kT<| zQBh^E%wIP}8i`zT*?@qd-K|2{&wd#b?{dHMmW>-dkV&j;C6rMZW`3#9@k&lV~-4Vwx7^>S6*oy=gQm_mgS^twTF02 zuP-pDLzz_^{$rOO91vyTR)`PBVNzJH6Ic~N8?P_AlG)PV$d>!hASQBa7)JRkS}^CR&hyaQ88Deny3z~T=EOJM%(H6sj>LR;>mzO$Yl5^gb{%?T= z>v@phI}WoJz2@kO1x(Gcm2*)4epAwyfAgPI7>f%pVZAxPGbYju#Jw--l2vE@tub_O zF8|kzPVG7pYw_&W`(8yrQSnRV&DZxGOj<$K>`MkaIT1}`5i7c=|o=u+qd^aCWhj$9!2s;H#me-0g~&FT+!5e!ML zrHKy;>|6@c8qLugp|j8AEC;TlmKs4It}1iei+Z9I`N*+X_JI^DoD|r`w%0d9Nz+Oi&}4EVXwgf-e;L} zRp2d7^xS;4D(g|XP*t@yT)OCIm%J6VPYh93il@tDbtQNCHont8<;6Xx#hBW8P52;u zYNFPlBwcyER!oua3>cS#avb=c(d@2Q_uf=xZ1et}=HWS?y?R!2k5}CVUdAoHE==7; z6z2UCUfDQzNe=dmn|8eF>1T&{HL#fz!s0v|WHs;Hy04e<8-+q+Cs}sXS9{ubmHCNw zdYf;i+BEz2P}*P==r+&&EUfo;5|6m0*<%g!`-&evxL03siFvhey;u4gkM#e2b#GE8 zDFbu8S5i1kaxj1VAp^*!RDy}AxTdZb1UW6P!Z)mK%)e+|xfC zx<6jl^lM}+H(q5g{qj2q&1RM}qsb0QO!GXrq`jD3Rfxp%Uv^_XSsP~zZHn2))bqSN@qRUY~uu4=(3)nWd#T; zKzK=+X|eugLUm@B?UC@|#10Wl$y*>}u>-PKV5x|HF?7PG*a%&L8z|+kHb`By-^XYg zP>ooQI2-bzz}c|G>Va}&b(Q;l>M6dX?Ntal1ANijiEoX9)o^H5ujc!aT8H6r4)~)W zpR0yojlNtPvrzxp_BC(tW!sj}->7WS*yH?rbgE(Wg_Mf#a{9bitsAO$K`q@+HG6qrOQ7XM>`p$HXaX!YEnxST KmH!3nhx?wETFuA+ literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_schema_loader.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_schema_loader.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..2831876d860989f78b166e5def2bff0f2aaf6e2e GIT binary patch literal 5488 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 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_stack_trace.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_stack_trace.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..52269ba34a162808aed9c5ea28dc249893e8b795 GIT binary patch literal 874 zcmV-w1C{&$0RRC20000000Sxj00!Cs0000000030|NsC0|Ns9v{JN@CiHe+6VtBsu z@^muVd9@(`00000000000001ZoV``=Z__Xk{Y?LgqkN$2O1d9Hh;<-kRkszku4+=1 z3DD#um&PKsBimUii2t3tq@@*1@MXeZ>YVSrd-u*(yWKaBxflQ5GOav2$6RzTa- zAcEDYTMC0cSm_dCp}=4wturzz9fEWqRMOQ37CMnB;T%(yDnSD-LvUyo7Ia#DT#Tl0 zwJvah3XRBNTt>N!DIBA+2*N_a5u0JcOwp=Bp0k!Lv)`ig$BhxGr2W;fKNtlAcA70_3ce>xBk6)T{nz<*V5nlR1211gh-3xA zI2SR(3uXyQW;i}R=)jq_jGQk#0(%(?MLeogH*d}4DNK%2-&Od%~*?4;6_?}d?yKIXue zL4b84{sPWW>x{^?{!$i|aSNXQ~ZjtRH^o|w>#0;x`dvCfj zieKl;6k1Osw^7HdKx4FNHUEG&*BD*~U1=0Fn|0_%t(tw%wGs6=L0emA@IBq}gyhw} z^k{!tDeA%gzT6c;SU5d}$bFQbdGq{}dcIqZ|593{y^gIF5y+$3t$H$zp9R4o0N8A( A@c;k- literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_stack_trace.h.i b/src/hos_libvariant/src/.hg/store/data/src/_stack_trace.h.i new file mode 100644 index 0000000000000000000000000000000000000000..ed577f5fccf814c668efadae16b683c990e90420 GIT binary patch literal 910 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 FBQ6dpr5peN literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/argparse-schema.cc.i b/src/hos_libvariant/src/.hg/store/data/src/argparse-schema.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..6de4546a38e31b955563b53a9c2a2e2cb3d804e2 GIT binary patch literal 1714 zcmV;j22J?@0RRC20000000wdZ05mB80000000030|NsC0|NsAk9PKe_y5FW&!(3g1 zo)nle1uc*O00000000000001Zob6g$Z`(E$e)q574`>@(mc$sv9)hCSUIq+F--aPj zBsnpVIEC$P9ftn*IU*%~yd2)_r9jaaHI>D~bNSAdytrVW9yWWn-aPi~?`F^L`)$8# z4t>Y|+;6t`FaLkr?Cw7|yM6z5-#+wD4QsX?Gv2-Xr+IpuT^y-Bv-Y9c-uJBUHV1Zi zc;5E|_5HAH*B=QsFB`m@ZJVcl|G8;<_PDwGtJ!Uu?ScI}>%ScO-Ile_+x_8%){b3W z|9tz~)%DHC+nW!+eEjw5_U6;|?|;0X1wUaw9qBPP|HALy9G^w;@~q3@Sq;y6c&>(L zum0vGykE;-1*N5;v}}gI=Wom%7Q=IS21=FUjElcJZPh?YtgB!h$GwMLInWc|6s_9x z_y%~Q)>UgI*CdOvYNTXPkEAVr74MJo4wO7R$8uatO2RI!TIZ)NzUOoGtVf=Dg(Pw{ z=!v5p1A3}2!Sb!z+ry>cN$9Qyxl<`EB_*(}<{>;*-Vx*WYROpxHh|q|WZI~sX!Dh_ zo$wYRyGP^kwC9qZ;A!PRf9ei`lC_6KF+?WZp&I1kowl2ht^hw;X~>;;4aOY6xHIZZ z>!_GBagW~OM^6D7S}Utb^e&JRNyE~XT+KlP1?tH`!;-o#wAHv4qOW6ht6|UB&G=GC z*OInXJ0M2L+)`rvvLYR2d5oM~YFu)-GJnU|MsJV`gmUqo*4 z=ms?dHC?i9^lDg8BKS8nVImK!e2o&N+2z8`6IOOpq+7r*m1Do)Zlj)fVN%M#s-2|( zPaNN@)HlxTiZL@r3OeRkl|7Y1zK^;fK7L~M=N(zGrbj*CDLWT1Rbj+v!V}}bb~480 z<^l$p^R!$**)BKU+1`?#3z(T(vU7n&DLWT{#!t)z45DwUZbTgiJ+B@MYN&dtTGcZZ z!W@kKGeN1YfhT>waIOkt#5f%ZC)opqm^`T@~0GC?T!y%s}~jI zX606V@>{z=yo1GEeXv|1a^_m$DR>@$y_6L>C8f~ZUwj`CpHlD?sR_RxtjR;t$q4Gf zTNhxh!aMiVg>fktOhdHUHh2IXpTvqOB2S#jZ`WW)YC7F%vB1wquU2EVHen89=0a&) z#-xFgsJoV>TIbvuYu^P}mFQ$V*dn||>Yz}%k@C`$Z^XDhEi(}TJUM4&-bq%{tc>vB zZO?FdcLbpvl=^V&$-reOB@0z{Qa2Lrc7(SU4B&O z`D#<6B<~YEQQ23Y>9M(EqUXf8etNCGjf=tFs1h@?o8%#87#ST}R+pc05*X|VOzp3< z%o*JgWN194LiggyIjd0G&?gn%p7R{tt7le0VO2<%GOM68hxagIW);xGNDJz7UpQlx zo`8}467<^wr6qVn?T;!+k=X92v%0*oE;z9}0A$8jaGpK!>@|1F!(KCv*HAOb)h$?p zYx|$6R^i&oa%T1&>n-mYb;3=wQma+ssz656fYu}{qjCZ~B~^hGhCxqM6^Onj_AJM{ zVFU`qDU|1a1e^P2R7CW(Z_LO(4mw34Ng0I#L5aFEVsMYP%bKxOdhOeq+z51+&@Tk} z1`m$BZ(-ntYj{eDR%CNIhdq|CJ&l^L!G-de@e=hUOY)|?tmWZ7fz?pD=Tuk z_Fc`N61DOzyZod$BPbEEA}P+i?io;AoWc7A*8SY1I1_zt9-JUq8G(1R<3H@{d-iqq IAA%PyvQArGWB>pF literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/argparse-schema.yaml.i b/src/hos_libvariant/src/.hg/store/data/src/argparse-schema.yaml.i new file mode 100644 index 0000000000000000000000000000000000000000..cc4d998ea7800b0823e653c39645b00491e15aac GIT binary patch literal 735 zcmV<50wDbW0RRC20000000N%?01FcU0000000030|NsC0|NsAo@Dsn_BalCEHQYKg zKOYEAFx>qB00000000000001ZoW)g5Z`&{oz57=PZh>5!r2%&GZMzK^&;dIZMWEWW zqfVAoSqd5q`|s0-9XpcTG#iHLCX$bO6se~yzwN6%bT}_jzE?_=o6U32+1gt_aM^BZ zi5s=P`?&G8n>?$bA&e-(Szl(zEL_btb^+5}iB4O))~HupLdv$Q3|J*SO6oME!L$!O zSO{QsV63=iVeUOp5n}7ZE@3vz8qy|>J9|-S&k=Vt?Gcnjm5we+2BPXHAiT`z5=?Z+ z>xpv;IOJrqLJKmmnw(FOam6&Ht0toUleqGiMEkXGxDNga7S;=F5-P7 z$%l#NFjvJeO2yc@N5l9AeHT!XhEzy#2SvFL%MoTZ$_H?McAjBMIx8IGX&w^XK!;x! zqEe@NQqehIfwgKsR^==YyBYLKR zXJ~db=;+wB$u=K|SwZflUy7e@>lEHfuEl?9-g~|!yWamb+0|*K&Fvo%yjE2AtUk`3zxyYOLHxb$7opIPwGR2PY;^}rMQuC(b9|D&Z_^Jr8tL5s R(}AB)>2RLawBHVF3)lb}RdN6T literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/gen-argparse-schema.i b/src/hos_libvariant/src/.hg/store/data/src/gen-argparse-schema.i new file mode 100644 index 0000000000000000000000000000000000000000..502ae7db2bf4689dd0a2331a3e1181b55543c785 GIT binary patch literal 323 zcmZQzWME_f14d>B2FA4zHUqYb z$8N;D(wMbzm8@E2UuZ7N`DKZFCN4-iJ&!5-OHz*M7tNoml=bIyt=g$N;i|>KO|o0h zF6pQXkqz-nJsqC+T{`BszpPuCv+Q;jMKYbirnDS?L*XqFiw`CtiF5wEkTy~CqPsiqy1wl&I zn#as8*WNzMrjsr6@@C=$&kM(naqi2y-o9hTqfh6bKVZJS)-7w_Wz`)A_8q7bdi+b= MdF2aXwa@+801q^nY5)KL literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/gen-json-schema.i b/src/hos_libvariant/src/.hg/store/data/src/gen-json-schema.i new file mode 100644 index 0000000000000000000000000000000000000000..d6e9af996786238e27806676322a24accaa8f095 GIT binary patch literal 271 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 UtN(m;{6~CwCB9t!2V%BNXF*n+hX4Qo literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/json-schema-v4.json.i b/src/hos_libvariant/src/.hg/store/data/src/json-schema-v4.json.i new file mode 100644 index 0000000000000000000000000000000000000000..4dcc940ff9790b1ec860916158ba90a52f31e576 GIT binary patch literal 777 zcmV+k1NQs?0RRC20000000PMX01+1e0000000030|NsC0|Ns9WfNiZuJ87xaVMB!#hgp-vf8W& zn(Z6s=wuNpqBv!sgrkc5XcJRRR{~Nc?@Nz_>-|z1$RSZ89>U<O--56jT3V&5aS2{&)%^(b)Mks_Cg^0Q^JZ`{<6 zjy21;a_8Yr(Ug=npKNmHlmwC7gRnK?CWKQ`Zb68SKY;GVp;vRKikD^M)e_oLYS&vN z1n}t?^(GIOvX5?OqByRgAkq|)ehsH5UBj(ywaTHR`{k=oA}m_s}!$ZY1G1bKBg zOwILQWr=SzwJzD31}4oNOQUH(o>}AL@aT#CaK~S|-;U@G9jK&bq{D&FWPs z_iRx=|1NB?=E>Ue*Pmn*W}c)>c;45|JIb4$uAzC|&EaMNcTKPBZXm8b*=aN?#(D7< HHc3BZl(lfB literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/varsh.cc.i b/src/hos_libvariant/src/.hg/store/data/src/varsh.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..330f15ba06c5b33da80e741b1f5de8b584ac3bf6 GIT binary patch literal 2806 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 IKSwXmI+~Yg%m4rY literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/_c_make_lists.txt.i b/src/hos_libvariant/src/.hg/store/data/test/_c_make_lists.txt.i new file mode 100644 index 0000000000000000000000000000000000000000..c7353529bf4839dfa947c25d114e8e6b53c2306b GIT binary patch literal 861 zcmV-j1ETx@0RRC20000000SKW01-g|0000000030|NsC0|NsAD*in?SnmIGbIc`UV z!59(E*NVsh00000000000001ZoRyc$Zrd;rMc39>5JDIBqRyu1u0Rz>XpPuTVLL$s z1RxlRj@js8h*Tk?=)YHQQIFB68$-jnL!S|^M9~m|m(F= zyfVo@e$2f33es;@e zqz=)$S=T`~v=-p^w33c8>W{KMGL5wRG!MZ}eVldmC^GkjQf=mPXc}}?KT2JRCSsRz zfcq`xQj+Ep<1F+5Uy($)av8uA#6FLNQzBInMpahW+Km#$1DP!Y>BQ*1)Ko&7Q=`Cls9FnvrXcxyg0vzG zvaYHToiI3ww>aYTB)W4i<#{OrW7hLt4_B)&$=8S7=DFK^{m*j30%_Bw?E{{H-06sfzw!Xi$0SsHO1({0qVPn0nYQe_6FnF^Mzo3s n&JeBq7{4wYfNM@d)nvVqX=kz#*1l-k*{q?i4n6+>oz6_2G{>Fz literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/_test_assert.h.i b/src/hos_libvariant/src/.hg/store/data/test/_test_assert.h.i new file mode 100644 index 0000000000000000000000000000000000000000..ea547a4b891562f6eba2154923ee8b3408f0e0c4 GIT binary patch literal 365 zcmZQzWME_f14dm22F3>vHUq-n4UhF86nf~vy=b(UOFvJL4!G$~CzP2t?BcguK1{#U09ZwT6>lYjrsx$hO5 zPqOfdnyzqgx!88gs$#S0;myj$HllaKmD0U>S0*WMuibb1_1C=V^>4nemg;ux z`5*geQzq}BOTQm%uvnY7HerMIN0~4$LGzE_r>inE)?R4+{-TL*>*o8JnK#)rULQKB z(l*!W^t`?vwny7F@7Nu9_vS+Nra1@uy;_XsM=unXZ|6za8^6NEFG4SI%RA2i(M>lP z40{&I8vfm(&J!1+<+-T(!Jn>~{Fm+5>AWv?K3}HGZneg8?=qp8NTDE;=6!;34M)>jA#d%B-b=zvWuMN5!+% zh6=}6D$a7i*Yn;P&qaoZ`}x=VtJ}|?Z*LZ#dS^)Cf*lY`MbQFCkup>hX;Ebi`tvOl z=3|xTOpVt4J!A5XDo%wt56{th*1^1^N?XM)-h9K2Ib>>+6@1yIRe~eAP2*A<#ptG` zTa$W%ZkR4<$^eaRy+8QT>v2)oyq8iIFjq>dt2Ij>8z~aKrix{Y(x^#;JOlQXpt#p?+Yh>roi*sM^jXrB~u<6?(q_c=ngXv`h%DULUM>=!^&a~xfRGk2uH5rwE(iaO@Um-jj!plE{6a-0H}_1VK_pPMN@GZ|iD59n!#3{iXGD^Op#)?Q z-WDbzO@T)Hcj(<#rmV~?h9)lzyr}KTk4ALlU*71)3;!jo7wjiD$!Jl?r-h)x4Rp5?;?yw z{JG(1!L)LIG`hFRUfGU3`?B8!b-FVQ7k)syf$o?>qZ=+(-jZt>F&0kTD7NuiLceB$Df))(0?eKE$yhUX$z#@j zuY=Uu`s`>eD5;{GpSX21v+$h4uBltSc7^5*Yqc;zXCsv@s~o3V9PGQ4Uq#s-7O5fTe+T(aayYvy=<|}Mk0iwC1;UrnRe`t?@72QL(SR*Z@To;(gap!Y50_nE3#c`2 z5l4AZ>9yD2A>}tC8yqCEkW5g(MuO4zrA0O87ft0zWc){{fUx F3a}}PL-GIs literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/prof__msgpack.cc.i b/src/hos_libvariant/src/.hg/store/data/test/prof__msgpack.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..a45126b7fb8a498b6cdcbd25ed524979fe17fd6c GIT binary patch literal 1250 zcmV<81ReVT0RRC20000000g1{01m7G0000000030|NsC0|Ns9P5fDP(wtmd7h8hYv z5Z+|q4>yhg00000000000001ZoV`|UZ=*&K{tUlj>PivBj+O*Ln zs?>-qEno@a+`w)oiA!0CR>IQjOHawdKG0MFNRPLGv55dA+S`%U5Jy}O8AHc|l?@r00 zyP+1T_)4&oNtz|(IYVY5wJ71@p&)A82)8zkl&LIDpd>K!J*lQ8i!)2*LzT}Y^KIzE zn4SEHW!deQk)vy_O;f84M`FcNPl$QkWwKbJ!@XCkRh8igO~DL* zho!(M>6U&&(R1b#p6+^xXq@9$O7^=PqBL zfBNwDw-2AsXP4I(S8w0_N~gBVI9z3NF?+xbs~LtTWmr13EqU0_G2>;&|g<$`eis-jdF-PcP z#vV^BdhpV@KhR&VV|*zo(hgTNyEslN)M`8$=}hPVj?!_NO4o@3*B79x@I}U?EM%r2 zx8r-e_%0xzo)Ni?h)~l8WW5F!Nmj%OQK5n_N7#{zKhqXL7y5m!XL~#T1xv_u5*LC0x3779@_#II*71+!taxv|`FV7bG;?s=UT)J%ZfiH+{|>i!VIZzh4D@MXI&0vjwq5 MraiI$0sqReZnx@a^8f$< literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/rand__test__json.cc.i b/src/hos_libvariant/src/.hg/store/data/test/rand__test__json.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..ee52a789c4f020c68aa3ffa7238baad46ef5862b GIT binary patch literal 231 zcmZQzWME`~faO5yJe1Aw9}3RD(Jf{$uFGeiQ^w%Ye^jOEW4;AU4T!FoquR5ZugO8c zHT$`?+6@iGPmCpYQe384nZ}10CU4lBR<_Xa-)@DwmOItW{ex@FE*U>yF*$NhdfL9= zJF~B>RsPGbFPv9!NG3ry>Z|kF88#M2n#<3drYFXoqS?fzN2c}nr5#LE41{QZ(rqMvw)rRA;Q O-=q70+x~oovlak}2Vdg= literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/rand__test__msgpack.cc.i b/src/hos_libvariant/src/.hg/store/data/test/rand__test__msgpack.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..eab9f453ee56faa19597e7a042a1ef6eaee024fd GIT binary patch literal 233 zcmZQzWME`~fR#Y%3Y5+89|~T}`l?v)d~q+5KO3X2KF57g`y?lr8W3GE$F^rT*C7W1 z*X-xoY`K#ZelfnRF=U8J@`SO z>S(X$<;qL%3ydF%xyLZ;xZIr}ee7pz@-4Ra&Fg+yI`l1))vD~{FY0N&GcUzyRu;p> zmU%ASoF}ZdyIh}~7~1tnWNuztPxEm2I80X?%*8FBdCJ4T!FoFJZ&b-KXIX&<7G7`Vn8c&W?<-C{mQlfyNYvI>6 z_WN4vd{-TtSl7Lq^SZ?YuCzs|;@ZbD57yqOc)myPwx+`ySLu+VJN7G5-aPrIB7A8A zV+UJ_ij{oh8qHvxXd|CVj`O%{4j!>^3BL2oIP>YsR7Xyb5wiIay11A zxLrRR%(KmNVhuz1-`qtCi+nGnT?%C1Q=Gi#y6=~FnQzZMw61ZT_HgmUd5r1{B&_l) zzRZ1eZAqT&%lwL219nIQ_YY+LDDV z0=zFgN=%s}qn}2Urp!p4+@rZKF;Qlb=DWXBw|vX1i~oDt^5n;Tmh<`ioDzPYZq1ot Q8S!LG3x5q`S-jJ60AB275&!@I literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__argparse.cc.i b/src/hos_libvariant/src/.hg/store/data/test/test__argparse.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..4fb00c7d26870a9916b41565510f26cb53a1c38c GIT binary patch literal 2144 zcmV-m2%q-=0RRC20000000+4M02wR*0000000030|NsC0|NsBg%YYPDIx>SR&BTyS z+NLkgU=Vu%00000000000001ZoW)pQZ`(Eye~v!|rwyB&#)|E253}0>ZsG(U(m06S z0$Y;>v_#uPCCU&fx9O1YzB^KssaVQVV1FJGlgGQ`?~X^_>5dN%$<30-tVLizbG1%0 z@@u*l0t#7#q<2+*I<$IcOD%9~PTV2sivS9tXW_1>>SwgF8 zJe4YAG;wLU;8I0Zz7|nXm1UZ$HOo#?vE(biP5x{h zSknp3R&v-nz@K0gMbnMqsqj4-Z9AzR_q-$WgZ$x$APpzxw+-A|Dnb_dD$7~>NgaI< z>l(?vXMfwld6woI&F8uD4%zUM6;kT9%$UkEp^XU6nL1@M%(&SemLFOz4#uCP3HXTl z)*0;c=EypW06?idvV;KgT^CLi%cufs$bAqAfb@o~IB0Gkk&s#1SVTY>0vGw_70`#| z#fy+@l?QxD{BLlF0DP|~7t#-T=k=0jQnd}sL73)>ynIQ#w_NIQ_{i>whm?{PCrm`~ z5cvy}dpLP0_CQX_!c;`TL;@z?D#t}@{*LKLTm7Nbe{0!yU?zgdd_fYr8IT)qAC7n9 z-3U(uB7{^x;T(ZI5Ees#A%sWUX-Ac49{b@vjdO@gr5(|*H;MRi$uem%l)~q!8dzd^ zk9=GXvS^Vn{q~;mN9Kwh*_+g^YP=ES&l?sh7X7Va*TYZgY&y$_GN8L<@Foy7J`Nzp zL)cZ?RD5F z)l>AnAF(CPW7Xcj+FGuB80^fOGdLlmQ{>5lWq4;pEi$@3ADzr6)62Wre0n_wod*Fv zQn)bx?P`2?b}=2z+re0DeQ!RV%?%$Yc*_M(^2G1Lkbc&~o)$kf@ceG@^G`qadv#Bc z#&Wkv)3|tnDg+lVk{A_V0r<^yda;LBQ^%uAuNe*axB|w^T`Wj>K90%deCMQ2&vg@w zOD8o0f|LgDP6bm*a$yz3=OdfVuP2x18r%gFE4B82(%^~-!n>jho>_qM$A@m`7uxwU z>im9t_?=fdV2>`sUjIk!Q(=Yl>E5DVAv*rr0eBpM8|TqvHfJJ6nH-@}D`Xa?wj>biHP z5n!A`GBEk`f5K^Q_mdzc)LrU-Kky?~l=~IOIFCjfX-m8Nap{;-P z2*8?qqURd;vqgOSsN<~txZ-Pe0vGVW^N8qT@}EB^%qr!+a}dTt21J$+CW>TCrg5&p zq{7`vn|)HSU6)*CdG{~Gs11qz+vT|9Kf7CdFV(YlaLqiU@DT*(nj&%%Jz=zKu_n}? zPje`=ni5DZpi-#h4@+^5pF_1x}__H zFKgH|T>^Hg@H0{31R2Z;)O?_7UG|~169c}O*5DppU5zhK8w=Rlauul~tipSmYKGmy zB={^4I_Av)5u56{#uzTkK-#xQ%NOR@v9ZR?YK%FVzJv17;=uj@0*O-^fkUysLMV7U zVc7~|LhZr=o(woE;^z{Oo#&8E&eANQb7 z{LaZ$P9X)2KZkKH`Ih-jTRXKuCoIj^O%jr5Erb~*_Ngzv`nW7I zt98rBCs1m(uQ#}pxaL(1kD6@V=@}Ivjv<|F5Q1r9a0v$KsKjoKxz^HrD>Plx#xD|m z2fMY=pmS#`;(N@~)Ycb8Mg?-Qv-e2(`MdFKR;v(SrVrg)dkbLJMU5BuV0~d(>L}zY zhA_pI>84j3d|Fx0Rn{w&rGk~Znne4qXulLypHfG(kbR36->-BJcZ=__qJ&z*oSoZH zBd<(LPFJeF>0H?ML$xo_Hz@nXPAK(QTiHK4Nv&G<%&$#yfV>Q80$bObT82x}trgf_WoFH8Z;#Z7 z24k#vZ8Oug8-EM+4yCqY*GoRS=^|uWfd#000000000000000000$z000$z0000R31M<)b1p$- WWJ7OmW@%?cWoBV@Y;eM*}+m literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__argparse.sh.in.i b/src/hos_libvariant/src/.hg/store/data/test/test__argparse.sh.in.i new file mode 100644 index 0000000000000000000000000000000000000000..3d9cd0380540b016c2955eb2685002c59a9b6874 GIT binary patch literal 1195 zcmV;c1XTL~0RRC20000000RR601dwY0000000030|NsC0|NsBhUvs>@aUm5C&$Sw8 z!YFxwJdOYW00000000000001ZoVAv1bDBU9$6tp}u@Yx^6C)@#55{RsYCD;>+EM!= zlco$0r=g>Vg(G8|=DT-!5(Gpsqi=-0z2EMCZ@IhUN?kK)-Ff0Tvg};ne(iqlDYxH; z!(M-^+}!oM!+Yh!-SE23h{F`so-S0|A?U0>S-_9c2sZicnl>>2N8LH0jOWY=RLQap z?1@kyOOt`rhKZS+r7jkP#&ck9QgiOkqq$J4g&sAj97kQ|a~g#hhgmksCgBJ*Nr)N6 zsf3Jl0*=rqMkE*}orW0AvSvi3KBfY`hwuWtKd5+v{3S5kCGaZ1zjdV&KE{5XKg5B$ zL7wXlGfbKd|K2>>l*QcTug~@)$CS_zwY@W;PBys-egZop?CtWI{AKnd_Jq&2KbZr<&S{p0rNR*}tAAx?z&u1O7?yx*^wyn_dC#C?Ip2!P-`^ zwgtRVslHNblu)W~O-SEQsj(Go><9KUZZtQbci7!O5lU=R2k$QH@Oa@}5Si_~RVqA| z!W$FO{vXXjJ?j7f00096000000Vn_f4ub#y0000000RI300960|NnoA*Y~?|2hs`F zB+h72yST-C%KHES0000000000004NLg;C2+!!Qus10d?aKWwc?0g2K^^h8wp9Vm)W znrx^=^HAbek)S93f&)jm_B;3+?i|>(O@RRIVdV9Cc4lk??7ssX3<2O;Mc76P#wl9& zC<~qDbfXe2FR?$j@BvLKvD5LhjFJ#-E;khHV>hH(x6q+V9MoeV|b}&)`;Bb%e z%qEMUCcLVE*g^Ud|2A1smV|8{|LKl)>5jJR0*DU)!{F=&l^F$^!hywYW5#&nw%1y} zRpd{K%2Vf45_8KD-$I%7Y%@yl+}`1T^u%~!BdaBYbh`YIi!)Je;*4t-<(Gg&k4KJQ zSAa(yXOWuFz&wfXG{xDeXvDcP*OcZ#oij+2NZn#hbE-?ZE}BDZ53q-x_bam_@_54+ J;uFV2u91S)IP?Gj literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__argparse__merge.cc.i b/src/hos_libvariant/src/.hg/store/data/test/test__argparse__merge.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..3bc6c17a35d2d9efd5216ca84bd98a3f3f2564d5 GIT binary patch literal 806 zcmV+>1KIol0RRC20000000QO!01A%)0000000030|NsC0|NsAe(E=n|3)9cbNnTeC zFA82ZQR12a00000000000001ZoXu8IZ`v>rekQ--nm#m{An9I#R!h6Kq8g+Vxx0M+?)+U$7@pL5IbnDJKPNmz0GKnL1#xU` zEY~w3;aaE}3^hw}1zlB)UzkjD9poB+F%@8vpVAxkva*2C%i=UoP{I2F54pvH?md&7 zWjZX!V0OC08OiA_lL~ixhw%*O%=osPTqrG(&B>T6o=qWRb5si!BPgA8-WXFpURu0P zmG7kx?@qPMH%^&S1>m#eEb?*6Z*#KA6#LElAJcw^P6Dd{SKk>2`yvM zf(t2y^n9~mqYfWZj`rvVNFGKR<>9ZwQP_0!E`}jIJn(=vUUG(LNny zwTRSlxLLr!d0?i*CT>DJqauBx`SRhBL_jfQJHMZ>E9|X=i?COXvw5rJWm7QZi)ec!(C4CRqK<7q+MF$m(}+c`3z@fCt>Rpv z(cRK=SD^`Z~ kzgg|o_%*UBHY?eK*k+^ZrBn9NamQIZwf|B31Nux7`KlIyZvX%Q literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__base64.cc.i b/src/hos_libvariant/src/.hg/store/data/test/test__base64.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..dfbdbba76678db0362f9a0b6fceada2ca2410110 GIT binary patch literal 18626 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 ZXk>qP{Qt3n`1JDIcYk^Je*nTp5Y$#uZejoc literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__bundleemitter.cc.i b/src/hos_libvariant/src/.hg/store/data/test/test__bundleemitter.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..97f9cff8eac7fe3d764c44219b9941b557d04ee6 GIT binary patch literal 983 zcmV;|11S6e0RRC20000000Wl*00~I|0000000030|NsC0|NsBhqK&EF{Vu!837@s2 z5VnIG^_dU=00000000000001ZoUK)DZ`(!;{%rjULIb*!=lLa0H@_qWk~F|NY-`X2 z`;rF3NusR7q&xNQBtt9m-^Y_=M|E6a$oj>m9+D4VL{gLC5I!a%Lk~#crA?KFUsWpM zQj2(#bJ-|DEieHRC!Y76kWp5~2>u-!dtnS}J5K#4{OnJz1($Zx{g2Z(N0c|b&J>T2 zE3b25E$T0o6-HL+K4NSv)R#uaY9Tj=Se%LQ03$=>c^?vLhn0pnK=K?-!6O9nuG-Aj z&vZn-_Pk1o7+gQzOJo6j_6CtEEu5XTU2-lVHzIz`UQ-z zQm&zBXW+hxk`&8Ni+XEy#fz<6E@X6CbG?a@Qt)((dQsa?)v`FXQL$Xq^GK%|ic`Bt z3xmtW>)KXSY?*3hBdmp{QSQ>}qKsp1c~j73roz?gir%%w5161v8DY$r%V`*N<|8oT zA5;nJo&%RVz3kPhox?L{{RYA^Nl4-T#u}XqTg;Xx&bX9DY$V2zp`@s{NR7|P;IgDQ zj_j55xt~6a8jf+}8jPR{4(Q0+K^M2T*B|Z}>lwq3G<}-%doBmf0ysZEmVC#MV;Y!H91~}7#Hqs`{|0w;SKj=K8uDnI_U;5I^ zpZxYye-671I5g;nw=rnsLxZemkR3A!+i5oMq-DFhVKSktT$%=ACBL^&Xjec*8=+K& zT!N*Q0wEKnbM6-1d+c3@Yps>O;Wjm2ITGj$XfMd3e;k^*Q|)bQj}$0lNYNciKsVM+ zV!yDRdjqP-1@A}p1~|UNjgW6uROaaFr%+bcF6E=T z0S}dK#Yc#^jZ$Fko;R86Qd*JYUu}$6RQlsS2A#NL^gH+^%m-Az3G?zSpSZ4N{H>Vi zjWGXjto@*s*_HEkXX(c3pnsmOR8ceL=4Tj8N7LZt&29p@;LYMyt#2Y!nRc^LWs zBVieTW&RE|FW{%8q@x5m7m_)_eP~AQM`<{uhpJi6{Re&B%Kh~vNTV&agz1{-{sm+z F_tSkO=kWjl literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__bundlehdr.cc.i b/src/hos_libvariant/src/.hg/store/data/test/test__bundlehdr.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..c86b4a2996b8426c1782ab08917012d024a669f0 GIT binary patch literal 610 zcmV-o0-gN;0RRC20000000JTa00f8t0000000030|NsC0|Ns9qh$!j`VEJNDSwH=U zV>Ju~nBPtS00000000000001ZoP|@#Zrd;rJ)2)KQGh~r4X^1%wtGkyv^g{d0`w9Y z1uczjq7o@kl#tE;-r=G)b`2CZz?t`kZ|0HIcrbu;D+**l0dLG+X}D2)3D;WWyOK*s zY_z~FP)PqVW0yi^MUx{ee{e0hG~=+2_V3S-pGsj2>ht7xuIp2-HhCd7$5j7-sBj`7yKM}K1$}p*-Ol9_T1tcbWWf&XH(t?p?`b3(Qvd(} literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__bundleparser.cc.i b/src/hos_libvariant/src/.hg/store/data/test/test__bundleparser.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..8349db77581da507aa7b6d66c8e385026eeec62a GIT binary patch literal 994 zcmV<810DPT0RRC20000000W``014ax0000000030|NsC0|Ns9lwgW9<7ghu_5xVV) zmaEjOcqnfG00000000000001ZoXu8kZ`(Ey{%rkJ5+b;N}qrIdmFj%hQ|nknOk_Sf~{A4G8?%vm|Q;rM{_j%*`I z=)O}M#l>oWZNq#cRdt0+jAJAoTUM$u9t4S*PKeJS;>%4@VDODk8#=HoUkYu&4~c?h zDrm$OnC!y?j4Zpb-3?QkOVJ0<_2$C1Y)<>o&Sy#4bi~BUgnj510do((+UK3_#p~YX z&o3~Zs(21Z;LA8>!sw@pAMFL@t;{{ooA2I*-LBc^HM>)@yEXfwX1}i4y?wh~tKZ(M z|J1fS2lv`50+>=#aGB~g+ZNjuyVt>=VHuG%)j_n@XlT0r7!pl`%;(`dAob zm4*QgvnFKvc+u@$KK9VKl#iY6D&^7EwvaqXp?<$)AH0$YQv|s=96B|JZb8X&*fil^ zR^y&wK*T?>%ygu76xxJCFPDg?W@1Vn4X|=yaO9=P=FW9&5dG zFp^XBPxO1C`ART~QKM1bcqQg=HjL|fmB5(Aew;WJ?mj)UTL(Iw=xHREPV;p93o~~{ zIUZ68%VgEO9L^ty@%cEMzX*r?_!L4vL~4(bZ2>L^co*eV=h(S7z+nh&98XR-ay<)j zlT?R`CGpn|Zw}yd9a1D)khAQ6gx7bm=#^OH=TIuX!unM`gQ}iERnMTRXHeBMsOlM1 z^=t=wSub&%LQ0y?gsN9%aMA4uk{meHpzOZ^Dn%(5sn8@~@QEpjcUrOqDw&3VGB?T% z*PzoRkvfwtiN0^3pXTE5eChZ;+6T4*KaHT889#XK)QUAv+7DUcA8D)w0f{twaet#1 Q^jF>&UUpsl2Qkh4$ZXZ(djJ3c literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__empty.cc.i b/src/hos_libvariant/src/.hg/store/data/test/test__empty.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..ec2a01f3453cedcc08f24947211c1b8550a5b7cd GIT binary patch literal 472 zcmV;}0VnkD)00000000000001ZoV}7!Yuhjo$DgfFakxENKHFP>IS*GyY`4qXs9ZfEV$x8PnBDxBC%ik1xx3y-<-2bd OjJ{-S&7J__{7(9fY~L0D literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__extensions.cc.i b/src/hos_libvariant/src/.hg/store/data/test/test__extensions.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..0555675d39c1fff401528b2cff2c96f0934d0d3d GIT binary patch literal 3480 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 LMMl!Uz29U4WoIm% literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__loadall.cc.i b/src/hos_libvariant/src/.hg/store/data/test/test__loadall.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..9e7d1c20dbd49d0385a5f097335c688c2100bf1b GIT binary patch literal 387 zcmZQzWME_f14d^C1}07jn}Oj!6a+lGk!&kH$6Y*HZ@bvR{Ze=L3Os|U0nrt6asz$+ z4;%2I-i0F(~C_i&!<&~veOb=gmMxWd&FP|G1``zJr zt4VGLtNK?yll2$(eiU*%xyUl*jD&V?ncS(a=npUcbbp?9V>R!Y#0jZ4qxf$;5Vcne z&e*|a@sdeT#LLRQRn+HFv4?)pjyokD^PbQB>sji-%fb=dCbjkd^vR6zuX(z@Y1SJ% z6wX>d-QU>z?ZRh4$JZWyyUvH7X;O>bS%G~L-P78-TZ78wbiZ#2_TdcANUch|n~66KEFTI!$8ZfxsZ^!U}ng||Grh0LqoZ0~p}p!P##*0w4W YDcQ(svB)n6vn*zBwEfNY+j#y>07HUqkYP8*ivz7PGx^r^V9DnpMYuUoofar=jYbW^o zA94^ldj8Gw8B>l-S@v+goX7+gAwD4&;hu{OhThh>=G%fd-CY~_xV&6kO7zjh%jeEi ze||PSw^DA6(nKZZ;DWW2Vh)-3a~un5DLj^`p0nfthtJKVHF_Ezr5y$pPl5`9*1pPB zJ8Yk{&}riBiFzzY9c&IKon~$c$vO4cX}+N&myzCyt*p}vA2?4a;GCB}YZK%AHDODg zZ>Dc8dRb6$v^<^n`U8>5wt!C|i-R+#tY&%IzxcB4{tIqKI(y?f8&5qwaEw23@nVjp z)i-y(GV4jyKKu7X>9X$KKf7eCFNJi>FlZ4u>7sifV96uqwMT7lzt_K=y}v6<%&l13 zZc3SD)nuoKjc1SixbX4dh9^;y!Lcq2e_lCRV=~V-Zl3%0&GCJrH}@%7GHp1O$uPl5 mP`1!UHtEj!JTdS8|lY77drr$)w3=D literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__numerics.cc.i b/src/hos_libvariant/src/.hg/store/data/test/test__numerics.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..669871fb4bb6946ff59fa06dacad63462e1721a4 GIT binary patch literal 2013 zcmV<32O{_Y0RRC20000000*4_03UV$0000000030|NsC0|NsAom>?|0YS4WZxK#y@ zE-a*1@1ghr00000000000001ZoXuH#Z`(Ey|J(i)Oon7~Y}rYQVp#kD(zP92xDPa5 zG3)_>wy0RBEE*E!BrW{icSlkZ^>AXh305G0seAl*cf2EyOz-4`{NwonYZ4gHL@anj z-ta|8UPQioy`-UJ%p#w81ctrlPkuNL5|@#~DT~Er9J5Gt7l%20@QFq~4Mk7?b{8Xq z>GN1bj4n-DTqVtKZ|Tf0ss{ej7jZ#RxPd<_N-e2aASH?Y@S22l$>J5AGXjEZWl+Du z1Dt-dsVyVNe8nOvcr+MTIW6vxIS*q&#NCQHe&}&>EL!Aiv!TfI1&zoFVv->dT^v}g zezW0+0`RFwVxZe+Kv9w|TLR$}zSRiay|{3k`7L#TK*Q^RSqRc0r}FPufk;S?SSchx zNFy3NCW8S1RS;-+5n~pNQF=pI5HmvtQIXzkL`)=6NO;_DZg%!xFDp4-%ZaZTdt>X3DZT)p}@zMPEzdgZ*idjAeBDNZNYaura)1{hEox9O<4=Dtg49Q)Vd zZwog6Y)v7s@Y`y_R8vABQ1TnlQaffCJorYQUSVfWV=--&c9>;&OLI7G^r|?3JZkO1Ao?ZKIn<(;$SZW1Ih1SaZ`DG9(IJt>LE5efQalWUKN z7jP;Jy@4c*EJX(hH85d35Ve34v`SbmPi6r#!4zd=X$~mq(N1^)hbpXs8sw2>${>dE zxqXg%atk-D_cFhI$Yx6?(Z$6St6CMe%#bv@)--^;(qFQmFRvi8rxq}}??1ZojI z*f?QPd|A}+GazTDr*hOD!ce7M5zR+E6Yny{q-|kUS9rfOfi^0xG*f0yZs`{maR8rM zr!Av8c*rF2%p{5%C3$Z6gMw`(K16{MYp6gBssvFeC90jmz|S|rplk+%o*6vlsPgn1 z;ZukbGD7r7rgGNm)tI$UBuW9$c(oT9D3I!b%rsd_zGA5dT{ z4u6JigMNm?k%e%4z$Ti6xGgeQ?WhN!3kC3pCPER&4A;Q6Mz&Mv&9*sJNdU28t8D|X z>VhWL=xJo&*!BZ@K&$Ar+r{~ExGj1)aJ#)t4=S{YEx?lcp@jn)UC%qZTR4Fab&48C z-eAUgFtS9H$l|GTJPPNzUalp*C4kDVSw!Lm4FWP_WEC;!%GS72rZ&idxC5Jim@MJc zo;#|e${80I@N1>1u=K;n#fAs~b|W)9O{kq`Nw!Xt)cDX;GpPd(5a)gjdw%UCO2+g4 z{ukExD{-9Hld1FS!_|25{+;7=G~w;o{J8wnamc2hDW_)un)2)%&Jur!+y5Yj-iUja z=e2t25EbB{@*!W?`x!hE^ocDG1gt#oU?_!@Zhb40^)jzZ-V3O2 z*_srfRqp~Vl4NBjJlwiqUE?7Han`5u{ejj(uA4>r<%>x%(n!c6EkCkIr`ivM+I6!~ zD~)Zj1~ZhSu8#FfDV~SgJs3)vokIPx9Dri1(~hPT?97I}f^GIe_eZ?YF&S~6R02OK zM1E2XeGz8&1u*ostwNB6AV}9?0$Sy@2w*XS-B)8$8=>No6gtiCUzfCrXQ3PPjh_B3 z#Tx_69Cr^5z8Qn(X3K^_fRp^Wfx!*E^z;D_#@LhMVRI&%KBZ}s^F1`5rHa4E-yTr* z&@Ob4&<;q3JT9>h?w*yQ4tpy4D%KEcJvmHF)(_1)j^%EqCg9{~NPgX-f{^Fh3f^v4 ztRT4+#YxuNoh!%8ws|^(ZSRX+l<4H7w{%saOh8eRnhioo z4t*tSq$Kp$u^XxT2@YBBj)(;uBKpXUi7E)FrjUoWrphZxF~9HIA+)R6 zHc<+NxmAehPSrbxIt`I7&9z+HMuX0Hq;6-84VhChUl2>ZRusyX9OLBSIJ(a~LYD0K@;G?Ip*j_({wX(v$0d@0GE#2_wGnNt_+}lg3@=Q^;Po!6| zQe}@-b6uj!oir`@drNiaLdCe5QPahlS5uz;dA{ZemS=>D_U4Jq(xM-kMv6=3r z@-|hw( zhSaEcTWTV@Q*vE0wm9$A@gCiM)4{~KF9jd;GTG*3@_&0NR~erV+xe>*DCSSHyGLPb v5)@D#5f2(fS`H0>wi?8;*;=yi11p7JVM9w literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__path.cc.i b/src/hos_libvariant/src/.hg/store/data/test/test__path.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..96204ae926918e72ebb0ffe419d2ca7035663483 GIT binary patch literal 1468 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 BI4}SJ literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema.cc.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..3eb5a219e6a40c4bbc2854881771b1c8b5ddc920 GIT binary patch literal 2945 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 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/invalid-schema.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/invalid-schema.test.i new file mode 100644 index 0000000000000000000000000000000000000000..6b7af253cc0255d0681f5efe7e6d1ad63d165492 GIT binary patch literal 481 zcmV<70UrJU0RRC20000000E%@014Ls0000000030|NsC0|NsAMoMyY4yzX&){_p0Z z-5xII!?=zB00000000000001ZoVAq8Zi6roMc42Zme*`Ty6PW9s?_dL76vAXTNsEj zQBakCuOE=m#I(+91!nGW?hG>|VelOW0Yz2}r$5QNkJoB?qNAn53LZoidB(FXp^ryijK;S_qBAO)ZKks);;@S|LnOZR9!B z9BRNEFyqjWnG-*jSim_`88hgJ&{SPxa(JqP0T<6N%fHJ?&7=f@q!v{TLUu%`Chwh= zdg+H%_P%r^pozZK#)3V_w3a^h%CmLA-a;~0uI*F$-~2LCRl&P^`L^`#2fwp>6?zMvbrT=2#{%!7EU z$2a|s)VQ1$)@!Dm=#_~sZsb^UPLcP0DDn8c^TL{? zs(U=j9`cHRy>!ld`Sv=Qdp9}OC7m)X6gys@%vk=lzPI8=&imQi+3WtDbMto6-n7Z1 zd8Kpr@%e4R&a3r)Hh(>IXYJy<3CiLefmxPG%jzS1_UEQ8xKn+q{B~uH)tz^4`(J7A I`!;DK0JwK~D*ylh literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/_makefile.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/_makefile.i new file mode 100644 index 0000000000000000000000000000000000000000..96b901f2028c0d5039d6bfa368ba62de874f6f4d GIT binary patch literal 171 zcmZQzWME`~fNUUD4rMd^hk{D~noiTkwSVSoZMyWlJ@!pl%=-y2H6XfT&SS1Zo}zMI z&ae%eLIW;pc<5;A`D*C}23$R@b?*G-z^mGxx_TD_FKV1Wta>>9feB&!0~Pb$fl`(h|)P3CR(8BN8IBgTdKV=_CLa CIY3+h literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/_r_e_a_d_m_e.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/_r_e_a_d_m_e.i new file mode 100644 index 0000000000000000000000000000000000000000..9689dee86beabda5890fec6230901d651659484a GIT binary patch literal 778 zcmV+l1NHm>0RRC20000000PPY00h1O0000000030|NsC0|NsARcI~nsro{Pmp7>tI zA&W@hRDIq600000000000001ZoLy2&Z{jczzWY~AitPms z-ksnrxGq$UIceBm;MdSv-LWRdKKz``jy5*Kep@sz><#_1ljd70iu4AtT%3--cja2dJC$qMW1GT{LxqQjGz3 zfU42{XcCAHba#Q?cw_~)kJ@&&JAx*Y7lxgq{ooGqtkJseYS1CL%IZiFxN10=F6u~p z2iuwe52zR>#cg8pIFi&xw`>g4!21=PF%>sN@EEnX6=5Wpc-0OyX?VYG?aAI4XneFE z7=jJ~9gxlhPOi2G`kT>KKkQo@ngn-5(EA}`F;KBG9ZjK+nez}#+p=+;0YuO7m!cWHNwduY4 zJ3g%2b~_hQ>Qw?QpucbRb`=`kwy-z1z>wE=j7slzJkf`Ui?_Ok-uaR5f16X}UkfPm zRr$h|09n9R<l`fcUdjq9`C&Om4QR z6j+nlBHb-z_5^dB%kmOZxsfG;mN^jN4N8iFz&1iH)_CM|nac7tVJlf?gt^KUaM*HH z%Ed0_3bs47%?p9_ON7m2wo=FfS z)1|=TT%a;OPsNoAO)XL`Hwi5HhChjMDn}H>sO_o_UeMHV6fu4F-htW>^97{!Sb`3Qn@nYf}*)bME|*h1%BAwB?MDR_!lxSs6O`f!`< IA4(&MuL!AnNB{r; literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/additional_items.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/additional_items.json.i new file mode 100644 index 0000000000000000000000000000000000000000..0229b7f170f50186d520d4572262baddddbf3b11 GIT binary patch literal 484 zcmZQzWME_f1I8r`3>>c@YzBt^P#`jC=|9P$m+>C!nA;jPO=C74R&#@?0nrt6_D=Qg zYc}9%`)=DhwKVNwWlmMIrSnlG-DNIZoL)ZKEjxaJT)=JQc>9adtjT*9s4X*n;iSp; zUdGO%#;GLrWt@iO@2x4^GH0&UtUGn1!R(9qMjgYpyP|VAp1O7YUY}7Yb}-i|YUZaC ztlx_gYjz1otbEnJgvZssmDg0VE7hN+eSK$ukMG6}VN((&`8{?FvNArsPswu2{^L`B z{;AHq5lZ~yZ4?(<6+Wx@gA|7$>()=}iwj@Rc`pC{ zXi3DSQez*Ng(ny#59lo4q-|R8ueyKRl8{%imwj)U>|MpQTuHI~R)w7{>o47q#k-Z) zX8m4gew(Add+#>W9>EVQe&wa{NgQ5g^XxYp)AGE6%I|LHR}?P}<(#6Va%q>?@qal- Yo2{bCzKiGYoO3-<{Nf|_iyO2`04s~*sQ>@~ literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/additional_items.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/additional_items.test.i new file mode 100644 index 0000000000000000000000000000000000000000..a8a9843ae66f675eb2ad33e1597a73e00da1c48d GIT binary patch literal 420 zcmZQzWME_f1I82v2G(W>n}Oj!6a=w^i=3V%uE&zzD!M1pz5cDL88b``h_0Bkb&7Xh zvw=X{dZSObBA4|0=3Ov$iS#)npd%@L(^;vd=DXDA3}=ri%ic0^8XrDmzQ4Zuc9+al zG3gV5)sqyAQhH9WUAcAI2c?Ihhi>b!@k|q8X4>qtaTD8D_TZO{wm+O5RS#vc#ybXR zMk&d6DLNj}I((ZgYNF7tu-q4~&c9kFlDFzgu;emjOF^dz28x?k=L>e%C&N7|)e5MIg1EMSDJe_>L z=#YZIvGvsR#SIPG8 z=JE2136phuSIoV@mHxLRCTUK$!TBfc7fmJAPdGU`txY(&MD@Wfe~q^do-4O6h;?Oq zWhegmvFWxo8D|To#mGLNoU^~pd+p&H&l*^b4Rb!94zV*7`a1KZT1iUmi5dLoB#Zv! zu`ak&ut!^yyQP(Pa#ONh5nHj&%9KlePfBK|Kk#vGzB>8I=?g?CH~0Hq;CO})$$!WT12w$qs(>YV3eS7b_ZjZgFdF!7<7)!ZN{%gsn z?y>b{8Jfj6Q{`5^|2}!`&x<-A%w_i)S%0v%{cJcvO>oZ~vt=Rahqv_`87_Z6rElWoZ%WSgsTC+x?vMS(@LE_B=$+p)OMz4CwD(bcyNuIIm> zxw7JW*dK$7?J4K&dN%+5UiokRrVS=rT2z+sdYsyLZQt|wIjx?5guiP|xhyU%ZDt1m DI)0}4 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/all_of.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/all_of.json.i new file mode 100644 index 0000000000000000000000000000000000000000..2fdf64751b42bf5646c54c2cf463fd01b37766f2 GIT binary patch literal 472 zcmZQzWME_f1I8H)4BQtXYzBt^P_Rda-&@FJXW{AW)p9e>TAZ)?pq2nr1EMSD9G!Ns zsL4Q}?Y*6=S~_2!pZ-1<`2!yX5+|N%VVNATR`&j0l?1~{PC6cz2F_)h>vrG#^SZ2Y z)$`N)&Nd4NY+Ta1tm!fDp_Yx`McmiM9+iBu#As{vo2s`v9HY~3^1jQ_Sfb&O#kETK z%*WfpnKB#x=^PLUT=$ScD1LABx{3d|vlnM@aNyDqt-IW!0ZTa>{DM9(Z@T;a4dbKa$a(X1Z=4Um+jRCF zW1*w^D&sBcTmg%98M7YWJ8<9hks@P1kB!BZw|#L7k~eoAd}5R)^?2T#={>!Z@1H)S z6!tymfb53Y`>P^KyzecsnY`p@z7s8p0}N^0b8-!E&u=k literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/all_of.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/all_of.test.i new file mode 100644 index 0000000000000000000000000000000000000000..4e785bead4e7e66b548415a066be299a2ab0fdf6 GIT binary patch literal 418 zcmZQzWME_f1I8o<2CgpQOBs}l$yxf{K30)km zj2?oaH<%3^r6e!^Xf^PcSSbDFjkDD0^=Bt4x4o5id0Ea?X8nNg+oZ1IGqcu9$20Va zPWcfc)G3^8Ip;!*?h=g+S6H;m_cpFy@K005?4eY8#Gzegg6slj8#z1F?pwE9n)Km} zQVXw#cgX3YzUL~|ZX(WB=Nb=fd~h&C-t$$5gKZsx4 H-w*`=kRQF< literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/any_of.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/any_of.json.i new file mode 100644 index 0000000000000000000000000000000000000000..5cf5d3002411e551b9fe109117f14353b6984e1b GIT binary patch literal 359 zcmZQzWME_f14eZQ1~v}}n}Oj!6zmnXTlPq*`(fSvu4f$o_iw4XZNmps1EMSD?45iz zui1d-_T115! zsH<<^SGI7aiPRPG*wowpn=7Uz*Z-OtYb0>FrS{j29hR0>Nf$%(*1c+(IY;TVPvPBl z$0ft1g}KYbKkQk2X}TvzQ1&K=DSr>2US`nw)JWiIX0QPB3Dq4JsWWak^7=A8ZW=9c4THl}u;XV=tDoxOX*r6I$qnQ|DnJ)-u=TBzV`p-$+i4)JDc5~ zZ#=!FFktbbrQ5~0*ft3S^qs$#yZv18saMawh+3~ZxU1-Dkc9iMofj9?@>kW&OpBZ% ztkR^K|ubYC6bKVR)0B zPrs&Jop7vYX=VAu*biBUq_y5yX>Q;1ihq0hjA!k4zewu;a&jwXQk^}kTj$nVr2 zL{YD`9zv6(wN?2oIaV$?zNj&4Gn3w#jai#a6{4ydBUGo%TN_qbelK%!aNdjq74=JG zw<(@I!FF&_>7y^KzRI;yx^F(aaC^1cJ%4lQx1H`At&_s7*ZxKC3BRB=flHCyd6w%* znOw0&KlSHG&eHZ-*ZfDM=g8|&&#%W*&mR7}XWe1*ETJ`9@~gP~4l+M_eykS&t^aXa literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/definitions.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/definitions.test.i new file mode 100644 index 0000000000000000000000000000000000000000..0dad6d7eac9e65a2a1c8481390abaabb1db8439e GIT binary patch literal 220 zcmZQzWME`~fH@2djO9=^!+$8aE1GNd%>Hp4!;V#1EvNz6>+8>zekD-!X63Sb zr7Gs8CQ7xbXH;3&KmTlY*>{YvT8 z^;cW_6_WglJSC2{zcOR5Vv!OSsJOnR^9N7l3aeR5%PLpLhZc$yeSP;>IN3tu^|MV| zr?V)oPTRjZwEVH58JEkv#_bzsoeRj?QMBZn+_EPtx+aNVSov+1EQ5sUdFdca_l5HR z8s=?Z`ZFMFLDc_l?hAZ3f4DWEk=AyD>dylz7S2)Ok1%f zrQ2oId#3eA&2zV|@lZV(>`-3)Zmou0_T`(B|I^=}J^S|h`Ks$}cLl8utn@Fd(dU19 zlI_Z)+}!i|c42cjr=I-CK1DFvsFd6Mce?@8cCSSWfi7mAc_*eRuAf*FapCBk%`!XY zM8$lcdAaoHr%BD{(zFxr1};wsn}Oj!6tqac+y2|T`i82hVuA9*M}#QQXR1wK?ZtI#+$a$)rj1 zP6_R=2tRwyazcM#sAfzj=Vz8oot>e-4Li84)O|m0YdXAQPrIR`&C{r2!TiPcH`uLH zU1lG5(vnFMw|QCbnDC{|_r)&1&qqG!Fm5s^yI)zCTk?9{x>E;g7x*d3zdI(hrt0kT zJ{^@e$G18~`djkk?M=Dw5_kwr^!(-L83J s+g~kGS#~OG|J<$L-sok;WS^b;?7OkWi@QKuFNj35cwDBh+M?p^XC_vkyO#HVLAI_%g!YldUleUIn!n2#nN@tXU^O(C)W#?1m13&&?0AF409 zuI{qd^ZJ^Jd4Zui0`jx3C?-8nW~!Ld8@D$zNO$w4kg%#cxw%*7c=GR@|L@dcme2Qn ucorAmuDRoN^u7Fw#S-RFPMc-89g&p%$4|6jABOTRG5Fg7m>LjWF=y=rU%n;- zf!6g#FQvp56+R5*=;mU+vPIUZTl&&&YgW@Ets7tE{o8N8evYg5R5A68rDZc3GnP!B z^Uh++C584wn#LI{TP8QIzS89`5_zInq1!?C$G>}_d9ng~-oBFawK46!@p!?L#jb3> zwOV-QCD{8(zk8^>PPuts_%`O0tAeX@jD9?Qyy@10>Ms^S?P8fl^*{cccsi|Px8UY| zHu|F5c5%Fy**N){=Bc2)KOJu+=M);L+$`Uh@K*MO;6g{41!~3xpZ1=3#dfXn@j3we C;dsFS literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/items.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/items.json.i new file mode 100644 index 0000000000000000000000000000000000000000..91d688048ddac6f73a491dc4f94de95dcb35adb0 GIT binary patch literal 333 zcmZQzWME_f14dp329^Q{n}Oj!6x`UzwC!xPn9lZd&ute?oxLe!_8W1S8W3GEXYZtg zd50Bv+TK@kolY-%QTBSZi{*wZo)e>1^jzP%>eD-BrKu^MD{gr{ZeaOYXm>a~T;Q1Q z*}?~XHK(7c9E-fel=b25ygsR_Vm0o$$p%jD{aW&p!isZGFZpXIu`O_&de_w+(N~>? zJJ{PjWfk=eD8Bm|0kaOa?P-E!?}H#X|=kFcQ+LCDa!o5@^Iz6U2A@?TB){x zb+3-fyo%7pZvRY=zhZsbReCzC=mfX)ZT~Z8VtuSU|JPi-e9bUe`($tXvcCQg@vEj4 X3UxR63Z}bWzHb)d`<2;C;_nUs{@A@7K|LW4`X*1le9Wya`yy|KA zo;_3R=eTTJvqPu5QQP6l_qq0Uj{<-5e@#-9Zjk@iy79E)%X`n?g?r6q&zvK=UdCZh z$P%yV><6a=7@b!WYkV|OJYM(Ev}K=H-8nkxoWH_ZbCqX&`YxqOg_-r%k&eaz|2yB6 O?PTAuHU4(`(`5kK_I+^x literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_items.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_items.json.i new file mode 100644 index 0000000000000000000000000000000000000000..efab9c320a39daadb725f2b3a37a812b32364125 GIT binary patch literal 259 zcmZQzWME`~fWr(7OoyOshW}7-rK_^v`RDyhL8sczI{azrNxS_b5T*u1SIpTu!I!Jq zfv5HRJf$7mx^K-je<69qbyXmHNl@CQB*FJ_^ z^WR0jEor(mwf%WUs$~qT!ZXM2+{d+@PNK({SYP^lO16>v@!wS_O(P;*w(nAVgUyaN uhD#%E$S(|8c5?#j*uv7Ch@7buN-?QCBEt~u1nEy7I_W=NulXyx1 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_items.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_items.test.i new file mode 100644 index 0000000000000000000000000000000000000000..715246b40c161746ee2928221970fb5e6f30bf6e GIT binary patch literal 223 zcmZQzWME`~fcXpzjK`sDhW}8YP@;c=^Q2t2TV&3rd6QxT+|pKMz|?@~iaATqJ8~Uz z;9F^^2TJ@1Hf;pplyJkSp}#H2X=T5J{ zmuKhpI!|oOc=~!-Kryp_rmw2I?cBE^W~-(iym|JTLG16=c2PrC!}&`}pKZ^{nv?$Y zU;t12lXL2m+DiiKqmHfSxnX}L>-KW?z$@O@455+nah+qizn`36wsUV5CAN8ZLt6V literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_length.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_length.test.i new file mode 100644 index 0000000000000000000000000000000000000000..a96a89f674829b50f0f214e5fadc310d53f07174 GIT binary patch literal 214 zcmZQzWME`~fN2a2j7OkshW}7dHf#0%O@TAN?&1s%h^bp1HE+_<`7kvgx?;}K^Nw7H z9C%nStZs?izCh2m*<3(;;j+sIOd36>IK8}U?JWMtY2}VTD)#*`&o3x1FKCmS9LW5z zuTQnjZi<3M5U;YI_@o!iHim_fiJ}?N8yq(Wvu(=_u)fA?a!vU2>aa_hky1a_yp-!x ydn0qn?AOgNe=5|=XRhP&R1NEYx?aD(T~^Nhq7U1mOS96aW!&F;n``s0iA4bJ>{)C8 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_properties.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_properties.json.i new file mode 100644 index 0000000000000000000000000000000000000000..47cdd5fdfc0e4f5bfe579bb3299edc5a6ec4b0ec GIT binary patch literal 272 zcmZQzWME`~fC~%^Oy8kwhW}6yxKg@WSV+;q|Hbr`CcN9VOnc6V!PJ20iaA>+o#ksX z;5q)@=I9|w{#U)rKloYrXc!oWZ3=Z(*|S?(VxN+f$+rz(AK(8nec8n0YfSIHKI4B- zB`QQE;HTne@3{FUVGBGP63z8oPwkE}*fwKH!=&g^QDSSq#_@nbK0iRoDuuKi!$f=$1Z|3WxN&gr; zI(!zLlARL}|Dg2V-Kyi|3nZsMa}S!RedXI0kyWzu^e5a9j#MvQ&{uHzQ=7)OUl!lw JxK6Kc1px06c}D;M literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_properties.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/max_properties.test.i new file mode 100644 index 0000000000000000000000000000000000000000..e607dce05272125289b5e6208c67708b3d3e33a8 GIT binary patch literal 234 zcmZQzWME`~fK?0(Oj1xb!+$84&J@Spa@bdZQ*e25u;^WpAKlZvVQN5h#hj%R4EYWj z@VKr|N?pdhp^&TW$OEzMre3*IBtjai%3~5DLzhD+}bbn>{W?>^^t&QthIkN0(pUyO^aJ+`8gYkCRS){do-|DIK5ZZYGwZ TQ=Lw0hfaHb`Fy_bjdeEw*D7Qx literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/maximum.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/maximum.json.i new file mode 100644 index 0000000000000000000000000000000000000000..72fd40902105b6893c5f033fd19ef8b0ce0eb22c GIT binary patch literal 304 zcmZQzWME`~fDa4|Eb34;!+$97>^if$^J9FHU@EWL6$zcW7ng5$fvEw}6?3*u^5ttX z5NQ2AXHjDBk%W?mvNnx{feBYUeld1>wIhO32n*VPWm zXc$*)SP{A-W#JQ5FZIZStk3qGb>lZot)8&w+T8p@RrcM>L*0`bb*{erYWvh*X4agh z3+`#(59IN9g!k|rTs-r3n{ubPe%JMNs+*5BhOb?uzp!Ez_Y3ERzgkSYpXYDb7IUFL zW=HTX2E(OST`XrdEi|`C{JF~FkJtChYA-JE&SpF1V{wQnO!@BP-p^~FG~31Aeg1d$ p=M#$rl>bcsbG3eDnbz}XNBE?s%4Y9-S^n&Gefb7XJ=>MvQvr6ajHUnp literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/maximum.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/maximum.test.i new file mode 100644 index 0000000000000000000000000000000000000000..cead4186b6bed09f47616ac0f88dbe877c7c2445 GIT binary patch literal 267 zcmZQzWME`~fYS^NOdFtVhW}77>!qbc@)_Oh?Y>QJ%%Ku|dsa<53sVE4E9T6dc#-Rn z0gr3F>X)0nmKWLoAJi9+H|o{9ux!(|Vx@n(MQ7$Y7v5SvZT6Ep_txlV^{=@q^lgQ# zufy95$u-YjD!rbYd4+}7)mJj-1`D%kR^Qhg)=4Z}m%g#=Q^_bT>lYHOzPnAOcz#Xh z?Z>s#(yqT|nWt7GY9*KU@{hI%cl2d}Q=g>EK9pZwu|CGGW9^B?2v3z6Opy|oc#98=)1J3aCM}#-pQt_ z(DPBtxkc{JJtio#S+w55$KlOXu{`NoPUrG7tR{t;SJOTIKNU+3=7#s+)g1v+%mg+wsPEkp^!fKd@vf%yt0)iKA>L literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_items.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_items.test.i new file mode 100644 index 0000000000000000000000000000000000000000..cbe79e90945da46c587211917d9a28ac2e75be68 GIT binary patch literal 216 zcmZQzWME`~fEf%7jJu$0hW}9T@JUFXtRPU1O`5&j;+{FwJE)<~-vP==J`dX2*^|ZN2&v=at{~Fnb-_gw?oqj)+twqJSGFvh@?xHS(p|3f?Y(UPx$9Pq literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_length.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_length.json.i new file mode 100644 index 0000000000000000000000000000000000000000..00aac669d4b2aa21a17eab6376e8fc26ad9415f6 GIT binary patch literal 250 zcmZQzWME`~fL#m>Ogo@#hW}8I__vI6iQ)9e3N0l{>kHJ&IL=LufvEw}6?3*u@a1ZD z;A#CnFKNcs*e%}YFGzQEJ3h8p;5l>2(tthH?(BaWuZ4MS=6Le7_4`Ddz=d+j@?PNw zmX?bbwpa!4Dz0GLa%siv%-B>n+qrLJ%r4A)P;=&*!Q5Z1?hUQYGyE@EeU2^j&N!%j z+^|~EI$lEZP^s^iEZO%)s{goF=gxnZ(zsjGb?Zmb`+|SPJvv0ppQJ7*{4q0~d%2nJ k{}YdOCb5TkR3v=l)6IV%Q~oz?R+q{-*H0{yr_Wgn0Mbcp?EnA( literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_length.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_length.test.i new file mode 100644 index 0000000000000000000000000000000000000000..2b842dcb0b4afa365a5880e79f4e706b9f2b726d GIT binary patch literal 213 zcmZQzWME`~fT;`&jEA9YhW}6yyU|>yqt2xe}ywGRsoF8D-5welBk7ZgEmty&P-?j^?OG^HH{dFOiPq~OsT*6SgR6y=U zM6yJvb8nOIR*Q`>o{Q8g5}#Qe(Yo+`La35xLiFq0qirt1yAAWBP3KNu+ARC7!!2J% x=F_cTH@|%PqtxHAj%(VMipLTEsy>w*c&rh1!Xc#U^C6+!`Mc{Gbb=-t0RRI~Sr`BS literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_properties.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/min_properties.json.i new file mode 100644 index 0000000000000000000000000000000000000000..c8f232eed24f89ffa92cf9df0c699395cca9eb3b GIT binary patch literal 266 zcmZQzWME`~fKv<%Ojn_7hW}9T>kEg!*@RQg2WD3-_P=sJP=1!eYM2@jT`_0tr1N}D z20X{!+Z^3wEcfL^aD}?eF%1Lbu+5>#P8H?m27e3{43Ei8+xmCc`{_$FkJN1WE7>Ie zU`c3rP)5a}ip6JcJ`&Z@EO?{0Ma$)W_i{n??2MN1?cO`r%j}-ncOXz>S#svfy+;>Z z3`v+-_4E9i<(!Vp4xJJ?$;XNl|GvGlc13%-klQ!5?su~*X+!dV~t_AlHv}2xG=-yZ+T|Pg_XU2F?mIn(;v@>dNSwRg(ST#jU{f! zBMyi6?&MwV#=Uj66BnO|6|WBaW$l^9qC1kGo!H0~BAPO_kLSnRel5}Uw-LOcRbnf?ksU3IixYw}m)|wJ`HeKuV{rStc2%VX`qE%aK>NWAKJvzny J{z5KGdjTw+VPgOQ literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/minimum.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/minimum.json.i new file mode 100644 index 0000000000000000000000000000000000000000..7117c87c83d21b63abff6d7f27b5cb70cbf6e84f GIT binary patch literal 306 zcmZQzWME`~fKLnzEb34;!+$8)dMUC~?|!yh&X##$Dt|r;InI0X9Hs_DSIpTu={(;d z1)gK?tGPC9);rhCe*d7lf!vL-t(+pxiCI1G-`!c%xAUjE8z0N9^(PF`Dl`C=GL0UQ~va+^E=Hxq`_A1}Sxw?4PlIPQoFDsG!I^#BtzY=EKM7^)ivB;* zDs3bdF=3%$<=n=n;uaql>RZ|@{hcei^+lU6b9+qXF(EPeUFsR)QJO5ZRl83AHh;d+ rdFj1h`o7Elf1Up^#G_ioy7`Hn@%_sJ%**6Hm+rTYauxsj^}90wES83n literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/minimum.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/minimum.test.i new file mode 100644 index 0000000000000000000000000000000000000000..bcc070e40863173463bea8c3831f3f1141db9c94 GIT binary patch literal 273 zcmZQzWME`~fQt+a%-m2m!+$7f+*SIU@eN~$u7JbUs?#qS4B5iJz|?@~iaBd1-sL)E zz|$J9`lU+xwnO0kgX#kMyCh97EZelL*r=vl``?1#XZh=*{3d;#Xq-<@Js?-vwi4#yriRa4E%L-};N*%b2F#ESuR;zvxwrm&qelwzW4xG8%c0zbS2; z`gd~mv?u28ZcI59y{hn6ozu06LGsTa|2SIg$`Z2YZv%vLu-;Dnhs+ZC0gj$85+t$~9V?H&b!`7uq5r2`g)I)xS$}3`n!xpi z|H8U;MRoVwWO+QHxAAOwg29G+OB=+pLr<)bjR?GzU>4?Ea_67i`mUx$4j&7u>~?Lf zOcCGv;M}Jm9p_Y?itcSwujwq7s9BkJCHZ|W+l5OvSWajhT)1?pzhl^oJxUJk_7P&m zPc<12Zz<0G^tj#fecDaYcq4A!W5$I7KR-w}-q3!3KwwT)^JRrX@oQ}1oyT98DK^*q zn6LRSk4Zi5g~*Ed&kMNq4Za3@=)SB~)(!E5VI`df&BO`Qm?c*}iKp YS4eSRG+VF!@kn~{>9m{jnfn5A0BNS0Q2+n{ literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/multiple_of.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/multiple_of.test.i new file mode 100644 index 0000000000000000000000000000000000000000..3998829c5bbdf0f8a996c1e9d851a36db61c253e GIT binary patch literal 294 zcmZQzWME`~fM*O0%q>th!+$6!&35%TS=_hE+8|4A>6MIvdoM*aVQN5h#hj&+9Qh6@ z2)M2{O3amBA+>n=2Zm#;S{j@@Y%dl`z1PcKymG}>Eolk1f4_}4SP7q;s>VGbrrMBc z)8oeD6E5y>%X5jD?90l0bW(Y`Pp7h!KYehj@57sB zJ(KNh-Rj#qw@llk_U5A1Lq^@Sh*`Y_|I)oK%??}FHm7Ct0-HNa4tPC?Xl*`JE8qL{ zvfVwE`TLZQg>dyG-QOTLKmE@%lRSrv!}c4tOtf6O`Q)EO75O95>q?Ki6+d11tZMou fJN37n^G-!4y6s*p@u+q0tJ4L}ueHzK;@JuSSHXc) literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/not.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/not.json.i new file mode 100644 index 0000000000000000000000000000000000000000..5708a0f30acb78bad06562986d926a9153a15274 GIT binary patch literal 356 zcmZQzWME_f14b1F2DTj#HUq}<2bOn>8~IEk_?A16F(KCqv+Eq7JgorR3om+uS|bvu1+x$0!4 z%ae)?g0g=dOJXre@#2fvpgL>v{v~0p*KfWlT(s+lXPeW_-x9N>Iigp-m300;%}sgP zY-ho%ahtPDx(c3rYn4>}J0Xcta-v(L^R9OX{#DgI-=USNeX?@ry$$nJ74$B4uv<87 z{{KMQNTX=gp3*v(^r^?s7I&8K`Z%RF>0I$!(>5uSH5bl>WfV8@uj`zAKEiC(y@NT6 vc6ZEky=MAdC|=jREPb^#Py4$R^LKZ*zj0xj`DK4=s$Ku37aXfs7q|id8HA<| literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/not.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/not.test.i new file mode 100644 index 0000000000000000000000000000000000000000..b094ea0ffaff96670a6478492c32ce917079b6e3 GIT binary patch literal 299 zcmZQzWME`~fY%HREb34;!+$8SkKfc6VsO{9kJG~c;wc8>9gALC!PJ20iaC2Ho$fni zz~fr4`bkPG=XtmQ_x94v0HN^CneD6oSr=vs25_F@nH8Gy^w#rV8{aN)d;Q?>l@~&5 zc|tU1IIozg*v@F1DG_m|D))lrzeQg4K{qFaXD*+ASlj-s!ZybYf5Bh-;%9O@KKjVD zVW#-{oL}C5S!I7L7QSs|6s4*8S$J-3)9tv5$S?!zLkzpat7a$f^_5$ibI(_9@$rIb zZI7gN@9@@LvvoI8{r%?Q?Kz%@Ip!U1>}H<2Xpvcwcc9Kv#|69him7#)z4@vjXF2{Le#$dQs2c_q_A__BSXV0HV=_T>t<8 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/one_of.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/one_of.json.i new file mode 100644 index 0000000000000000000000000000000000000000..ca57a008e0e522b93462953b3a2dd2ac487ed1f3 GIT binary patch literal 357 zcmZQzWME_f14dN_1~zvHn}Oj!6!6~a{hzeq`(MYfr~B9zhHyS$f3pXs21HlPIXd~Q z-(drunQ|DoWz?6!A>S#CN?A`bbBvu=9|etEYMrUpb;%sD#gcGh77 zp0@a-FLud(*)ZGoZ~}io(L$9XrH;2rtJR(E?e#izjO!+ccI^8n@nZMYAIEZw?QAqp z-sri-AYjn~x$vl}k|nAv{_@v!rXMTvNjmmeP+HG1f9WE%>-}3EyRI$MJ&|gEW|R0T z4X5oF_9dTx_rN5+Jks3d@|UltUyIlW3fBA-VC-zq|8rKvmOtn}bG7N--Rje3Jqn&? zuX*dqj1xUO?j0{I(m3k-Z}Wsr_fLig@qanUc0T^(w$mk_f~`DL;t%HkXU^fUbeoa7 dYHsEFvh`2i8h`8i%<{Z`jlE=AxXFD>6#)9Zg*N~I literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/pattern.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/pattern.json.i new file mode 100644 index 0000000000000000000000000000000000000000..5fcaaf675e70bf4ba085b55dfaf90e68b9c78f9a GIT binary patch literal 238 zcmZQzWME`~fOQNEOm0v%!+$9F`ggA4uJ8IeHZz63%;lHd%TxI-1f~W=SIk*D!I!Jq zfv5HRyd;TTTHl!BTy>T_4q=u`om8fLZ|~!d`UKreI!q_4`)gEsr>xievalrYrbP~` z^rg;Ax*ZYjuXshD32ghAlootTYR~%FJZT{kXqR5-%$?TO)ZjY9q1fxmy4h?|z&PIms~``y63#DB#Pe;b_@h0~Z-x<7Z+ XFqrIld}aGH&F*8C-FENY+rI+YU_n#b1!RvgdI3Kiv|hVOZbk&hK!HDnLFd5S$&ilS(MA@K@q zWK1`0m3QAUWC=8oKn2zMU>SRCe={EcX0re;?`7?Zh$s(@%&gQ(tn2P_C_`(>s9#2B zWUQndUNDgnT5e^R&J=BUkZKPIhW2z6-evVXJWz^a-Po~v=_`}cEdKVO-H5QS8F52M zWqAuDPA%KZ*Qv2LV_LWFre)i)ODhB*5OVe=p~~CJJ&yQy2s2for)UU=9AfymdIG`Vi1_#{gmxpb<5-xWgP{l1~-n z7IYQn&tjLs=B_s}GrZg@ZJ1SQ^{9j26!JCbhh6%kj=%oeE*fxsg3^d&E?pB9>4N3s zN?OoREici85`qui0@C3$;@LRGBg3XH&z}BIrE#@Cv(RAs$i~odahdhwiN zB3S+xokdP*3#h^aOLPRmD?}6{Co=a%<#>oWizTUCTKPf~D&gko@#ps4_fBpYYDEmR zP6(CwcoOBD=Uv-4w}ur)k_&VW3!2Ha9blH6pS;O;c@us6@T5O>Gj%3YM%gW1RDfqxJ2 Rc>v;oyS&&g{sQ9sBFNrLFu(u+ literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/pattern_properties.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/pattern_properties.test.i new file mode 100644 index 0000000000000000000000000000000000000000..66ce8603669bd0167b99f0219e14624d62e5cf96 GIT binary patch literal 562 zcmV-20?qvZ0RRC20000000Hs<01Y|-0000000030|NsC0|NsAj3N0TsY1?TsP=#pL z&{(3y{W-D#00000000000001ZoXwTNZrd;nhF?X{u}Fr-*{y^E0@`L04K`^= za+|iuyO**IcaF1l>*TCDI1D99{PauI?X%v3sq{Csh05VV=@LB1U-2``@9HQ%f*Qrv z4S0{1zFTh4dV@~gLuDjFtmf5OgD>`mb_$fm9UjzjDW(%og)t%yQKp|j%NnlOV;xtX zEEDtjbj6+FADb>4LtbXL`Y3IoehU(s*qOM~V%2TsO*6)lp|gN_+ny0f=U{c@>LF7r zX6Qt--Z3{^&m(|OdJwL|O)cJtFv>RvsQHqm7fr7v#@)Z#E-d=dBd*F3sEP<=4CCY;hb7$eAkydh5N1^(q&G z+Nw&2{0m$t3T`Q!f-T!iLQlos95(B4zEd*4Mvr^{tGt_=%YiObHaqLx3$UJQRcv4k Aw*UYD literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/properties.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/properties.json.i new file mode 100644 index 0000000000000000000000000000000000000000..a24abbc5b19d64c9fe707743f55b03bc4e16c116 GIT binary patch literal 507 zcmVwjZ9XOqRMx_tik;KI!nx_S`kzy zXqV+rB$on8@C)Ihf-P<*;a<}r)*Ujd|a`JwI*v2Q-~XJGZR8 xEo^8DXC8%_JI>sPg@dwI)Shmm&NQcI&Pv%_`SF}~Pfc9-?vdvO-XFbm!q5yJ^lQ22&&}fI{ynR1qTit?6=uv0u54 zX(Y0jc9*zy6bcY!MQeHBD-e}7YqnoX+aE5`r3uT)olsOsDIR}E%xwNc zHSJyMUr?v=UboxKNxDQws4=BGTP6(_1uH|-i0D~}+mdtBS8LMTAA&TEyl>y>R+Yqk zF+M_HuN;U3tVKi9h6%z@2)vL2S3L7@kZr^9O>-!eh znks+jh6c7%t6A^0IzXzOa`jPH$J+7PRX^pyBP~u`liMS$OVypu+J~G!i?rSQ1yQ$3 P4~0sD;yV8T-qr5_mVDrY literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/ref.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/ref.json.i new file mode 100644 index 0000000000000000000000000000000000000000..c33d427e29ed24b35ef67057124765fa44730a5c GIT binary patch literal 584 zcmV-O0=NAD0RRC20000000IaA01Ybu0000000030|NsC0|NsA->UxW27T6SZVe4d` zDRJ2%uXdFH00000000000001ZoXwWWZsRZvhVOm~L!G%Lbvx5s`V2kvUi83PbfUtM z42daF6zQ{%mLy(AUebw+@xg#ClKM#gl>L;X_WJO5cQKA8*Pkc|i9&?<00^Pzr7hNbhhcrEwIE`A!@0hUrwO zHr%{)TVckrUO-Q&RlAM-ojZlnHrfuM6^ofNeH;rR{r^ah*kSsK+>vP`bOuq6 ze8A&nS=j0Fk!3_{pnjoM6 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/ref.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/ref.test.i new file mode 100644 index 0000000000000000000000000000000000000000..d30197a9cfdf54e0c6f1582b15497f397c069f63 GIT binary patch literal 513 zcmV+c0{;B~0RRC20000000F@O01FQQ0000000030|NsC0|NsBhBh=h2#L>(BoAOO`yn^Ae=uOICt%IAdG@fnWN#F>Uz6$2C;w*W4OI ztTs{;T4u3iS;i`$V$FS$E7n*=IS3(18V%~vni?%hbV-{!4YtkR`K7NIx?J!N|C_O6 zcwNk6oED3Xb#ja6ASS!%0Kb5p?5A|U0N4sr&=VXz3-h;Q5Ml2+oTz{T(u7kw(4XGw zrc}_c(DG0|c1qaty*LlTN&6q7lVA_qc}8BRz^#K23~qSJjIMwhMISi|y1Y#+FC{85 z2ue~3_#Dsi+y!d7I+E3Orzza?AU2!FI!WceRl9z-i+yHmNSfEgK5uqOK!_BpzyXD^h^|3O5NP`aV{7%py=Tx%KRnX zT_YL5n^)=Z$AXWX7~cGuj!!4`UzzXQb683JfOSIpTu$&s&F zLBRF>bXWt)I;_+F# zb5ji0q~t{pFBS6g#AlwC{CfRnOztb;IV-j2#DDni<;{Al$Uyq+>)t8N1?RT~xo({< zc4}3@p`xj+^=n)v1|=Q5(YPR@#JwVH-BdQ_Lyu1WeX;!bofZ|3mODouFP69~oBYnH zxNq${g{KAc13d~oii$S+OC9o?WVXdr`^rm^Ao<<)5=v~mZ=-%MPpo48+1)7cN%hI9 WdMVG;-*?}yS9VpcVrczzZ6N@BkAwpN literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/required.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/required.test.i new file mode 100644 index 0000000000000000000000000000000000000000..e22a6fbe798587b74b419497cb041c2e6a4f07db GIT binary patch literal 235 zcmZQzWME`~fYl5PjBlZAhW}9DWTSs%cE5t!_sw&Thu=D2Q9GX{1f~W=SIpTuVK-m1 z0gr3_(NjFm*Z*-P85~_P&Bpo2{4OEVi4olua_2Qxmd! zRxJIt_xksO%kvITGck9XKCd-v$D&lxP304wU*Kdd61-NZzE8Q6xxgc6vHPKyKDkzV zIksw~%@2Csuexl*MtSw$T&aGhMiGsRzxeO*{K~!lv)=zxXWr#s`JG?a9Ua`fw^#p$ V^qs7T5bIO?4pL8LcPv?a902({XE^`> literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/type.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/type.json.i new file mode 100644 index 0000000000000000000000000000000000000000..c416bb7af0a9ed92f0f5ca7222e118b9e880c804 GIT binary patch literal 692 zcmV;l0!#e>0RRC20000000MLX03=!f0000000030|NsC0|NsASxLGXaYv8UuShosx z4nM~&K2?VR00000000000001ZoXwfdjbeSuuBA>fh?h_QK?)JXu-j?44y&Tk#=EX1`B@9l6av zg<(z5Wb1aEaVQ}MFo-;Y8v zGL!EWLre|860|giWl%_S&^-7EBPFpB#v*qSMxr+nW+L_w28wT?W`_qB@-bu~-)j~N zy|qiy%=$M0&9ZI6#ApN%Wm+_X2PtR=qKszb;} zb*Feb^3yNKMi3~0j1W_z<06EW;IIfG4eDr);`-S}2#H)q2q?abZi^Jys0kt;HQizv z>4vc!C5<5>chU%`G^a+Gi@s>XObMzs3-%B$c77N6fBrWS&HD)pkq{glw^o!IE=+VOb`^wq aC=G;ZNCkv(==_6OUeA42+tm+5Dm@?`_cuWR literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/type.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/jsonschema-tests/type.test.i new file mode 100644 index 0000000000000000000000000000000000000000..b1c3c58b39408aa3f2d2084afa5596b47aea8f27 GIT binary patch literal 781 zcmV+o1M>U;0RRC20000000PYb036`}0000000030|NsC0|NsBzWK|}PHmTdbi>WW- zD8M{f{}X=z00000000000001ZoUNF_Zlf>|hF`_;o&pJ`@7Ce?(~<+jBD(N(r42ef4K8MOH)|?Q|D!CFSb_g&(*5J zw5M;|sL`tUGc8F|BtSxACC|9%5Upi9RFwc7yR*fROTwv zb}(htZUUsUs?t1$rmgexvL(d*!K_Mk{AW*_j>G=IL@;%2ezqhCM~p%otIF9fdOL{n z<{Ss2J71PR<7as*jySw;duM0pn#c~Fv(a;IQY@pHD?sLzB%_g#(tKbeT?6EzG#!XY zr$Y^;;mAR9G=$!QNk8(pvL2lpn=4BUNw|)Oa zeCS+jAH|a_MTIcfJ~BU9hOz;W|G+`I9HWEsn+F2Y(Rl4COh*QiBcHB2g#buF0syT! zr4mHJ{kVeMXVbKS&+durzHhC6^DK#dA`t8zk)4<)3J2Oz6-Yk(n9)di;2o8XtrOif za*i1B)HqQ%@@+O8*(Q77qtM}&Kx}B7@@?p!$RB#wDn}#XC8wANo3{V~f9;7GfPhQN zf>)nn0-)g%0<;2M0e~g~q~n4zB+F3oC?G3I2DlWJs{uYd{iWgiw{(7r__lp&cmm#9 z+MO`@73#az+R0#onhJo@t(fHu&{F{f+K*vW28t>`K$|iQ1YoLwAlaE&UI=6=3j$3O z$^OhzikGW`@K}c8=Gy$~>@&SlCx3fKtD37l~*|_+ke0w zIGZM1ut*aT7Gok|Bfe&nyxfoxXw9$Z==P>mz;r&q(nZ}NnS`AjZ?)fd$e5<4+^8%aY0+nr(&)Xk)$#&+& zi){Chgvr`ojurvWM_~5InhX=iGx^QoYIz_oVSZX@1C1ss8ry%nGM2ad{#LxbW!h2+eL1w{2Bq5?!tAi84C)~N@J znhXTm;#1YrUuN{zHrp{jPMqp`nbVWE)A-bncXwH~Tv;WYS;c7fbMwzl_ByHRSyR0B zIQFhuD%rs$TNI&}_F>nPh-7CO?)6X4UEaNTS*xwqNvli~5!Nrp4c8tq`tSx>-r}B}i;3@Of8|vzH+%lMFpmt!*g|4`YzWzrhXT3K6TCnx>lPAm$v$-lx zKNftV(*0g^Q+LAOzZH=dO#8)-xU88GmhHQC@vC~Te_sOG4weMh%~$I-PkoZQ#)wIO z`BW>r6s?aP8g@SVH_bz*1rNiB8bWw`yVKvDDLGu996bMJgHIX!9Xz4GVb8{68ob|~-L g^6>T%lSS_JzmEj{{3xiO#(6sYt;Hio`2fS@_L!0Za{uu9(w%?jTpQ z0T0`Q;@={Qw*x=y3m4=M4HlabdZ|LH_WRbb_T?Lc6@LCxnQNM#&BJCcY{y_(!MBFR z>9N|x=?q?h8#Oih{Ab0csU{UHx|=3^e%`@ao(l0#srT3JT~X%X;ahrG|M@2EHAyk4 pk)Bgt-nYKL$F}UjlP?}I-c2F$PVawAwbqipDf9X*`{NCshX9EnR-FI< literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/sample-test.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/sample-test.test.i new file mode 100644 index 0000000000000000000000000000000000000000..d83f3ea43d274acdf2ddde054dbe59518b1c5c5a GIT binary patch literal 516 zcmV+f0{i^{0RRC20000000G1R00z0Uu+aRH21?>itv7rRgyBH5wXt@EzZPtuuXooR=|G9dbh z&);R(JnPrg8k95h)gNR-yv(8biKA%#aDTBLx>XX_NYCWh=ua6nw{dA#+GG!pfWQVU<)s*+>Spl46$hzoNz0 z#T~nN6$iV$m-iw?5~85(CWDV~J;L<}*S&D9??;8RhG5;wTJY89X|6ak;heqrE&c~$ GFu@pzN%h+R literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/simple-test-fail.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/simple-test-fail.json.i new file mode 100644 index 0000000000000000000000000000000000000000..019d9d844479634899fcc17a5e25bb45d8a03f80 GIT binary patch literal 301 zcmZQzWME`~fVT_`j5DBYhW}9TINk8t!qbbUS2r~5;d3uMF}XB;6HE<=u9%bCe>bn$ zfTwl+LrtZ1*LC@x7O~s~utN zx?UXakvgTgVODnHr)%r}p5FA)tg3&x!+n!wm5WaAy1hKpOLHo#ZDPc|vI+CgE!lEb znQ8T(_iNKdCH6jxIqI-bS?%GA_UkdHk54!xR{cjuP2s8#Clj;ok*{6_+P{+Tip`$}0C_`=RR910 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/simple-test-schema.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/simple-test-schema.json.i new file mode 100644 index 0000000000000000000000000000000000000000..3693a3e887d23ac65881dbbfa4379841afbb77d3 GIT binary patch literal 239 zcmZQzWME`~fb|Rvj22Kf!+$7PowxKPM}kolW6PvX?9qu+x;B?{!PJ20iaD))2l<)| z1YFL)4WDpKIf8%Q53cveoELImafsgT-J|$tx2}YV+OflGvu~PjHZD{vTlg*^V9^;D z_b1+(>kr;c3jNL(y)w`=M5gbP>$8il{QQeV*6nig?OwFSEM-pUU(UJgD$I^kdS5Xw z+5BHX{oIU^!6Zefdf3jjFJWnusT literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/simple-test.json.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/simple-test.json.i new file mode 100644 index 0000000000000000000000000000000000000000..cfe71ca0be993c2b453dc62cfb8e40662661a4d7 GIT binary patch literal 308 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 S=QHON+2<7X=cTZ+mI45)M|-LO literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/01-any-type/02-enum.yaml.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/01-any-type/02-enum.yaml.i new file mode 100644 index 0000000000000000000000000000000000000000..0231912452fa8041766e049d39e3807af0435faf GIT binary patch literal 285 zcmZQzWME`~fV&I~%&t&2!+$8Kx%yU3XQH#ln#;zgYzr4A9Ljj{3Z@1`SIk*DX*XZ9 zf=JtUyQA`A;yziE_1@HSJuXNxoVBXiqt|d>^~I#->0gq}`Tk7rZ{T0B#EI)fkT^$k z$703S2MK%yOJ}vjuC|!kI&)W`CY$E3X8X_k-{>Ux9Wcpt=TYZO-RTgUxzoet##gh= zujhJLuMz64a!oC}>ATHmgZ0y>P4}4+*Dx*KT;KgVxAf++=W=Qc=XJ}tKCrTgiEutW zb#w=hh;P{P1*;Zan^mJBdpt;Uxuwg2dh-AP literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/01-any-type/_makefile.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/01-any-type/_makefile.i new file mode 100644 index 0000000000000000000000000000000000000000..19ea61e8ec9c4f99d3874ef7ab9c049b793300d2 GIT binary patch literal 179 zcmZQzWME`~fMOsu8_H(*4+Ulw?7t4mcn4aGFUnK+zy7aS)w#_uH6XfTj_;|1T+Ido zEf0&oYqEV@5YYVPM#m4WOB_)?W+mqBd-nQH+_wGakM za_=*{iX6T>Z2fsc|7fs9#2k&~`YPRjQyx$1_svXue$(`Qg3Dd8TiWN&dPYYlI@l(- M*j{A3>T4Vd0Q)CQumAu6 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/02-numeric/01-min-max.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/02-numeric/01-min-max.test.i new file mode 100644 index 0000000000000000000000000000000000000000..20e0e72e70c6d54794a78a69cd45403b757d330f GIT binary patch literal 236 zcmZQzWME`~fHe#ZOv|8bhW}9Ts>)I#cTL5WCIN@k$93!3wcdUNszZQ^Ia4PDavd_@ zaabSpYwu4*o`cpEOdpl6bhMT|xOF1s%{%XzWgWTZ|1YW3R-UY!5dJ}-f6>a8oP$d3 zmtKWMZ#pzF=*65TlY+~)EX@BAVtMcVtim-GrOdfM-da1o(-m-5E}fw&mloI9z|XY! zZ+7Ur_^ljq#XR#jhPTbBd!)JSaLXRsFH5`6T}}PJq+~8rT8i?9bMYqc6t>;UwSB2? UxprraVPA#w{GM}p5r;Tk@p%s)44wWfO%~@GEV}$fS|+YMv{-ww>BD_T z*XB+0lool)mvL#@-kldUW!)}^md=UF)-#_jqPjpt)SfeGYudjf_C@zCy+fSO_xyS@ Nlkc@{Jg4=!cmT?GVJ83p literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/02-numeric/02-multiple_of.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/02-numeric/02-multiple_of.test.i new file mode 100644 index 0000000000000000000000000000000000000000..09e7c85cffca2af321755a9040ae3e616aa0a457 GIT binary patch literal 154 zcmZQzWME`~fG8j}8_H(*4+V-eyrHOf9mcO>B&=q*LPlnsR7Xyb1sJl1f1|b ze5`IGEF5)b4Jt6qbDU-?sSMVous7As%#tF8l@Mj!=|xB kHSO6Hv86(p6B_4Po=};WxxTClCLfEBk_Zfw+0x-@+3xH6XfFPfx$NG$}VR KJ2fpcClvrFU>6hs literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/03-strings/01-min-max-length.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/03-strings/01-min-max-length.test.i new file mode 100644 index 0000000000000000000000000000000000000000..954e3dfb8a48877e2f002fc835bae94a4dfaf771 GIT binary patch literal 215 zcmZQzWME`~fawejjEkUbhW}7-@XLYh4o;iKGjpFU&{->bC)-)R1EvNd;5bw&OW{EWtdG~wVs^GKPIW^wX6WXG+Ye; literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/03-strings/02-pattern.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/03-strings/02-pattern.test.i new file mode 100644 index 0000000000000000000000000000000000000000..db871bc7659e3ba2267946f37150a4ebd8d7c942 GIT binary patch literal 174 zcmZQzWME`~fIJ{|5Xxrw4+S$^l|uI1?wn*=dX;N;gVpC=)+MK4YCv?wobGjDUYIGg33^?U|#+Q{-L}l8PC1OuCMW(B%FBcPUUeYz$IH=fh)#}7e3ay0~ z*>+9ac(HR=Xy2~DjZs=&Ten&{h-P-qv~+kmY0;&S1z{rDIvZ~?2gOHC@tS12kzrAY Gbu$1`P(jK7 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/03-strings/02-pattern.yaml.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/03-strings/02-pattern.yaml.i new file mode 100644 index 0000000000000000000000000000000000000000..a6e68e7646065d3bc962767d1e1c0b6f2ff991d3 GIT binary patch literal 173 zcmZQzWME`~fLtK82g+vn4+X99SMD~rcn2(Y6|bG}_33`ruQjqTH6XfT&gIa6fD_(l ze76Q^c<5+)>YfVL(DU{4)75*%qS7?-N+(v>j`OuNnh F0{|MHKp6l4 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/03-strings/_makefile.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/03-strings/_makefile.i new file mode 100644 index 0000000000000000000000000000000000000000..d24649470dcba7184a2be756ab08dd97a0c185e9 GIT binary patch literal 79 zcmZQzWME`~0Dd6F2W2z-hXTRt>WxxTClCLfEBk_Zfw+0x-@+3xH6XfFPfx$NG$}VR KJ2fpcClvrFU>6hs literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/01-min-max-length.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/01-min-max-length.test.i new file mode 100644 index 0000000000000000000000000000000000000000..353616578c25a4f02b076f9e3b984c6442b9f084 GIT binary patch literal 219 zcmZQzWME`~fY}TTj9Z{=hW}7-qWb8Ed3Q=}&InpWr^rUE{kEp?0Za{uu9(w1!IA5b z1CQ%^p|rWJTgx8v+Bm;d>bb~g68s`%K|ob``UIt}tC4Cy|Nr&Bbu`BF zRqmbO&Ag;pG-=xB&H8?O&gbtlbF)x1$&Z=EU3Ga+;c92ckNXX+zs4KBw7tvx>1)eD E0E{_cy#N3J literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/01-min-max-length.yaml.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/01-min-max-length.yaml.i new file mode 100644 index 0000000000000000000000000000000000000000..8ebbdbb46a9ab3bd661683297df44076e95d6c09 GIT binary patch literal 214 zcmZQzWME`~fN2a2jEkXchW}8Ib??ij!c9vjK5E>xmvh0afPg8dC17embj6&heU4m* z3|L6PtQVbHdk`EZG9(9)_ zuup5~Qw`hMD$FHiVUo4_%g1>xwXdata_HV=MOWSA8{w){N#qgAl}+Wh00H6{R(uv0+H!*|~G2L*dd(d(IrX6movjl{-nTk1joVa^+Ey>VlHO zBDX9(k7UzLTnh3j9=U7z0&H{*joGyrt~8vLlVx>|32QW&F1A!CF;s`)(HeV6020YR A$N&HU literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/02-uniqueitems.yaml.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/02-uniqueitems.yaml.i new file mode 100644 index 0000000000000000000000000000000000000000..c56359ce3e1ab0cffe9611da882ba55c66a1020d GIT binary patch literal 168 zcmZQzWME`~fD9mY1j=Uk4+UI(4;z1K)G^U75UG_>tLsIK#lWNyw zrnQP4TEA95R9zX({>^)R>ifSzNoJ8t6S8|{^kvMChppQ2Gxqm^_=9=Z Ol>W0k7rr>x;V=N)a7!)# literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/03-items-plain.yaml.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/03-items-plain.yaml.i new file mode 100644 index 0000000000000000000000000000000000000000..8e39bda3ff3d0b049d6b00b2a2248b473664deb5 GIT binary patch literal 178 zcmZQzWME`~fFdAu49aHs4+RTvraInQ$fxy_r&w?Sp7Gf*H6XfT&gIa6fD_(l ze76Q^obWtzCisMo=h;vVJzqaRUA<>ar!<$SOjC){bdi1~@lxXTj3Z4)yCxe46*n%r zn(*|ff}3Y5tv0YlU<-}~Uv(Gjpo>YJQRgZT$Obv*xn6tLekdMib zhh=}#PCw_<;eMJv1_eQn7TnMbn6iIzfrops?9`=qWh9in!WFu3C-X*6A=2RT5+mX%DJ*#pYKjiXK9JVAc1Su9s%- zmOLrg8A;$^CT{Ji=rbo#G*$NDtvEzNK2FZI?m;FJIr+J>{T=KI5T+=dB7y5+4Y3J?TyP)HOAzCj83t#ZnT1^KK?* zC9vn8i&Q%pvgljKYqk5Gj(aCc2Cw?m*>m>AwI7%H-%k8@RIBP={{Q>o_nFSm-COc2 W?ZxA*{;}0c(nat8vBrkIc?$qrIcoj@ literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/05-additionalitems.yaml.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/05-additionalitems.yaml.i new file mode 100644 index 0000000000000000000000000000000000000000..8ffffad27faf66e919c78fdb8b9dba328bb376b4 GIT binary patch literal 239 zcmZQzWME`~fb|Rv%vw-3!+$6cm+Y7-8};$&G->f;*Z*x#nEE}s4yFb~SIjvZXvo)W zz;mav^(YT>cHIT@5ZM?5lc0iCHzZfBs@L}noVcoMQ=op~lg~f>!kHN!d$4VIy(a4X zivwD{Oqb#^TqfMurV`}i@FL*ifsHF2oR@HUoe%NzPl=yr^k{2J(R{67-TNV?FWy?o zZdqdz@WaZw`aQ=_+vp>*Mv8aR7i4U(Ik0#|z0}K#yCgEsdTid@+2Up7J8kQ;%xC{D Zmuy>gU*II)tLhS``H>?2d5@oN1^_q!Xj1?H literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/_makefile.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/04-arrays/_makefile.i new file mode 100644 index 0000000000000000000000000000000000000000..d24649470dcba7184a2be756ab08dd97a0c185e9 GIT binary patch literal 79 zcmZQzWME`~0Dd6F2W2z-hXTRt>WxxTClCLfEBk_Zfw+0x-@+3xH6XfFPfx$NG$}VR KJ2fpcClvrFU>6hs literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/01-min-max-properties.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/01-min-max-properties.test.i new file mode 100644 index 0000000000000000000000000000000000000000..612019eef0cbd1926d3b68af40977558e1a27054 GIT binary patch literal 208 zcmZQzWME`~fC&r?j8~v+hW}6yIp0vdpyT%3-}7#2gmcXMYjEIdF-#4Ju9&m5eR2{snag)W*>EB)6l_IVmcbOZUN&d##H$!0CvIDK}nh$L- z;$6Gw?TRhyx)^6pX{`M)=cbRyxlEHubCm@zwC$LYvdWjbhRdDw|7^nBa6*fP*DxdSi%|d0 zX3_UYb4>qje14`y+OJ48=i22`mT+h9jKcLZe)?@`O1`c)SASBGKsD3ZIWG<@)b|t< m%#A;A#q-3<6T7FkKV|#$;q6?}zvdr;pVYD2G3;UJXaWFwmQjlU literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/02-required.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/02-required.test.i new file mode 100644 index 0000000000000000000000000000000000000000..058fbf311be649ee60f998406cbd69b0029b15fd GIT binary patch literal 186 zcmZQzWME`~fGQyM3(98r4+Y9~kC^J%irnYOzM1J?UbH&-^n|rAH6XfT&eFcUT!$4T zT;pB$?ew0sw)no1MaRyCmoiq^J5StGz0TvC!}i7P?+c!5b)R&bx9Sx8{!Rniki!!# z%49kYJMtZC))Bn_NJ(sJ*H#bD7n5oaf4{Kw=ZxQfr(R(<4h?&3c1ngj7RqM$4+Tx;1-zR4ZCtbOvlYs0<27Vj`t&4B4T!Fov$ofkuh~Gt zx!ms|^8tpO`)72u+B75t8CTAlzi`zKYsCwlQ_oJC|5uA4Y^{hz-J(L72aB(L+2_H_ zCOYLo`^@`M0n^WrtO+{+Z;P08;~^E9PwN+sJpw zfXAg?_0yf!sqqhl1)N3JsRqq<+h!aR_+Pf2$F-@EHUE2!-TkeX?yg?Gd9}(ZLtpWn zWf{H;4hH(%I+$rb^-t5bGkelDxOGexVse=keu&w---<{6!$R^-GKAv+kdg7uovp{-y2e?MI6C0szfuRN(*s literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/03-properties.yaml.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/03-properties.yaml.i new file mode 100644 index 0000000000000000000000000000000000000000..0cc235fc149c6df42565c724ecb8cfa360b8cc16 GIT binary patch literal 205 zcmZQzWME`~fL;a$#!4ug;Xf2iZJzKmF;6PxTU1W%40EZ(>GnD6U}`{g#hkr ndDXKO0XNNSq-`h74t^r<)^Ec7zqaJ!X*cHH&fVfHYWYV24&_o= literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/04-patternproperties.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/04-patternproperties.test.i new file mode 100644 index 0000000000000000000000000000000000000000..f714f56891f269bbcd8934cb4124471c8700477a GIT binary patch literal 242 zcmZQzWME`~fK3bxOaV|f!+$6Uin4n5_>;Txymc1*|NdyS{F`#&AxsU3u9&m8-;w)} z0Z;3Huah?qo836N|H0AS8dD_G3)iapwg÷UE8MM3!B?dpe5RqyK^4BXtd)hj_J zf5Up0>)Kxnl1}NI%j{lsFgs0U`_k3!NzIO}H%ug$JTy$ww*+6;G56ySvf|2~v+-h= z-lu@~_lwWp=G^i9aiU~mH;W}dH>cmN5~K7kjow bb)n{WU0XO`8YzmNp0TRl=Vb_JLXew%BUV literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/05-additionalproperties.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/05-additionalproperties.test.i new file mode 100644 index 0000000000000000000000000000000000000000..1d20f88158978b737fa2815c28f2c7ac38e67549 GIT binary patch literal 284 zcmZQzWME`~fIAEfENoCV!+$8ST(;ECL1xm9$$ElMIQAJ>D}HAC3sVE4E9UH-*h`7Srs4kD?a9#tPChPX?Eh8EXTwBw-x2<1eDnKysf>y?(ODz*%O%>EnK!1 zq%1wzAF=UO%MBMNsigel&*}nnw()8+OF5e?S*a2!5uhGDCBt)3cTABx@5IlZP3Kyd z&-07U(OSHB!Kx$E*_@^dbzGR$e?WWtCAlpoLDgrU@5nrS|8ZO2@$EMc$*j$oH6fsz zXGzlhHSXu;vn1^aGB$V=pV<<0?@^V>zVtb+Mu%>HH@PGt*q3OzAPj&Y`pVZ%E7`Jl&#xKFS{}YYaN|mO~kZKn@aP6|WSNpE8mS>-Tong4F Uuk&o5k$XsA-1jG3etMyA0E{$%VgLXD literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/06-dependencies.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/06-dependencies.test.i new file mode 100644 index 0000000000000000000000000000000000000000..c5b68366e2b863776f83322b323ab1d350d65237 GIT binary patch literal 240 zcmZQzWME`~fDH@`%%)H_!+$9FYRzSh7GZHKmNU2#xNIL< zG1&N8#k$7$rr@_9W@XP@?tBlQ*LC(z+^^$1)_$H|_(qpg-*vow?TSQ69aFa>dn^D5wP^bQ literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/06-dependencies.yaml.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/05-objects/06-dependencies.yaml.i new file mode 100644 index 0000000000000000000000000000000000000000..5c50fe916a699178a2782dcfbc10e1182ff25493 GIT binary patch literal 242 zcmZQzWME`~fK3bx%ra0m!+$7{-H>@{v+O?B1P`_FuuJ;P@$VU%VQN5h#hk5y-h534 zB6q60EE{xG3NNpg5cmBZvgpdQt+6I8yS)_~772AK#%`&cS@}7W?ZAmiEOVY8nzQia zq>CvbE!FyO-QLuD}@QwV-%JLqi-G#55QoE(5i9B%&TeKkWz|Ec)o?_b% zeDN$<>BF?VlxZHb?MkmS$?HBWxxTClCLfEBk_Zfw+0x-@+3xH6XfFPfx$NG$}VR KJ2fpcClvrFU>6hs literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/01-all_of.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/01-all_of.test.i new file mode 100644 index 0000000000000000000000000000000000000000..1b5f032b07051c6f868f2eaf583f8176ed1f2bc1 GIT binary patch literal 180 zcmZQzWME`~fD#~e8Omn(4+V{9_a0bi8L!{!9Bq#Nu(VNp}O NX4Y^?TS6=t$Zqj&OsQ)t}W%8GwEBoVC3#ldBUzl3E!t>sR`!jVjWSl%h&#<=M HwsQdh)Ko{= literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/02-any_of.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/02-any_of.test.i new file mode 100644 index 0000000000000000000000000000000000000000..4915b795f2011d6bb389035f5d5b8d0f730b1866 GIT binary patch literal 194 zcmZQzWME`~fF>aI70PD#4+ShMIJb9mZ1+1Pc0Yin>tXd*hU$+nH6XfT&eFb(T!#&K zT^*pEiJ>R=&Z2BTC?Tr40`x1=~%*bGP z@^|OVptVbb+yd4tH`(>}Oo%RT%72-!2b}thzMTA%Fj3~lTpiZFBYu0>isOGXn)3wi ced4vNpmyh-{}V5+nVBbd@#a_VL^;3B08!^r^#A|> literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/02-any_of.yaml.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/02-any_of.yaml.i new file mode 100644 index 0000000000000000000000000000000000000000..63318bbd7d9dc918cb56054b6ebe3cf3a6162db0 GIT binary patch literal 184 zcmZQzWME`~fC>f%Mp-DE;Xf4k3usIFpGjAY*l#2K%E-En(JD*nMEwN=;q4#`N znAx`}0jIL7csZy3ozwp8=yg8JP09B2Qw?3V-1b?U+Btnin&yOzlb4eV#aHwezvQ(K SxMub5h{-8C*8CM0ysQ8p;!Lmr literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/03-one_of.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/03-one_of.test.i new file mode 100644 index 0000000000000000000000000000000000000000..4a0066d3504aa54118d55fce2b6b954ddeeed50d GIT binary patch literal 218 zcmZQzWME`~fLRO-jCY}IhW}7-^lpIK|MS01oP00H9K3FCxPR;NOE5Jcx?;}JK1Z%Y z1_G|@h0>N@=;bz_=lFqPX?K8n=7O0XX`3{bmX}}BYI+n_KL5Y`{OjimwkADH>FZ_O zBxvfSw8!G`()SZ3OCHo6h*(*9+hnWpiIV7#4oz~#I=z)sbu1^`-zD*)=Sk{?hYQNz z`)pq`V{_t_s3ON!xj6q9&g(C!F23pMr4}{oTfJFnS<0Vvo>zlH`s-D0-DRASK7Azs Dp_^fh literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/03-one_of.yaml.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/03-one_of.yaml.i new file mode 100644 index 0000000000000000000000000000000000000000..2e3a53ef8523435b0954f40e0fe07180c5f50bc1 GIT binary patch literal 218 zcmZQzWME`~fLRO-Od3!&!+$6c3%p_U_KsLWsoQ3v%xv=te z#8%DZn3E?SZpnDd*7rm#Hv4AX)~!)DYP8#%B&yHJ+isOPlE3En>`DioqO^}@7BU|* zZt*7hC(bcSPS;eNbmq6{+gAtqC%z6kTC&0B<9C)I=7@(^O55hSJ+<%tz*2W&@_7Kr CSziPI literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/04-not.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/04-not.test.i new file mode 100644 index 0000000000000000000000000000000000000000..254114d386884c10914ecc75dc90917cf090f1d3 GIT binary patch literal 165 zcmZQzWME`~fK(v063S-y4+R#po~(7>czlzQX-mG7z}Fq$?>pXtsR7Xyb9#FW`5F{> z81_3^ZQk`m^zns+P$5U>(+M2)+Xd9smz!OG?aL}A(sGgKn!^!?T~0Pf3(ERtI2!Jr x>s0Ku`-|rHtG?5oJZ9S(wz|Z%USsMM&-?cbI5r+we(%hj7v;5e3~>^s`T!N@LWBSS literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/04-not.yaml.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/04-not.yaml.i new file mode 100644 index 0000000000000000000000000000000000000000..e27772a77b36efb8807263f45f3d868828221f26 GIT binary patch literal 159 zcmZQzWME`~fOsIa12$8c qr=|AQejkjw*aj($%HT`C{-=^~1H+g*J2I&9{mOYvP literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/_makefile.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/06-combinations/_makefile.i new file mode 100644 index 0000000000000000000000000000000000000000..d24649470dcba7184a2be756ab08dd97a0c185e9 GIT binary patch literal 79 zcmZQzWME`~0Dd6F2W2z-hXTRt>WxxTClCLfEBk_Zfw+0x-@+3xH6XfFPfx$NG$}VR KJ2fpcClvrFU>6hs literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/07-ref/04-ref.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/07-ref/04-ref.test.i new file mode 100644 index 0000000000000000000000000000000000000000..da9c02de37ad8848e56b4e2f1a546261ff08d852 GIT binary patch literal 195 zcmZQzWME`~fMx~;#!x7m;Xf4EsXJMG73h8UX9q{vl&75X?IEJ;VQN5h#hkVMd%2hl zd5*`c9+BRCr*iW8AS)K%jTgi`9~VriF2Bs|E_g(h^FM#xk@7tgh2jqUesGLq+lHXT z%LbvTE2kt1^%*RVd|UP0h)Z^IQRZ>eHxun2<_X@FbD!;!aro|%zKKC*zE4k1t1wPy e?{41Q{MEShr}b6$Q@#85{nobF!|?b?$|eBM{851b literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/07-ref/04-ref.yaml.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/07-ref/04-ref.yaml.i new file mode 100644 index 0000000000000000000000000000000000000000..c524a7b1e8ebd1025f0df09a3fc50ff3ac327b02 GIT binary patch literal 196 zcmZQzWME`~fEES@MlUFv;Xf33Y;ukB5V)-$s$3H4{&qqT!_BwaFf|~$V$Rn7y?hvu+JREtBUp}27Kx4D3&Y`UVhjtbn zSW(qbR$ZXhZJtv1jqj@0W=D~8xusukT^0MaWMjfjv+_y%3eL^edw;dSVMd*5PnwZ< e@z>en8fx4t_5aCVVD;+VzrQTxE91G}aeo1ay-&aZ literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/07-ref/05-inline-addressing.test.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/07-ref/05-inline-addressing.test.i new file mode 100644 index 0000000000000000000000000000000000000000..36a541847a2e03af0078da0ec0c170fbd83f7e17 GIT binary patch literal 278 zcmZQzWME`~fNKm4jHjS%hW}8I7`Hr%dupfFif2#jx9eXtOM13rI!q0Su9!1*!ofTy zLmroURW6Uc3=6*;%P)v|dr+XgcZ$X88y*X;{d=VP7#P#Kx~ILVI4g4u|Tt z51g+yP6`*h(k#&3w0?EYuKoWvWCd;Cl>cGr*>zJqX58*RE}-jS8?^j-#Hp!wPWNnb z(3AYJWxxTClCLfEBk_Zfw+0x-@+3xH6XfFPfx$NG$}VR KJ2fpcClvrFU>6hs literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/_makefile.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/_makefile.i new file mode 100644 index 0000000000000000000000000000000000000000..c004fa138c0f0d4c214c988f435f1f69028b2f75 GIT binary patch literal 167 zcmZQzWME`~fOH_W3d&~q4+RFbEBs#xJ`eX<+!HmeX_7`ssJkFc4T!Fo^VsXm$&HU5 zgYDr$b|toB)7-BUhpqGs20^)yeN@zw`2FZ$|e wd985~Hobb*|CE=no};kYW#4n>eSy+CC(oRBo@{(w*UR_uqen~(*3DWE0J-r(o&W#< literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/_r_e_a_d_m_e.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/_r_e_a_d_m_e.i new file mode 100644 index 0000000000000000000000000000000000000000..51a4e972d9cc5db67b98789bf6ac2038619da8a6 GIT binary patch literal 165 zcmZQzWME`~fK(ur4`nm_hk})Vl4{NGM9mFtP+-)$`}dLV{QNsGH6XfTj_PScz9R}e ztQY46|6sY0vo*Hw(FQe(O^gTq&+VTW)b~X#C#^+`B{E{kTh7>!U4K)8(!{kk|Mq^z xKey)dsbF@G+8H}c47O~SaAG}XzSLPQyE%605$C}5w$I+Z+!_3XdD&m}c>o*2Lsb9( literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/submakefile.i b/src/hos_libvariant/src/.hg/store/data/test/test__schema__data/tv4-tests/submakefile.i new file mode 100644 index 0000000000000000000000000000000000000000..1ba005095ff3a06c8e3a6d8b52273e05f867a372 GIT binary patch literal 215 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 LbmnKxI{6F$wdue3 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/test/test__yaml__parser.cc.i b/src/hos_libvariant/src/.hg/store/data/test/test__yaml__parser.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..73f7ba458f598884f17fa31ea102385d31afdf71 GIT binary patch literal 642 zcmV-|0)71e0RRC20000000Ke)00j5|0000000030|NsC0|NsAU@W*n_o#5+wxC=&p z@c8hUc*kl000000000000001ZoQ+f4Zqq;zeeQn6U>@p3iDL(-DmRTpLMnmUiU)** zD2g`rI9Xxun!SV|)PHBacA`xb5HGgRnVaX#%&6aor-GG8zEG7F*oX@#n$8A8cc+qU=(AxcxtGROp18nO+Q&}Y0hdYOyNRJJJG zLNFW-pLjq5o6@FAVM|Mcj$vFUaSF-!)$2XJP9YW^POdDm8{auxl!EFMzCs)&1BjCG z0Fo%i;TXO-JEuH_$UeL1!Xo?JSLdcm;j*dr=F)Ld6xp}!V=Gt=i(QSG#@wl;!i7~) zqXg{1Z*qar4A+dm>-q|NHwW&4)*Wm@!miK2r(DZNjBDLzEK$+jQisj|m1Xb5`P%n2 z2j}>#b8__;Z!6@9x05vRy18dc`|Vh%J!CcaP%C~%@ccBinMcqY9I(=Pn%W_tWZAOa z(n&7Ns>ErU{xA&n@{vAGzKk>d>o`L@ct1(tR$$NY+#4Xz{Rux4LacaD zQO27A0hQ})&@Fo3g00()_6VVFU$^k(?ZbV`g>!pF8e8zbxs34mKHMyn&4>B2)^g%q z>J+eB$dKbt@GMQt`DG3FA^*%PQJGSo$x1F-({Osn$}(&lay%;_e6f&H$oU4d?_SuU cU0cA7%hXTVT{yteVo3_pu7w_zxX!O{T#i|{q21HlPd91bWjJD^R u4M7@SzW!@99&}yQ)@z^e(?O_3*wIEnnf*xDb1$v4XFMM=F|fr7MgRar`y{sj literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/~2ehgtags.i b/src/hos_libvariant/src/.hg/store/data/~2ehgtags.i new file mode 100644 index 0000000000000000000000000000000000000000..3ec112115ef01f56a1a0ae9a5650abbb809de098 GIT binary patch literal 495 zcmZQzWME`~00SVU4`nm_hXO~Zy{^0$3R0g2_ulq@`P2Mu9OD$28W3HYmSm8cmY8H= zVQP?)Xpoj>U~FJ&m}HWel$dIfYM7LkW|(4dMV5n!HXTSy43$lrU!5N5q!7K&_ zCJ+s>vRd<8{qsXlxC1@l4zNjYGRgZZfIs|YG#-S@x39$_v^r>I0DH%U={-d3y@|4 zSuOVbh~V<$hCee5jPCcXXJIk9>YM{r1E#>f??`S)f_YwXdZ*(g*HtqYx_V7&O_juEe+ER7`Rp9BkSBuH9!U~r)q}?^`AIh{ zli5tZTG+>gpIA6M&lsiA7+~dboLhTz}cGE3FMXekXzvE+29h1uufqJ(ZGi z@axCmt`5Ix8<%gZe5WE~32!m>ZGHc=wWyfiaZs_-=I7fa$RnD~KQkTx-+%A7o6;O4 zQ)jQKxXr>H@qhL!s(ijY{I_(q=qrg+<+3Z|Hw8C{n}CS$kP?y6neSHt-Nb&vFI32O zq0#!#D+SVRh9fACgE7#q5tFoEAr(*o*F!28uM=e4kMe-dO~uUb1>{(T2$ffkgsbxq zCC5JbI%ZN*F+k;OF4J80D!%$Ol~8S2zm}w2)nu>MpE=F4&xwdhuS*?&FZ)8{nZLn( zN94JW^^RPlgamymd;d&h^0vkX?DS`Reos&QgF`Z8H;o zRqXb(Q-TMQ(NC+|T(cfq_VrUW9U2zk;g*EVx5L)jIS(TGS0Kt+(m=WjuDeoh>a-Kz ztYhWBtNkfi7bWxD%vRUo`a;!Gb2>o*_Q{+$*44~zpk8m&*%jGyxK+0INkp1NG|tEz zBB}6sP^oeC9KPxBX&F*X@}Fg)PZWuLy|;|5vn9@kY*wa??vx(2S7Kx z=EI`Pxz9~&YkzF|Swkpc{eKa}uP?!>cK4OY38ZXlt}*jmj|FUw8ksS26>yvQpY3M1 zdEUQ3C#jk7Cv7?^32I*28SZf8-KtXtLQ2!k?#~%3r6R(it9t(O58glKt z9Ec{oE{2@hOQ{Z_rg4a=2C=N#0VlWRj4W|s<$Q+e$O zleVuumHkldBRjxq{E9r`DF=|aI1$&R*cZ2l&vVEw^Scgp9YTETeAag)|2tehz@aZY_Y_86I#o4$# zwzPX{0Nvx>Ko|)Erp_fKdX_ZKW_se@niJB9g1wchMgSF)ok&vXOAPkq6X{r%aGav( z>j_ChLvddD7420+QC`b)e|jA~bb&fW=`uo&m~8+>KAM*NSYnu=ED+ zl>05zFYr{1a~-IC{BO4~^n7lim!7%mP$`HR_h1J$s4m{JF)|8^$I=_Q9Jf=cnL)Eb zr1Z|q;D!gj1h7)-Ma8jT$PBf@=`%GlB+Jy&8?zL*)2VErc_31|f_rR1uJ4f99!nzw zsw^!{?;hT|t=x8*L9@9lmJlzE2wWtOEWC(mwO|(npQ==Wo~3-mbs-jYD3u0$ufdxa`!&@shPpE zS(T0XT?Vbq8lIb7+3!NH!yumFCvWsMX?tZkhR}=(MW=4kMnpvt1^K>?)nTc%fyx}())8ax_ldC-BV)yzBiRQz1I( literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/undo.phaseroots b/src/hos_libvariant/src/.hg/store/undo.phaseroots new file mode 100644 index 00000000..e69de29b diff --git a/src/hos_libvariant/src/.hg/undo.bookmarks b/src/hos_libvariant/src/.hg/undo.bookmarks new file mode 100644 index 00000000..e69de29b diff --git a/src/hos_libvariant/src/.hg/undo.branch b/src/hos_libvariant/src/.hg/undo.branch new file mode 100644 index 00000000..331d858c --- /dev/null +++ b/src/hos_libvariant/src/.hg/undo.branch @@ -0,0 +1 @@ +default \ No newline at end of file diff --git a/src/hos_libvariant/src/.hg/undo.desc b/src/hos_libvariant/src/.hg/undo.desc new file mode 100644 index 00000000..f04ce07e --- /dev/null +++ b/src/hos_libvariant/src/.hg/undo.desc @@ -0,0 +1,3 @@ +0 +pull +https://bitbucket.org/gallen/libvariant diff --git a/src/hos_libvariant/src/.hg/undo.dirstate b/src/hos_libvariant/src/.hg/undo.dirstate new file mode 100644 index 00000000..e69de29b diff --git a/src/hos_libvariant/src/.hgignore b/src/hos_libvariant/src/.hgignore new file mode 100644 index 00000000..1e6ada79 --- /dev/null +++ b/src/hos_libvariant/src/.hgignore @@ -0,0 +1,10 @@ + +syntax: regexp +\.swp +\.swo +\.o +\.a +\.so +\.la +\._ +build diff --git a/src/hos_libvariant/src/.hgtags b/src/hos_libvariant/src/.hgtags new file mode 100644 index 00000000..bedfe9e7 --- /dev/null +++ b/src/hos_libvariant/src/.hgtags @@ -0,0 +1,4 @@ +fb0efab8850da0ff03051b4abae8e1bff1d4ca23 1.0.0 +edb423a0428e6a3744dbf0c4a9ae46e7165561a3 1.0.1 +0000000000000000000000000000000000000000 1.0.1 +40b8e618db81a21c1e363f7c1ee77b2e2c9cc717 1.0.1 diff --git a/src/hos_libvariant/src/CMakeLists.txt b/src/hos_libvariant/src/CMakeLists.txt new file mode 100644 index 00000000..a9ba68d9 --- /dev/null +++ b/src/hos_libvariant/src/CMakeLists.txt @@ -0,0 +1,244 @@ +project(LibVariant) + +cmake_minimum_required(VERSION 2.6) + +enable_testing() + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/") + +include(CheckCXXSourceCompiles) +include(CheckIncludeFileCXX) + +if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) + set(EXAMPLES_AND_TESTS on) + set(LIBVARIANT_DOC_TARGET doc) + option(BUILD_SHARED_LIBS "Build shared libraries." OFF) +else() + set(EXAMPLES_AND_TESTS off) + set(LIBVARIANT_DOC_TARGET libvariant-doc) +endif() + +option(LIBVARIANT_BUILD_WALL "build Variant with the -Wall flag" ON) +option(LIBVARIANT_BUILD_DEBUG "build Variant with the additional debug flags" OFF) +option(LIBVARIANT_BUILD_TESTS "build the Variant tests" ${EXAMPLES_AND_TESTS}) +option(LIBVARIANT_BUILD_EXAMPLES "build the Variant examples" ${EXAMPLES_AND_TESTS}) +option(LIBVARIANT_BUILD_PROFILE "build Variant with profiling flags" OFF) +option(LIBVARIANT_ENABLE_YAML "Enable YAML encoding" ON) +option(LIBVARIANT_ENABLE_XML "Enable XML encoding" ON) +option(LIBVARIANT_ENABLE_MSGPACK "Enable msgpack encoding" OFF) +option(LIBVARIANT_ENABLE_CURL "Enable cURL related functionality in the SchemaLoader" ON) + +set(LIBVARIANT_MAJOR_VERSION 1) +set(LIBVARIANT_MINOR_VERSION 0) +set(LIBVARIANT_PATCH_VERSION 1) +set(LIBVARIANT_VERSION + ${LIBVARIANT_MAJOR_VERSION}.${LIBVARIANT_MINOR_VERSION}.${LIBVARIANT_PATCH_VERSION}) + +# Offer the user the choice of overriding the installation directories +set(INSTALL_LIB_DIR lib CACHE STRING "Installation directory for libraries") +set(INSTALL_BIN_DIR bin CACHE STRING "Installation directory for executables") +set(INSTALL_INCLUDE_DIR include CACHE STRING "Installation directory for header files") + +set(DEF_INSTALL_CMAKE_DIR "${INSTALL_LIB_DIR}/cmake/LibVariant") +set(INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE STRING + "Installation directory for CMake files") + +# Make relative paths absolute (needed later on) +foreach(p LIB BIN INCLUDE CMAKE) + set(var INSTALL_${p}_DIR) + if(NOT IS_ABSOLUTE "${${var}}") + set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") + endif() +endforeach() + +if(LIBVARIANT_BUILD_WALL) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") +endif() + +if (LIBVARIANT_BUILD_DEBUG) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Winline -Wfatal-errors") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Winline -Wfatal-errors") +endif() + +if (LIBVARIANT_BUILD_PROFILE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fprofile-arcs -ftest-coverage") +endif() + +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DENABLE_STACKTRACE") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DENABLE_STACKTRACE") + +# setup include directories +include_directories("include") +include_directories("${CMAKE_CURRENT_BINARY_DIR}/include") + +# libraries to depends upon +if(LIBVARIANT_ENABLE_XML) + find_package(LibXml2) + if(LIBXML2_FOUND) + include_directories(${LIBXML2_INCLUDE_DIR}) + add_definitions(${LIBXML2_DEFINITIONS}) + add_definitions("-DENABLE_XML") + list(APPEND EXTRA_LIBS ${LIBXML2_LIBRARIES}) + else() + message(WARNING " Could not find libxml2, disabling.") + set(LIBVARIANT_ENABLE_XML OFF) + endif() +endif() + +if(LIBVARIANT_ENABLE_YAML) + find_package(LibYAML) + if(LIBYAML_FOUND) + include_directories(${LIBYAML_INCLUDE_DIR}) + add_definitions("-DENABLE_YAML") + list(APPEND EXTRA_LIBS ${LIBYAML_LIBRARIES}) + else() + message(WARNING " Could not find libyaml, disabling.") + set(LIBVARIANT_ENABLE_YAML OFF) + endif() +endif() + +if(LIBVARIANT_ENABLE_MSGPACK) + find_package(MsgPack) + if(MSGPACK_FOUND) + include_directories(${MSGPACK_INCLUDE_DIR}) + add_definitions("-DENABLE_MSGPACK") + list(APPEND EXTRA_LIBS ${MSGPACK_LIBRARIES}) + else() + message(WARNING " Could not find msgpack, disabling") + set(LIBVARIANT_ENABLE_MSGPACK OFF) + endif() +endif() + +if (LIBVARIANT_ENABLE_CURL) + find_package(CURL) + if (CURL_FOUND) + include_directories(${CURL_INCLUDE_DIR}) + add_definitions("-DENABLE_CURL") + list(APPEND EXTRA_LIBS ${CURL_LIBRARIES}) + else() + message(INFO " CURL not found, disabling CURL functionality.") + set(LIBVARIANT_ENABLE_CURL OFF) + endif() +endif() + +# We want to following checks to try compiling with the same flags that we +# have already setup +set(CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS}) + +check_cxx_source_compiles( " +\#include \n +int main() { + std::shared_ptr i; + return 0; +} +" + HAVE_CXX11_SHAREDPTR ) + +if (NOT HAVE_CXX11_SHAREDPTR) + check_include_file_cxx("tr1/memory" HAVE_TR1_SHAREDPTR) + + if (NOT HAVE_TR1_SHAREDPTR) + message(STATUS "Fallback to using boost shared_ptr") + find_package(Boost REQUIRED) + include_directories(${Boost_INCLUDE_DIRS}) + set(USE_BOOST_SHAREDPTR 1) + endif() +endif() + +check_cxx_source_compiles(" +int main() { + long long i = 0; + unsigned long long u = 0; + return i + u; +} +" + HAVE_LONG_LONG) + +if (HAVE_LONG_LONG) + add_definitions("-DHAVE_LONG_LONG=1") +endif() + +# add sub directories +add_subdirectory(src) +if (LIBVARIANT_BUILD_TESTS) + add_subdirectory(test) +endif() +if (LIBVARIANT_BUILD_EXAMPLES) + add_subdirectory(examples) +endif() + + +# Build documentation +find_package(Doxygen) +if (DOXYGEN_FOUND) + configure_file(Doxyfile.in ${PROJECT_BINARY_DIR}/Doxyfile @ONLY IMMEDIATE) + add_custom_target(${LIBVARIANT_DOC_TARGET} + COMMAND ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/Doxyfile + SOURCES ${PROJECT_BINARY_DIR}/Doxyfile) +endif() + + +# Add targets to the build-tree export set +set(LIBVARIANT_EXPORTED_LIBS Variant) + +export(TARGETS ${LIBVARIANT_EXPORTED_LIBS} + FILE "${PROJECT_BINARY_DIR}/LibVariantLibraryDepends.cmake") + +# Export the package for use from the build-tree +# (this registers the build-tree with a global CMake-registry) +#export(PACKAGE LibVariant) # NOT IMPLEMENTED IN cmake 2.6 on RHEL6 + + +# Create a LibVariantBuildTreeSettings.cmake file for the use from the build tree +configure_file(LibVariantBuildTreeSettings.cmake.in + "${PROJECT_BINARY_DIR}/LibVariantBuildTreeSettings.cmake" @ONLY) + +# Create the LibVariantConfig.cmake and LibVariantConfigVersion files +file(RELATIVE_PATH CONF_REL_INCLUDE_DIR "${INSTALL_CMAKE_DIR}" + "${INSTALL_INCLUDE_DIR}") +configure_file(LibVariantConfig.cmake.in + "${PROJECT_BINARY_DIR}/LibVariantConfig.cmake" @ONLY) +configure_file(LibVariantConfigVersion.cmake.in + "${PROJECT_BINARY_DIR}/LibVariantConfigVersion.cmake" @ONLY) + +install(FILES + "${PROJECT_BINARY_DIR}/LibVariantConfig.cmake" + "${PROJECT_BINARY_DIR}/LibVariantConfigVersion.cmake" + DESTINATION "${INSTALL_CMAKE_DIR}") + +# Install the export set for use with the install-tree +install(EXPORT LibVariantLibraryDepends + DESTINATION "${INSTALL_CMAKE_DIR}" + COMPONENT dev) + +# Create the package config file +configure_file(libvariant.pc.in + "${PROJECT_BINARY_DIR}/libvariant.pc" @ONLY) + +install(FILES + "${PROJECT_BINARY_DIR}/libvariant.pc" + DESTINATION "${INSTALL_LIB_DIR}/pkgconfig") + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/include/Variant/Config.h) + +FILE(GLOB install_headers RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + include/Variant/*.h) +install(FILES ${install_headers} DESTINATION ${INSTALL_INCLUDE_DIR}/Variant/) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/Variant/Config.h DESTINATION + ${INSTALL_INCLUDE_DIR}/Variant/) + +# Am I the root CMakeLists.txt? +if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) + include(MakeTBZ2) + add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source) +else() + # set parent variables as if it used find_package(testlib2) + set(LIBVARIANT_LIBRARIES Variant PARENT_SCOPE) + get_directory_property(LIBVARIANT_INCLUDE_DIRS INCLUDE_DIRECTORIES) + set(LIBVARIANT_INCLUDE_DIRS ${LIBVARIANT_INCLUDE_DIRS} PARENT_SCOPE) + set(LIBVARIANT_FOUND TRUE PARENT_SCOPE) +endif() diff --git a/src/hos_libvariant/src/Config.h.in b/src/hos_libvariant/src/Config.h.in new file mode 100644 index 00000000..37ff2e74 --- /dev/null +++ b/src/hos_libvariant/src/Config.h.in @@ -0,0 +1,13 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_CONFIG_H +#define VARIANT_CONFIG_H +#pragma once + +#cmakedefine HAVE_CXX11_SHAREDPTR 1 +#cmakedefine HAVE_TR1_SHAREDPTR 1 +#cmakedefine USE_BOOST_SHAREDPTR 1 + +#endif diff --git a/src/hos_libvariant/src/Doxyfile.in b/src/hos_libvariant/src/Doxyfile.in new file mode 100644 index 00000000..82dfd8ac --- /dev/null +++ b/src/hos_libvariant/src/Doxyfile.in @@ -0,0 +1,1569 @@ +# Doxyfile 1.6.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = libvariant + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @VARIANT_VERSION@ + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = @PROJECT_BINARY_DIR@/doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = @PROJECT_SOURCE_DIR@/src \ + @PROJECT_SOURCE_DIR@/include + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = @PROJECT_SOURCE_DIR@/include + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. Note that for custom extensions you also need to set +# FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = YES + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @PROJECT_SOURCE_DIR@/src +INPUT += @PROJECT_SOURCE_DIR@/include +INPUT += @PROJECT_SOURCE_DIR@/README.md + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# If the HTML_TIMESTAMP tag is set to YES then the generated HTML +# documentation will contain the timesstamp. + +HTML_TIMESTAMP = NO + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# When the SEARCHENGINE tag is enable doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) +# there is already a search function so this one should typically +# be disabled. + +SEARCHENGINE = YES + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +MARKDOWN_SUPPORT = YES + +USE_MDFILE_AS_MAINPAGE = README.md diff --git a/src/hos_libvariant/src/LICENSE b/src/hos_libvariant/src/LICENSE new file mode 100644 index 00000000..2fda3ee9 --- /dev/null +++ b/src/hos_libvariant/src/LICENSE @@ -0,0 +1,16 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= diff --git a/src/hos_libvariant/src/LibVariantBuildTreeSettings.cmake.in b/src/hos_libvariant/src/LibVariantBuildTreeSettings.cmake.in new file mode 100644 index 00000000..06629e75 --- /dev/null +++ b/src/hos_libvariant/src/LibVariantBuildTreeSettings.cmake.in @@ -0,0 +1,3 @@ + +set(LIBVARIANT_INCLUDE_DIRS + "@PROJECT_SOURCE_DIR@/include") diff --git a/src/hos_libvariant/src/LibVariantConfig.cmake.in b/src/hos_libvariant/src/LibVariantConfig.cmake.in new file mode 100644 index 00000000..e2383699 --- /dev/null +++ b/src/hos_libvariant/src/LibVariantConfig.cmake.in @@ -0,0 +1,25 @@ + +# - Config file for the Variant package +# It defines the following variables +# LIBVARIANT_INCLUDE_DIRS - include directories for Variant +# LIBVARIANT_LIBRARIES - libraries to link against +# LIBVARIANT_FOUND - library has been found + +# Compute paths +get_filename_component(LIBVARIANT_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +if(EXISTS "${LIBVARIANT_CMAKE_DIR}/CMakeCache.txt") + # In build tree + include("${LIBVARIANT_CMAKE_DIR}/LibVariantBuildTreeSettings.cmake") +else() + set(LIBVARIANT_INCLUDE_DIRS "${LIBVARIANT_CMAKE_DIR}/@CONF_REL_INCLUDE_DIR@") +endif() + +# Our library dependencies (contains defninitinos for IMPORTED targets) +include("${LIBVARIANT_CMAKE_DIR}/LibVariantLibraryDepends.cmake") + +# These are IMPORTANT targets created by VariantLibraryDepends.cmake +set(LIBVARIANT_LIBRARIES Variant) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibVariant DEFAULT_MSG + LIBVARIANT_LIBRARIES LIBVARIANT_INCLUDE_DIRS) diff --git a/src/hos_libvariant/src/LibVariantConfigVersion.cmake.in b/src/hos_libvariant/src/LibVariantConfigVersion.cmake.in new file mode 100644 index 00000000..ca388800 --- /dev/null +++ b/src/hos_libvariant/src/LibVariantConfigVersion.cmake.in @@ -0,0 +1,12 @@ + +set(PACKAGE_VERSION "@LIBVARIANT_VERSION@") + +# Check whether the requested PACKAGE_FIND_VERSION is compatible +if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/src/hos_libvariant/src/README.md b/src/hos_libvariant/src/README.md new file mode 100644 index 00000000..05c8da1d --- /dev/null +++ b/src/hos_libvariant/src/README.md @@ -0,0 +1,126 @@ + +Introduction +------------ + +This library, libvariant, provides a class called Variant. +This class is a discriminating union that can contain one of the following values: + + - a null, or no type + - a boolean value + - an unsigned integer + - a signed integer + - a floating point value + - a string value + - a reference to a map of string to Variant + - a reference to a list of Variant + - a reference to a iovec list (Blob) + +### Features + + - Scripting language like variable (Variant) in C++ (with all the upsides and downsides that implies). + - [JSON](http://www.json.org/) serialization. + - [YAML](http://yaml.org/) serialization. Deserialization ignores most tags. + - plist serialization. + - Schema validation based on [json-schema](http://json-schema.org/). + - Schema lookup can be set to use libcurl to fetch remote URLs. + - A simple argument parsing (ArgParse) class that produces a Variant from a programs arguments. + - Experimental [msgpack](http://msgpack.org/) serialization using [msgpack-c](https://github.com/msgpack/msgpack-c) (disabled by default). + - JSONPointer (RFC6901) and JSONPatch (RFC6902) implementations. + +### Changes for the 1.0.1 release + + - Cleaned up static data initialization, will no long call abort. + - Fixed a bug related to proxy resolution when performing additional path resolution. + - Added an ignore_payload and payload_length parameter to the payload serializer helpers. + - Implemented proper JSONPointer lookup routines and changed the schema lookup to use them. + - Modified ArgParse so that positional argument can be specified in loaded configuration files. + - Added a make dist build target. + - Other minor fixes. + +### Implementation details + +Under the hood, Variant uses an explicit vtable to implement the different +behaviors with the same interface. The vtable has more types than the standard +types listed above. The additional types are a reference and proxy type. +There is also a class that is exposed to the user as VariantRef. Several of +the functions that return a Variant return a VariantRef. A VariantRef is a +Variant so const Variant & can bind to a VariantRef. But, in general Variant& +cannot bind to VariantRef as all functions that return VariantRef, return it by +value. This means that if you want a function that takes a non-const Variant as +a parameter to be used as an output parameter, the function must take a +VariantRef by value. VariantRef can be constructed from a Variant as well, so +such a function can take either a VariantRef or Variant. + +libvariant is [publicly hosted here](https://bitbucket.org/gallen/libvariant). + +Building +-------- + +This project uses CMake to generate a build system. Consult the CMake +documentation for your preferred build system generation. + +### Building on unix + +The default build system generated by CMake on unix is to use make. +To build with make simply perform the following commands where you would like the build output: + + cmake /path/to/libvariant/sources/ + make + +And to install: + make install + +The cmake configuration files use the standard cmake variables. + +### Dependencies + +libvariant is optionally dependent on the following libraries + + - [libyaml](http://pyyaml.org/wiki/LibYAML) to provide yaml serialization + - [libxml2](http://xmlsoft.org/) to provide plist serialization + - [libcurl](http://curl.haxx.se/) to provide schema web lookup + - [msgpack-c](https://github.com/msgpack/msgpack-c) for the experimental msgpack serialization + +CMake variables are provided to override the default dependency behavior. + +Schemas +------- + +This library also contains a schema validator. The language of the schema when +serialized as JSON is json-schema. See json-schema.org for details about +json-schema. Note the validator in this library uses the version 4 dialect. +The schema for the version 4 dialect can be acquired from +http://json-schema.org/draft-04/schema + +Other than a validator, there is a function to add the schema defaults to a Variant. +This function goes through the schema and attempts to add the defaults +specified in it to the Variant provided if a value is not already present. +There are several constructs that it ignores such as not. + +### Data generation from schemas + +Generating a valid set of data from schema is an interesting idea, and can be +useful for testing purposes. But this problem is rather difficult in general. +For example, the anyOf, oneOf, allOf, and not constructs in a schema mean that +it is possible that the data generator must solve a satisfiability problem. +It is well known that non-trivial satisfiability problems are NP complete. +Despite this there does exists several random data generators (but they can +fail to produce output or can produce output that does not validate). The +following are links to two of the generators I was able to find. + + - [http://schematic-ipsum.herokuapp.com/] - a web app + - [https://github.com/andreineculau/json-schema-random] - requires nodejs + +API Documentation +----------------- + +The main API is documented in the source code using the Doxygen format. +The generated html documentation is served on the web at +http://gallen.bitbucket.org/libvariant-docs. + +If you have doxygen installed, you can generate html documentation of the +libvariant public interface from the source code with: + + cd /path/to/build_dir + cmake /path/to/libvariant + make doc diff --git a/src/hos_libvariant/src/cmake/Modules/FindLibYAML.cmake b/src/hos_libvariant/src/cmake/Modules/FindLibYAML.cmake new file mode 100644 index 00000000..26ce0ef2 --- /dev/null +++ b/src/hos_libvariant/src/cmake/Modules/FindLibYAML.cmake @@ -0,0 +1,18 @@ +# CMake module to search for the libyaml library +# (library for parsing YAML files) +# If it's found it sets LIBYAML_FOUND to TRUE +# and following variables are set: +# LIBYAML_INCLUDE_DIR +# LIBYAML_LIBRARY + +find_package(PkgConfig) +pkg_check_modules(PC_LIBYAML yaml-0.1) + +find_path(LIBYAML_INCLUDE_DIR NAMES yaml.h HINTS ${PC_LIBYAML_INCLUDEDIR} + ${PC_LIBYAML_INCLUDE_DIRS}) +find_library(LIBYAML_LIBRARIES NAMES yaml libyaml + HINTS ${PC_LIBYAML_LIBDIR} ${PC_LIBYAML_LIBRARY_DIR}) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibYAML DEFAULT_MSG LIBYAML_LIBRARIES LIBYAML_INCLUDE_DIR) +MARK_AS_ADVANCED(LIBYAML_INCLUDE_DIR LIBYAML_LIBRARIES) diff --git a/src/hos_libvariant/src/cmake/Modules/FindMsgPack.cmake b/src/hos_libvariant/src/cmake/Modules/FindMsgPack.cmake new file mode 100644 index 00000000..37871bdd --- /dev/null +++ b/src/hos_libvariant/src/cmake/Modules/FindMsgPack.cmake @@ -0,0 +1,17 @@ +# - Find msgpack +# Find the native Message Pack headers and libraries. +# +# MSGPACK_INCLUDE_DIRS - where to find msgpack.hpp, etc. +# MSGPACK_LIBRARIES - List of libraries when using MsgPack. +# MSGPACK_FOUND - True if MsgPack found. + + +# Look for the header file. +FIND_PATH(MSGPACK_INCLUDE_DIR NAMES msgpack.hpp) + +# Look for the library. +FIND_LIBRARY(MSGPACK_LIBRARY NAMES msgpack libmsgpack) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(MsgPack DEFAULT_MSG MSGPACK_LIBRARY MSGPACK_INCLUDE_DIR) +MARK_AS_ADVANCED(MSGPACK_INCLUDE_DIR MSGPACK_LIBRARY) diff --git a/src/hos_libvariant/src/cmake/Modules/MakeTBZ2.cmake b/src/hos_libvariant/src/cmake/Modules/MakeTBZ2.cmake new file mode 100644 index 00000000..ec160f9e --- /dev/null +++ b/src/hos_libvariant/src/cmake/Modules/MakeTBZ2.cmake @@ -0,0 +1,13 @@ +foreach(what MAJOR MINOR PATCH) + set(ivar ${PROJECT_NAME}_${what}_VERSION) + string(TOUPPER ${ivar} ivar) + set(CPACK_PACKAGE_VERSION_${what} ${${ivar}}) +endforeach() + +set(CPACK_SOURCE_GENERATOR "TBZ2") +set(CPACK_SOURCE_PACKAGE_FILE_NAME + "${PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") +string(TOLOWER ${CPACK_SOURCE_PACKAGE_FILE_NAME} CPACK_SOURCE_PACKAGE_FILE_NAME) +set(CPACK_SOURCE_IGNORE_FILES + "/build*/;/.hg*;~$;CMakeCache.txt;${CPACK_SOURCE_IGNORE_FILES}") +include(CPack) diff --git a/src/hos_libvariant/src/examples/CMakeLists.txt b/src/hos_libvariant/src/examples/CMakeLists.txt new file mode 100644 index 00000000..706bc685 --- /dev/null +++ b/src/hos_libvariant/src/examples/CMakeLists.txt @@ -0,0 +1,21 @@ + +add_executable(convert convert.cc) +target_link_libraries(convert Variant ${EXTRA_LIBS}) + +add_executable(example1 example1.cc) +target_link_libraries(example1 Variant ${EXTRA_LIBS}) + +add_executable(example2 example2.cc) +target_link_libraries(example2 Variant ${EXTRA_LIBS}) + +add_executable(map_example map_example.cc) +target_link_libraries(map_example Variant ${EXTRA_LIBS}) + +add_executable(list_example list_example.cc) +target_link_libraries(list_example Variant ${EXTRA_LIBS}) + +add_executable(pretty_print pretty_print.cc) +target_link_libraries(pretty_print Variant ${EXTRA_LIBS}) + +add_executable(arg_parse arg_parse.cc) +target_link_libraries(arg_parse Variant ${EXTRA_LIBS}) diff --git a/src/hos_libvariant/src/examples/README b/src/hos_libvariant/src/examples/README new file mode 100644 index 00000000..35bf4a31 --- /dev/null +++ b/src/hos_libvariant/src/examples/README @@ -0,0 +1,23 @@ + +convert.cc: + +This example is for a program to convert between different serialization +formats. It can load JSON, YAML or plist and then save it as any of those +formats. + +example1.cc: + +A quick example of how to load YAML and JSON with the convenience interface. + +example2.cc: + +Shows some basic ways of querying for information from a Variant. + +map_example.cc: + +Shows some basic operations that you can perform on the map types. + +pretty_print.cc: + +Shows some basic examples of how to pretty print a Variant into JSON and YAML +in several different formats. diff --git a/src/hos_libvariant/src/examples/arg_parse.cc b/src/hos_libvariant/src/examples/arg_parse.cc new file mode 100644 index 00000000..abe36849 --- /dev/null +++ b/src/hos_libvariant/src/examples/arg_parse.cc @@ -0,0 +1,101 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include +#include "../../src/include/Variant/ArgParse.h" +#include "../../src/include/Variant/Schema.h" +#include "../../src/include/Variant/Variant.h" + +using namespace libvariant; +using namespace std; + +void MoreOptions(ArgParse &opts) { + opts.AddOption("/abc/a", 0, "abc-a", "libabc a").Default("a"); + opts.AddOption("/abc/b", 0, "abc-b", "libabc b").Default("b"); + opts.AddOption("/abc/c", 0, "abc-c", "libabc c"); + opts.AddGroup("abc", "libabc", "Options for libabc").Add("/abc/a").Add("/abc/b") + .Add("/abc/c"); + opts.AddGroup("abc-exclusive").Add("/abc/b").Add("/abc/c").MutuallyExclusive(); +} + +int main(int argc, char **argv) { + + SerializeType stype = SERIALIZE_JSON; + Variant params = Variant().Set("pretty", true); + + ArgParse opts(argv[0]); + + opts.SetDescription("An example application that uses ArgParse."); + opts.SetEpilog("An epilog of the help text!"); + opts.AddConfigDefaults(); + + opts.AddOption("foo-key", 'f', "foo", "What to foo with.").Action(ARGACTION_APPEND) + .Type(ARGTYPE_FLOAT).Default(0.1234).Minimum(0); + // Defines an option --foo or -f that takes a number argument, which is 0.1234 + // if not specified and has a minimum value of 0 + + opts.AddOption("bar-key", 'b', "bar", "The bar.") + .Default("frobnar!").MaxLength(100).Pattern("[A-Za-z]*!") + .Env("BAR"); + // Defines an option --bar or -b that takes a string argument that + // may be any alphastring ending in an ! up to 100 characters in length. + + opts.AddOption("blurt-key", 0, "blurt", "BLURT!") + .AddChoice("furble").AddChoice("murble").AddChoice("durble") + .Default("durble"); + // Defines an option --blurt that can take the string values + // 'furble', 'murble', or 'durble' and will error on any other. + + opts.AddFlag("recursive", 'r', "recurse", "Do operation recursively"); + // Add an option -r that sets true if present and false if not + // Same as opts.AddOption("recursive, 'r', "recurse", "Do operation recursively") + // .Action(ARGACTION_STORE_TRUE).Type(ARGTYPE_BOOL).Default(false); + + opts.AddOption("verbose", 'v', "verbose", "Increase verbosity one level.") + .Action(ARGACTION_COUNT); + + opts.AddOption("quiet", 'q', "quiet", "Decrease verbosity one level.") + .Action(ARGACTION_COUNT); + + MoreOptions(opts); + + opts.AddArgument("host", "Hostname").Type(ARGTYPE_STRING).Action(ARGACTION_STORE); + opts.AddArgument("port", "Port number or name").Type(ARGTYPE_STRING).Action(ARGACTION_STORE); + opts.AddArgument("XXX", "Message IDs").Type(ARGTYPE_INT).Action(ARGACTION_APPEND) + .Minimum(0).MinArgs(1).MaxArgs(0); + // Define that the program takes at least 3 positional arguments, + // the first being a string which will be stored in host, a port name + // which will be a string stored in port and a list of positive integers + // which will be stored as a list in key XXX. + + // An example for a single positional optional argument (can have no + // required arguments after it): + // opts.AddArgument("msgid", "Message ID").Type(ARGTYPE_INT).Default(10) + // .Minimum(0).MinArgs(0); + + cout << "The description:\n"; + Serialize(cout.rdbuf(), opts.GetDescription(), stype, params); + cout << endl; + cout << "The generated schema for the parsed arguments:\n"; + Variant schema = opts.GenerateSchema(); + Serialize(cout.rdbuf(), schema, stype, params); + cout << endl; + + opts.Validate(); + cout << "Now parsing the arguments..." << endl; + Variant args = opts.Parse(argc, argv); + + int verbosity = 1 + args.Get("verbose", 0).As() - args.Get("quiet", 0).As(); + + cout << "Using verbosity " << verbosity << endl; + + cout << "The parsed arguments then look like:\n"; + Serialize(cout.rdbuf(), args, stype, params); + cout << endl; + SchemaResult validate_result = SchemaValidate(schema, args); + cout << "Does it validate? " << (validate_result.Error() ? "no" : "yes") << endl; + if (validate_result.Error()) { cout << validate_result << endl; } + return 0; +} diff --git a/src/hos_libvariant/src/examples/convert.cc b/src/hos_libvariant/src/examples/convert.cc new file mode 100644 index 00000000..5dfd9180 --- /dev/null +++ b/src/hos_libvariant/src/examples/convert.cc @@ -0,0 +1,99 @@ +/** \file + * \author John Bridgman + * \brief A simple convert utility that can read in + * the json, yaml or xml formats and then write out + * any of those formats. + */ +#include +#include +#include +#include "../../src/include/Variant/Variant.h" + +using namespace libvariant; + +int main(int argc, char **argv) { + enum Op { + NOOP, + JSON, YAML, XML + }; + SerializeType input = SERIALIZE_YAML; + SerializeType output = SERIALIZE_YAML; + Variant params = Variant::MapType; + params["pretty"] = true; + while (true) { + int c = getopt(argc, argv, "jyxJYXhp:"); + if (c == -1) { break; } + switch (c) { + case 'j': + input = SERIALIZE_JSON; + break; + case 'y': + input = SERIALIZE_YAML; + break; + case 'x': + input = SERIALIZE_XMLPLIST; + break; + case 'J': + output = SERIALIZE_JSON; + break; + case 'Y': + output = SERIALIZE_YAML; + break; + case 'X': + output = SERIALIZE_XMLPLIST; + break; + case 'p': + params["pretty"] = Variant(optarg).AsBool(); + break; + case 'h': + default: + printf("Usage: %s [options] infile outfile\n", *argv); + printf("Options:\n" + "\t-j|-y|-x Specify the input format, JSON, YAML or XML plist\n" + "\t-J|-Y|-X Specify the output format, JSON, YAML or XML plist\n" + "\t-p true|false Set pretty printing (default true)\n" + "Leaving out the input or putput file or specifying it as -\n" + "will use stdin or stdout instead.\n"); + return 0; + } + } + + FILE *in = stdin; + const char *in_file = 0; + if (optind < argc) { + in_file = argv[optind]; + if (strlen(in_file) == 1 && in_file[0] == '-') { + in_file = 0; + } + } + if (in_file) { + in = fopen(in_file, "r"); + if (!in) { + fprintf(stderr, "Unable to open %s\n", in_file); + return 1; + } + } + FILE *out = stdout; + const char *out_file = 0; + if (optind + 1 < argc) { + out_file = argv[optind + 1]; + if (strlen(out_file) == 1 && out_file[0] == '-') { + out_file = 0; + } + } + if (out_file) { + out = fopen(in_file, "w"); + if (!out) { + fprintf(stderr, "Unable to open %s\n", out_file); + return 1; + } + } + + Variant v; + v = DeserializeFile(in, input); + + Serialize(out, v, output, params); + + return 0; +} + diff --git a/src/hos_libvariant/src/examples/example1.cc b/src/hos_libvariant/src/examples/example1.cc new file mode 100644 index 00000000..d0c2dee2 --- /dev/null +++ b/src/hos_libvariant/src/examples/example1.cc @@ -0,0 +1,37 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include +#include "../../src/include/Variant/Variant.h" + +// Import Variant from libvariant +using libvariant::Variant; + +// Example strings to use +const char *example_json_string = +"{\"key1\": \"value1\",\"key2\":1.23,\"list\":[1,2,3,4]}"; + +const char *example_yaml_string = +"key1: value1\n" +"key2: 1.23\n" +"list: [ 1, 2, 3, 4]\n" +; + +int main(int argc, char **argv) { + // Load the example_json_string onto ex1 + Variant ex1 = libvariant::DeserializeJSON(example_json_string); + // Load the example yaml string + Variant ex2 = libvariant::DeserializeYAML(example_yaml_string); + // They are the same + if (ex1 != ex2) { + printf("Differ!\n"); + return 1; + } + + // Pretty print to stdout + libvariant::SerializeJSON(stdout, ex2, true); + + return 0; +} diff --git a/src/hos_libvariant/src/examples/example2.cc b/src/hos_libvariant/src/examples/example2.cc new file mode 100644 index 00000000..629349b9 --- /dev/null +++ b/src/hos_libvariant/src/examples/example2.cc @@ -0,0 +1,50 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include +#include "../../src/include/Variant/Variant.h" + +using libvariant::Variant; + +int main(int argc, char **argv) { + if (argc != 2) { + printf("Usage: %s input_file\n", *argv); + return 1; + } + const char *file_name = argv[1]; + Variant v = libvariant::DeserializeYAMLFile(file_name); + + // Now lets examine the variant + if (v.IsMap()) { + printf("The variant is a map of length %u with keys:\n", v.Size()); + bool contains_complex_type = false; + // Maps are internally just std::map + for (Variant::MapIterator i(v.MapBegin()), e(v.MapEnd()); i!=e; ++i) { + printf("\"%s\" ", i->first.c_str()); + switch (i->second.GetType()) { + case Variant::MapType: + case Variant::ListType: + contains_complex_type = true; + break; + default: + break; + } + } + printf("\n"); + if (contains_complex_type) { + printf("The map contains non scalar types.\n"); + } + } else if (v.IsList()) { + printf("The variant is a list of length %u\n", v.Size()); + // Lists are also internally std::vector + // Can use v.ListBegin and v.ListEnd for iterators + // and Variant::ListIterator for the iterator type + } else { + printf("The read in variant is neither a list nor a map.\nIts string value is: %s\n", v.AsString().c_str()); + } + + + return 0; +} diff --git a/src/hos_libvariant/src/examples/list_example.cc b/src/hos_libvariant/src/examples/list_example.cc new file mode 100644 index 00000000..52831ddd --- /dev/null +++ b/src/hos_libvariant/src/examples/list_example.cc @@ -0,0 +1,29 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include + +#include "../../src/include/Variant/Variant.h" +using libvariant::Variant; + +int main(int argc, char **argv) { + Variant list; + // Can assign the type to a variant to "force" it to be + // that type. The type will loose any value it had (i.e., + // a list will be empty, maps will be empty, numbers will have + // an indeterminate value, etc.) + list = Variant::ListType; + list[0] = true; + list[2] = "abc"; + // Note that now the list is [true, null, "abc"] + // Lists are extended automatically to the length that they are referred to. + list.Append(123); + // Appending to the list + + for (unsigned i = 0; i < list.Size(); ++i) { + std::cout << list[i].AsString() << std::endl; + } + return 0; +} + diff --git a/src/hos_libvariant/src/examples/map_example.cc b/src/hos_libvariant/src/examples/map_example.cc new file mode 100644 index 00000000..dabe886a --- /dev/null +++ b/src/hos_libvariant/src/examples/map_example.cc @@ -0,0 +1,48 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include +#include + +#include "../../src/include/Variant/Variant.h" +using libvariant::Variant; + +int main(int argc, char **argv) { + Variant map; + // The type of a Variant with the default constructor is the NullType + assert(map.IsNull()); + // Treating a NullType as some type converts it to that type + map["key"] = "value"; + map["doo"] = 1.2345; + map["bar"] = 123; + map["foo"] = true; + Variant map2; + map2["ubar"] = 12u; + + map.Merge(map2); + // Set all the key value pairs in map2 into map. + + + if (map.Contains("doo")) { + // the key "doo" is in the map + } + + Variant doodaa = map.Get("doodaa", true); + // Get checks if doodaa is in the map and if not it returns the second + // parameter. + assert(doodaa.IsTrue()); + + Variant val = map["blah"]; + // "blah" was not in the map so val is of NullType + // But "blah" has been added to the map as NullType because Variant can't + // tell if your assigning or referencing with the [] operator + assert(val.IsNull()); + // But then we can erase it + map.Erase("blah"); + + for (Variant::MapIterator i(map.MapBegin()), e(map.MapEnd()); i!=e; ++i) { + std::cout << i->first << ": " << i->second.AsString() << std::endl; + } + return 0; +} diff --git a/src/hos_libvariant/src/examples/pretty_print.cc b/src/hos_libvariant/src/examples/pretty_print.cc new file mode 100644 index 00000000..2bb04755 --- /dev/null +++ b/src/hos_libvariant/src/examples/pretty_print.cc @@ -0,0 +1,40 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include +#include +#include "../../src/include/Variant/Variant.h" + +using namespace libvariant; + +const char example_string[] = "--- { id: [ 1,2 ,3, 4], names: [ foo, bar, gar, mar ], twiddle: true, swizzle: 1.24456e-4," +" subs: [1, 2, [ 1, 2, [ {a: b}, 2 ]]] }"; + +const char styles[] = "any\0block\0flow\0"; + +int main(int argc, char **argv) { + Variant val = Deserialize(example_string, SERIALIZE_YAML); + std::cout << "--- Pretty printing JSON to stdout using generic serialize function\n"; + Variant param; + param["pretty"] = true; + param["indent"] = 2; + Serialize(std::cout.rdbuf(), val, SERIALIZE_JSON, param); + std::cout << std::endl; + param.Clear(); + //param["width"] = 10; + for (const char *mstyle = &styles[0];*mstyle; mstyle += strlen(mstyle) + 1) { + for (const char *lstyle = &styles[0];*lstyle; lstyle += strlen(lstyle) + 1) { + param["map_style"] = mstyle; + param["list_style"] = lstyle; + std::cout << "--- Pretty print YAML to stdout using generic serilize function\n" + << "With params: "; + Serialize(std::cout.rdbuf(), param, SERIALIZE_JSON); + std::cout << std::endl; + Serialize(std::cout.rdbuf(), val, SERIALIZE_YAML, param); + std::cout << std::endl; + } + } + + return 0; +} diff --git a/src/hos_libvariant/src/include/Variant/ArgParse.h b/src/hos_libvariant/src/include/Variant/ArgParse.h new file mode 100644 index 00000000..97e0a17b --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/ArgParse.h @@ -0,0 +1,301 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_ARGPARSER_H +#define VARIANT_ARGPARSER_H +#pragma once +#include +#include +#include +namespace libvariant { + + + enum ArgParseAction { + ARGACTION_UNKNOWN, // Unknown action (invalid) + ARGACTION_STORE, // Interpret the option argument and store it at the path + ARGACTION_STORE_CONST, // Store const into the path + ARGACTION_STORE_TRUE, // Store true into the path + ARGACTION_STORE_FALSE, // Store false into the path + ARGACTION_APPEND, // Append the option argument to the list at path + ARGACTION_COUNT, // Make the value at path be the count of this options occurrences + ARGACTION_HELP, // Print out the help text and exit + ARGACTION_ADVHELP, // Print the advanced help and exit + ARGACTION_CONFIG, // Consider the option argument a filename to be loaded and parsed as a config + ARGACTION_CONFIG_JSON, // force parser to use jscn + ARGACTION_CONFIG_YAML, // force parser to use yaml + ARGACTION_CONFIG_PLIST, // force parser to use xmlplist + ARGACTION_PRINT_CONFIG // At the end of parsing print out the resulting config and exit. + }; + + // A constrained list of only the valid types for ArgParse + enum ArgParseType { + ARGTYPE_GUESS = Variant::NullType, // No type specification, guess, uses deserialize machinery + ARGTYPE_INT = Variant::IntegerType, // Error if it cannot be turned into an integer + ARGTYPE_UINT = Variant::UnsignedType, // Error if it cannot be turned into a unsigned + ARGTYPE_FLOAT = Variant::FloatType, // Error if it cannot be turned into a float + ARGTYPE_STRING = Variant::StringType, // store as string + ARGTYPE_BOOL = Variant::BoolType // Error if it cannot be turned into a boolean type + // it treats 0 or the strings 'false' and 'no' or any substring ignoring case as false + // and everything else as true + }; + + //! Valid values are: + // This is used for converting the enum to a Variant and back for + // ArgParse::GetDescription and ArgParse::Merge + // store -- store the value into the key (default) + // store_const -- store const (see Const) into the key + // store_true -- store true into the key (i.e. no option argument) + // store_false -- store false into the key + // append -- make the value a list of instances of the option + // count -- count the number of instances of this argument + // help -- display the help text and exit + // config -- load a file and merge it into the result (uses GuessFormat) + // config_json -- same as config, force to use json parser + // config_yaml -- same as config, force to use yaml parser + // config_plist -- same as config, force to use xml-plist parser + // config_print -- when finished parsing, print out the config and exit + ArgParseAction ArgParseActionFromStr(const std::string &action); + std::string ArgParseActionToStr(ArgParseAction action); + + class ArgParse; + struct ArgParseImpl; + struct ArgParseOptImpl; + struct ArgParseGroupImpl; + + //! ArgParseOption is a part of class ArgParse. + // ArgParseOption is the interface that ArgParse provides to the user to be able + // to conveniently set the options for an option. + class ArgParseOption { + public: + + //! Set the title of this option. The title is used + // as an argument placeholder string. + ArgParseOption &Title(const std::string &title); + + //! What action to perform when this option is encountered. + // See ArgParseAction above for a list of actions. + ArgParseOption &Action(ArgParseAction action); + DEPRECATED ArgParseOption &Action(const std::string &action); + + //! Set the type parsing and validation. + // If set and the argument is not of this type, then it is invalid. + // Default: ARGTYPE_GUESS + // If type is ARGTYPE_GUESS then ArgParse attempts to parse the + // argument with the same machinery that is used by the deserializers + // to figure out the type of a scalar. + // ARGTYPE_UINT is the same as ARGTYPE_INT but with + // Minimum set to 0. + // See ArgParseType for the list of valid types. + ArgParseOption &Type(ArgParseType type); + // Same as above but throws on invalid type + DEPRECATED ArgParseOption &Type(Variant::Type_t type); + // String version of the above + // Valid types are "string", "number", "integer", "boolean", or "null". + // Default type is "null". + DEPRECATED ArgParseOption &Type(const std::string &type); + + //! Set the const value for "store_const" + ArgParseOption &Const(Variant val); + + //! Set the default value used when the option is not set. + ArgParseOption &Default(Variant val); + + //! Set the environment variable name to check for a value for this option. + // When the environment variable is present this acts like Default was set + // to the environment variable's value. I.e., this overrides default, + // command line arguments override this. + ArgParseOption &Env(const char *env); + + //! If the resulting value is a number, require to be at least this minimum. + ArgParseOption &Minimum(Variant val); + + //! If the resulting value is a number, require to be at most this maximum. + ArgParseOption &Maximum(Variant val); + + //! Add choices. + // If a choice is added, the value of the option must be one of the choices. + ArgParseOption &AddChoice(Variant val); + + //! Set choices (old ones forgotten) from a vector. + ArgParseOption &SetChoices(const std::vector &val); + + //! Return the vector of choices set. + const std::vector &GetChoices(); + + //! Is this option required? + ArgParseOption &Required(bool req=true); + + //! Set the help text for this option. + ArgParseOption &Help(const std::string &helptxt); + + //! If this option is a string, it must match the regex in pattern. + ArgParseOption &Pattern(const std::string &pattern); + + //! If this option is a string, it must be no longer than maxLength. + ArgParseOption &MaxLength(unsigned l); + + //! If this option is a string, it must be no shorter than minLength. + ArgParseOption &MinLength(unsigned l); + + //! If this option can be specified multiple times, it must be + // specified minArgs times at least. + // A value of 0 means zero arguments is valid. + ArgParseOption &MinArgs(unsigned l); + + //! If this option can be specified multiple times, it cannot be + // specified more than maxArgs. + // A value of 0 means any number + ArgParseOption &MaxArgs(unsigned l); + + //! Specify that this argument must be present l times. + // Sets both minArgs and maxArgs to l + ArgParseOption &NumArgs(unsigned l); + + //! Adds this option to group gname. If gname does not exist, + //it will be created with an empty title and description. + ArgParseOption &Group(const std::string &gname); + + //! Sets this argument to be an advanced option + // This hides the option when not printing advanced options + ArgParseOption &Advanced(bool adv = true); + + private: + ArgParseOption(ArgParseOptImpl *i) : impl(i) {} + ArgParseOptImpl *impl; + friend class ArgParse; + }; + + //! Groups are a way to organize the option and to provide mutual exclusion + //of option. An argument may be part of more than one group, but may only + //be part of one group that has a non-empty title and description. An + //attempt is made to order the help text so that options within the same + //group appear together and if a group has a title and/or description the + //options are placed within a subsection headed with the title and + //description. + class OptionGroup { + public: + //! Set the title for this group + OptionGroup &Title(const std::string &t); + //! Set the description for this group + OptionGroup &Description(const std::string &d); + //! Set that the options in this group are mutually exclusive + OptionGroup &MutuallyExclusive(bool exclusive=true); + //! Set that at least one option in this group is required. + //Has no meaning when the group is not mutually exclusive. + OptionGroup &Required(bool req=true); + + OptionGroup &Add(const std::string &keypath); + OptionGroup &Add(const Path &keypath); + + //! Sets this option group to be advanced + // Hide the group when not printing advanced options. + // This only hides the group when it has a title or description + OptionGroup &Advanced(bool adv=true); + private: + OptionGroup(ArgParseGroupImpl *i) : impl(i) {} + ArgParseGroupImpl *impl; + friend class ArgParse; + }; + + class ArgParse { + public: + //! addhelp true causes AddHelp to be called. + ArgParse(bool addhelp=true); + ArgParse(const std::string &pname, bool addhelp=true); + + //! Add the option and configure it as an option that takes an argument. + //The default action will be "store" and type will be unspecified + // + // keypath must be a valid path as defined in Path.h + // + // For no short option, shortOpt may be 0, and for no long option, longOpt may be + // the empty string. If both shortOpt is 0 and longOpt is empty then this option + // is hidden unless Env is also set for the option. + ArgParseOption AddOption(const std::string &keypath, int shortOpt, const std::string &longOpt="", + const std::string &helptxt=""); + + //! Convenience methods for getting an existing option. + // ArgParse args(argv[0]); + // args.AddOption("key1", 'k', "key1", "how many things").Type("integer"); + // args.AddOption("key2", 'K', "key2", "what to name it").Type("string"); + // (... some intermediate code ...) + // args.At("key1").Default(42); + // args["key2"].Default("foo"); + ArgParseOption At(const std::string &keypath); + ArgParseOption operator[](const std::string &keypath) { return At(keypath); } + + //! Add the option and configure it as an option that is default false and + //if present sets to true + //i.e., same as: + // AddOption(keypath, shortOpt, longOpt, helptxt).Type("boolean") + // .Action("store_true").Default(false); + ArgParseOption AddFlag(const std::string &keypath, int shortOpt, const std::string &longOpt="", + const std::string &helptxt=""); + + //! Adds the group name. + OptionGroup AddGroup(const std::string &name, const std::string &title="", const std::string &description=""); + //! Returns the group name. + OptionGroup GetGroup(const std::string &name); + + //! Add a positional argument. + // By default the new positional argument will have NumArgs as 1. + // Arguments are processed in the order they are added. + // If maxArgs is 0, then no positional arguments after this one will + // be processed. + // Default action is store. + ArgParseOption AddArgument(const std::string &keypath, const std::string &helptxt=""); + + //! Convenience methods for getting an existing argument. + // ArgParse args(argv[0]); + // args.AddArgument("arg0", "pick one").AddChoice("AAA").AddChoice("BBB"); + // args.AddArgument("arg1", "scale factor").Type("float"); + // (... some intermediate code ...) + // args.At(0).AddChoice("CCC"); + // args[1].Default(0.456); + ArgParseOption At(size_t argumentIndex); + ArgParseOption operator[](size_t argumentIndex) { return At(argumentIndex); } + + //! When this is on, trying to add a second option with the same short option + //will cause the second option to act as though it had no short option specified. + void ConflictResolution(bool resolve=true); + + //! Add a --config and --print-config option + // --config is set with action ARGACTION_CONFIG and + // --print-config is set with action ARGACTION_PRINT_CONFIG + void AddConfigDefaults(); + + //! Add -h,--help option with action ARGACTION_HELP + void AddHelp(); + + //! Set the description text that follows the usage message. + void SetDescription(const std::string &txt); + //! Set the epilog text at the end of help. + void SetEpilog(const std::string &txt); + //! Override the default program name. + void SetProgramName(const std::string &pname, bool do_basename=true); + std::string GetProgramName() const; + + void Merge(Variant newopts); + void Merge(const ArgParse &other); + + //! Validate the argparse description against the internal schema + void Validate() const; + + //! Parse the arguments with the internal description + Variant Parse(int argc, char *const *argv); + + //! Print the help message and exit. + void PrintHelp(bool advanced=false) const; + + //! Return the Variant that describes the arguments + Variant GetDescription() const; + + //! Generate a schema for the Variant returned by Parse from the argument description + Variant GenerateSchema() const; + + private: + shared_ptr impl; + }; +} +#endif diff --git a/src/hos_libvariant/src/include/Variant/Blob.h b/src/hos_libvariant/src/include/Variant/Blob.h new file mode 100644 index 00000000..b2706e4d --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/Blob.h @@ -0,0 +1,63 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_BLOB_H +#define VARIANT_BLOB_H + +#pragma once +#include "../../../src/include/Variant/SharedPtr.h" +#include +#include + +namespace libvariant { + class Blob; + typedef shared_ptr BlobPtr; + typedef shared_ptr ConstBlobPtr; + + typedef void (*BlobFreeFunc)(void *ptr, void *ctx); + + class Blob { + public: + + /// Reference the buffer and call ffunc when Blob no longer references it + static BlobPtr Create(void *ptr, unsigned len, BlobFreeFunc ffunc, void *context); + /// Will call ffunc on each buffer in iov + static BlobPtr Create(struct iovec *iov, unsigned iov_len, BlobFreeFunc ffunc, void *context); + /// Copy the data into a newly allocatd buffer + static BlobPtr CreateCopy(const void *ptr, unsigned len); + static BlobPtr CreateCopy(const struct iovec *iov, unsigned iov_len); + /// Reference the buffer and when done call free to free the buffer + static BlobPtr CreateFree(void *ptr, unsigned len); + static BlobPtr CreateFree(struct iovec *iov, unsigned iov_len); + /// Reference the buffer, assume static or other allocation lifetime where + // calling a free function is not required + static BlobPtr CreateReferenced(void *ptr, unsigned len); + static BlobPtr CreateReferenced(struct iovec *iov, unsigned iov_len); + ~Blob(); + + BlobPtr Copy() const; + + void *GetPtr(unsigned i) { return iov[i].iov_base; } + const void *GetPtr(unsigned i) const { return iov[i].iov_base; } + unsigned GetLength(unsigned i) const { return iov[i].iov_len; } + struct iovec *GetIOVec() { return &iov[0]; } + const struct iovec *GetIOVec() const { return &iov[0]; } + unsigned GetNumBuffers() const { return iov.size(); } + unsigned GetTotalLength() const; + + int Compare(ConstBlobPtr other) const; + + private: + Blob(); + Blob(const Blob&); + Blob(struct iovec *v, unsigned l, BlobFreeFunc f, void *c); + Blob operator=(const Blob&); + + std::vector iov; + BlobFreeFunc free_func; + void *ctx; + }; + +} +#endif diff --git a/src/hos_libvariant/src/include/Variant/Emitter.h b/src/hos_libvariant/src/include/Variant/Emitter.h new file mode 100644 index 00000000..1b113470 --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/Emitter.h @@ -0,0 +1,226 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_EMITTER_H +#define VARIANT_EMITTER_H + +#pragma once +#include +#include +#include +#include +#include "../../../src/include/Variant/Variant.h" +#include "../../../src/include/Variant/Blob.h" +#include "../../../src/include/Variant/EmitterOutput.h" +#include +#include + +namespace libvariant { + + /** + * Class to override to implement an Emitter + */ + class EmitterImpl { + public: + virtual ~EmitterImpl(); + + virtual void BeginDocument() = 0; + virtual void EndDocument() = 0; + virtual void BeginMap(int length) = 0; + virtual void EndMap() = 0; + virtual void BeginList(int length) = 0; + virtual void EndList() = 0; + + virtual void EmitNull() = 0; + virtual void EmitTrue() = 0; + virtual void EmitFalse() = 0; + virtual void Emit(const char *v) = 0; + virtual void Emit(intmax_t v) = 0; + virtual void Emit(uintmax_t v) = 0; + virtual void Emit(double v) = 0; + virtual void Emit(ConstBlobPtr b) = 0; + + virtual void Flush() = 0; + virtual void Close() = 0; + + virtual Variant GetParam(const std::string &key) = 0; + virtual Variant GetParams() = 0; + virtual void SetParam(const std::string &key, Variant value) = 0; + virtual void SetParams(Variant params); + }; + + /** + * Actual emitter class. + */ + class Emitter { + public: + Emitter(); + Emitter(shared_ptr i); + ~Emitter(); + + Emitter &BeginDocument(); + Emitter &EndDocument(); + + //Some emitter implementations require the length of the map at the + //beginning. Such implementations should buffer events if length == -1 + //Implementations are free to ignore the length. + Emitter &BeginMap() { return BeginMap(-1); } + Emitter &BeginMap(int length); + Emitter &EndMap(); + //Some emitter implementations require the length of the list at the + //beginning. Such implementations should buffer events if length == -1 + Emitter &BeginList() { return BeginList(-1); } + Emitter &BeginList(int length); + Emitter &EndList(); + + Emitter &EmitNull(); + Emitter &EmitTrue(); + Emitter &EmitFalse(); + Emitter &Emit(bool v) { return (v ? EmitTrue() : EmitFalse()); } + Emitter &Emit(const std::string &v); + Emitter &Emit(const char *v); + Emitter &Emit(intmax_t v); + Emitter &Emit(uintmax_t v); + Emitter &Emit(double v); + Emitter &Emit(ConstBlobPtr b); + + void Flush(); + void Close(); + + /// Get the value of parameters of the parser (e.g. pretty printing, + // styles, etc.) + // See individual emitter below for supported values. + Variant GetParam(const std::string &key); + /// Get a dict of all parameters + Variant GetParams(); + /// Set the value of parameters. + // See individual emitter below for supported values. + void SetParam(const std::string &key, Variant value); + /// Set all parameters from a dict + void SetParams(Variant params); + /// Internal/advanced function to get the underlying implementation + shared_ptr GetImpl() { return impl; } + private: + shared_ptr impl; + }; + + template + inline Emitter &operator<<(Emitter &e, const std::vector &v) { + e.BeginList(v.size()); + for (typename std::vector::const_iterator i(v.begin()), end(v.end()); i!=end; i++) { + e << *i; + } + e.EndList(); + return e; + } + + template + inline Emitter &operator<<(Emitter &e, const std::map &v) { + e.BeginMap(v.size()); + for (typename std::map::const_iterator i(v.begin()), end(v.end()); i!=end; ++i) { + e.Emit(i->first); + e << i->second; + } + e.EndMap(); + return e; + } + inline Emitter &operator<<(Emitter &e, bool v) { e.Emit(v); return e; } + inline Emitter &operator<<(Emitter &e, char v) { e.Emit(intmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, short v) { e.Emit(intmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, int v) { e.Emit(intmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, long v) { e.Emit(intmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, long long v) { e.Emit(intmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, unsigned char v) { e.Emit(uintmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, unsigned short v) { e.Emit(uintmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, unsigned int v) { e.Emit(uintmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, unsigned long v) { e.Emit(uintmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, unsigned long long v) { e.Emit(uintmax_t(v)); return e; } + inline Emitter &operator<<(Emitter &e, const char *v) { e.Emit(v); return e; } + inline Emitter &operator<<(Emitter &e, const std::string &v) { e.Emit(v); return e; } + inline Emitter &operator<<(Emitter &e, float v) { e.Emit(double(v)); return e; } + inline Emitter &operator<<(Emitter &e, double v) { e.Emit(v); return e; } + inline Emitter &operator<<(Emitter &e, ConstBlobPtr v) { e.Emit(v); return e; } + + shared_ptr CreateEmitterOutput(void *ptr, unsigned len, unsigned *out_len=0); + shared_ptr CreateEmitterOutput(const char *filename); + shared_ptr CreateEmitterOutput(FILE *f); + shared_ptr CreateEmitterOutput(std::streambuf *sb); + + /** + * Create an Emiter that Emits the format specified by type. + * Supported parameters are dependent on type (see below). + */ + Emitter CreateEmitter(shared_ptr o, SerializeType type, Variant params = Variant::NullType); + + /** + * Create an Emitter that Emits the JSON format. + * + * Supported parameters are: + * "pretty": boolean + * "indent": integer (number of spaces to indent when pretty is on, + * default 4) + * "precision": integer (number of digits for floats) + * "strict": be more strict about emitting correct json + */ + Emitter JSONEmitter(shared_ptr o, Variant params = Variant::NullType); + + /** + * Supported parameters are (first is default): + * + * "scalar_style": "any"|"plain"|"single quoted"|"double + * quoted"|"literal"|"folded" + * + * "map_style": "any"|"block"|"flow" + * + * "list_style": "any"|"block"|"flow" + * + * "implicit_document_begin": false|true + * + * "implicit_document_end": false|true + * + * "indent": integer (number of spaces to indent) + * + * "width": integer (set prefered line width) + * + * "precision": integer (number of digits for floats) + */ + Emitter YAMLEmitter(shared_ptr o, Variant params = Variant::NullType); + + /** + * Supported params are: + * + * "pretty": true|false + * "indent": integer (amount to indent for pretty) + * "precision": integer (number of digits for floats) + */ + Emitter XMLPLISTEmitter(shared_ptr o, Variant params = Variant::NullType); + /** + * Supported params are: + * + * "precision": integer (number of digits for floats) + */ + Emitter BundleHdrEmitter(shared_ptr o, Variant params = Variant::NullType); + + /** + * No parameters supported. + */ + Emitter MsgPackEmitter(shared_ptr o, Variant params = Variant::NullType); +} +#endif diff --git a/src/hos_libvariant/src/include/Variant/EmitterOutput.h b/src/hos_libvariant/src/include/Variant/EmitterOutput.h new file mode 100644 index 00000000..ffc5b1e8 --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/EmitterOutput.h @@ -0,0 +1,87 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + * + * The end user should not need to look at this file unless they are + * creating custom outputs for the emitters. + */ +#ifndef VARIANT_EMITTEROUTPUT_H +#define VARIANT_EMITTEROUTPUT_H +#pragma once +#include +#include + +namespace libvariant { + + class EmitterOutput { + public: + virtual ~EmitterOutput(); + /// Return the number of bytes written, or throw an exception + virtual unsigned Write(const void *ptr, unsigned len) = 0; + virtual void Flush() {} + virtual unsigned NumBytesWritten() const = 0; + }; + + class EmitterFileOutput : public EmitterOutput { + public: + EmitterFileOutput(FILE *f, bool c); + ~EmitterFileOutput(); + virtual unsigned Write(const void *ptr, unsigned len); + virtual void Flush(); + virtual unsigned NumBytesWritten() const { return num_bytes; } + protected: + FILE *file; + unsigned num_bytes; + bool cls; + }; + + class EmitterFilenameOutput : public EmitterFileOutput { + public: + EmitterFilenameOutput(const char *filename, const char *mode="w"); + }; + + class EmitterStreambufOutput : public EmitterOutput { + public: + EmitterStreambufOutput(std::streambuf *sb, bool d); + ~EmitterStreambufOutput(); + virtual unsigned Write(const void *ptr, unsigned len); + virtual void Flush(); + virtual unsigned NumBytesWritten() const { return num_bytes; } + protected: + std::streambuf *streambuf; + unsigned num_bytes; + bool del; + }; + + class EmitterMemoryOutput : public EmitterOutput { + public: + EmitterMemoryOutput(void *ptr, unsigned len, unsigned *out_len = 0); + + virtual unsigned Write(const void *ptr, unsigned len); + + virtual unsigned NumBytesWritten() const { return *out_length; } + protected: + void *data_ptr; + unsigned length; + unsigned out_length_dummy; + unsigned *out_length; + }; + +} +#endif diff --git a/src/hos_libvariant/src/include/Variant/Exceptions.h b/src/hos_libvariant/src/include/Variant/Exceptions.h new file mode 100644 index 00000000..20c33383 --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/Exceptions.h @@ -0,0 +1,88 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_EXCEPTIONS_H +#define VARIANT_EXCEPTIONS_H +#include +#include +#include + +#include "../../../src/include/Variant/VariantDefines.h" +namespace libvariant { + + /// \brief Exception thrown when a key does not exist. + class KeyError : public std::runtime_error { + public: + KeyError(const std::string &key) throw(); + }; + + /// \brief Exception thrown when internal state is corrupt. + class UnknownTypeError : public std::runtime_error { + public: + UnknownTypeError(VariantDefines::Type_t type) throw(); + }; + + /// \brief Exception thrown when a function expects a specific type but the action type conflicts. + class UnexpectedTypeError : public std::runtime_error { + public: + UnexpectedTypeError(VariantDefines::Type_t expected, VariantDefines::Type_t value) throw(); + UnexpectedTypeError(const std::vector &expected, VariantDefines::Type_t value) throw(); + }; + + /// \brief Exception thrown when a function cannot convert the Variant to an acceptable type for the routine. + class UnableToConvertError : public std::runtime_error { + public: + UnableToConvertError(VariantDefines::Type_t sourcetype, const std::string &targettype) throw(); + }; + + /// \brief Exception thrown when trying to index a type other than map or list. + class TypeNotIndexableError : public std::runtime_error { + public: + TypeNotIndexableError(VariantDefines::Type_t type) throw(); + }; + + /// \brief Exception thrown when attempting a numeric operation on a non numeric type. + class NotNumericTypeError : public std::runtime_error { + public: + NotNumericTypeError(VariantDefines::Type_t type) throw(); + }; + + /// \brief Exception thrown from path functions + class BadPathError : public std::runtime_error { + public: + BadPathError(VariantDefines::Type_t type) throw(); + BadPathError(const std::string &msg) throw(); + }; + + class InvalidReferenceError : public std::runtime_error { + public: + InvalidReferenceError(const std::string &msg) throw(); + }; + + class InvalidOperationError : public std::runtime_error { + public: + InvalidOperationError(VariantDefines::Type_t type, const std::string &opname) throw(); + }; + + std::ostream &operator <<(std::ostream &os, VariantDefines::Type_t type); + + void AddStackTrace(std::ostream &os, int level); +} +#endif diff --git a/src/hos_libvariant/src/include/Variant/Extensions.h b/src/hos_libvariant/src/include/Variant/Extensions.h new file mode 100644 index 00000000..a3f615bc --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/Extensions.h @@ -0,0 +1,92 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author Josh Staley + * \brief Useful extension functions for Variant + */ + +#ifndef VARIANT_EXTENSIONS_H +#define VARIANT_EXTENSIONS_H + +#include "../../../src/include/Variant/Variant.h" + +namespace libvariant { + + /// \brief Returns a default parameters for use with FlattenPath and ExpandPath functions. + Variant ExtensionParams(); + + /// \brief Sets any missing Extension parameters to 'params' for use with FlattenPath and ExpandPath functions. + void ExtensionParams( VariantRef params ); + + /// \brief Returns a version of 'var' with flat paths based on 'params' + Variant FlattenPath( const Variant &var, Variant params = ExtensionParams() ); + + /// \brief Returns a version of 'var' with expanded paths based on 'params' + Variant ExpandPath( const Variant &var, Variant params = ExtensionParams() ); + + /// \brief Flattens 'var' paths to 'flat' based on 'params' + void FlattenPathTo( VariantRef flat, const Variant &var, Variant params = ExtensionParams(), std::string prefix = "" ); + + /// \brief Expands 'var' paths to 'expand' based on 'params' + void ExpandPathTo( VariantRef expand, const Variant &var, Variant params = ExtensionParams() ); + + /// \brief Returns a string string map representation of 'var' based on 'params' + std::map + FlattenPathToStrStrMap( const Variant &var, Variant params = ExtensionParams() ); + + /// \brief Returns a variant representing elements in 'compare' that differ from 'base' recursively + Variant RDiff( const Variant &base, const Variant &compare ); + + /// \brief Sets elements into 'diff' from 'compare' that differ from 'base' recursively + void RDiff( VariantRef diff, const Variant &base, const Variant &compare ); + + /// \brief Updates 'base' with entries in 'update' recursively + void RUpdate( VariantRef base, const Variant &update ); + + /// Perform an operations on v according to RFC6901 and RFC6902. + // Note that JSON Pointer is ambiguous without the presence of a document. + // These function throw if the lookup fails because of incorrect types or + // on ambiguity. + // On return (or throw) the operation will have either succedded or no + // change will have been made. + + /// Add data to v at the spot specified by pointer + void JSONPointerAdd(const std::string &pointer, VariantRef v, Variant data); + /// Remove the element in v at the spot specified by pointer + void JSONPointerRemove(const std::string &pointer, VariantRef v); + /// Replace the value at pointer with data, error if the location does not already exist + void JSONPointerReplace(const std::string &pointer, VariantRef v, Variant data); + /// Move the value from src to dst (equivalent to get(src), remove(src), add(dst) + void JSONPointerMove(const std::string &src, const std::string &dst, VariantRef v); + /// Copy the value from src to dst (equivalent to add(dst, get(src).Copy())) + void JSONPointerCopy(const std::string &src, const std::string &dst, VariantRef v); + /// Perform a lookup into v according to RFC6901, return a reference to the value at the location + VariantRef JSONPointerLookup(const std::string &pointer, VariantRef v); + + std::string FormJSONPointer(const Path &path); + + /// Perform a patch operation on v with the patch as described by diff according to RFC6902 + // Returns true if the patch is applied and all tests pass, + // false if any tests failed and no patch is applied + std::pair JSONPatch(VariantRef v, const Variant &diff); + + /// Create a diff suitable to give to JSONPatch to transform src into dst. + Variant JSONDiff(const Variant &src, const Variant &dst); + +} // namespace libvariant + +#endif /*#ifndef VARIANT_EXTENSIONS_H*/ diff --git a/src/hos_libvariant/src/include/Variant/GuessFormat.h b/src/hos_libvariant/src/include/Variant/GuessFormat.h new file mode 100644 index 00000000..9687d863 --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/GuessFormat.h @@ -0,0 +1,23 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_GUESSFORMAT_H +#define VARIANT_GUESSFORMAT_H + +#pragma once +#include "../../../src/include/Variant/Variant.h" +#include "../../../src/include/Variant/Parser.h" +namespace libvariant { + + /// + // Try to guess the format of the input without removing any + // input from the input object. + // + // Currently only looks at the first non-whitespace character + // and if it is '<' then says XMLPLIST, otherwise says YAML + // if enabled otherwise JSON. + // + SerializeType GuessFormat(ParserInput* in); +} +#endif diff --git a/src/hos_libvariant/src/include/Variant/Parser.h b/src/hos_libvariant/src/include/Variant/Parser.h new file mode 100644 index 00000000..b430d835 --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/Parser.h @@ -0,0 +1,158 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_PARSER_H +#define VARIANT_PARSER_H + +#pragma once +#include +#include +#include "../../../src/include/Variant/Blob.h" +#include "../../../src/include/Variant/ParserInput.h" +#include "../../../src/include/Variant/Variant.h" +#include + +namespace libvariant { + + class ParserImpl; + + class ParserActions { + public: + virtual ~ParserActions(); + virtual void BeginDocument(ParserImpl *p) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void EndDocument(ParserImpl *p) + { throw std::runtime_error("Parser: Unexpected event"); } + // If length < 0, unknown length + virtual void BeginMap(ParserImpl *p, int length, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void EndMap(ParserImpl *p) + { throw std::runtime_error("Parser: Unexpected event"); } + // If length < 0, unknown length + virtual void BeginList(ParserImpl *p, int length, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void EndList(ParserImpl *p) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Alias(ParserImpl *p, const char *anchor) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Scalar(ParserImpl *p, double v, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Scalar(ParserImpl *p, const char *str, unsigned length, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Scalar(ParserImpl *p, bool v, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Null(ParserImpl *p, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Scalar(ParserImpl *p, intmax_t v, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Scalar(ParserImpl *p, uintmax_t v, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + virtual void Scalar(ParserImpl *p, BlobPtr b, const char *anchor, const char *tag) + { throw std::runtime_error("Parser: Unexpected event"); } + }; + + /// The class that parser implementations override + class ParserImpl { + public: + virtual ~ParserImpl(); + /** + * Attempt to parse some actions. + * At least one ParserActions should be on the action stack. + * + * Run is not guaranteed to be recursively callable from inside a + * ParserActions callback. Do not do that. + * + * return 0 on success + * return 1 when done + * return -1 if needing more data is detected (not all parsers support this; can be treated as an error) + * throw on error + */ + virtual int Run() = 0; + + /** + * Push a new ParserActions handler onto the action handler stack. + */ + virtual void PushAction(shared_ptr action) { action_stack.push_back(action); } + + /** + * Pop the top ParserActions handler off the action handler stack and + * return it. + */ + virtual shared_ptr PopAction() { + if (action_stack.empty()) + { throw std::runtime_error("Parser: Attempting to parse an actions without any action handlers"); } + shared_ptr ret = action_stack.back(); + action_stack.pop_back(); + return ret; + } + + /** + * Access the top ParserActions + */ + ParserActions *TopAction() { + if (action_stack.empty()) + { throw std::runtime_error("Parser: Attempting to parse an actions without any action handlers"); } + return action_stack.back().get(); + } + + /** These three functiosn can be used to query the state + * later. + * Done means that a call to Process will immediately return 1 + * Error if Process threw an exception last + * Ok if everything looks good (Process never been called, or last return 0 or possibly -1) + */ + virtual bool Done() const = 0; + virtual bool Error() const = 0; + virtual bool Ok() const = 0; + /// Return a string describing the last error suitable for presentation to a user + virtual std::string ErrorStr() const = 0; + /// Reset the parser + virtual void Reset() = 0; + protected: + std::deque< shared_ptr< ParserActions > > action_stack; + }; + + class Parser { + public: + Parser(); + Parser(shared_ptr pi); + ~Parser(); + /// 0 on success, 1 when done, -1 other problem, throw on error + int Run() { return impl->Run(); } + /// Push an action handler onto the action stack. + void PushAction(shared_ptr action) { impl->PushAction(action); } + /// Pop the top action handler off the stack. + shared_ptr PopAction() { return impl->PopAction(); } + + /// Query state + bool Done() const { return impl->Done(); } + bool Error() const { return impl->Error(); } + bool Ok() const { return impl->Ok(); } + /// Return a string describing the last error suitable for presentation to a user + std::string ErrorStr() const { return impl->ErrorStr(); } + /// Reset the parser if applicable (some types will throw) + void Reset() { impl->Reset(); } + + /// Internal/advanced function to get the underlying implementation + shared_ptr GetImpl() { return impl; } + private: + shared_ptr impl; + }; + + shared_ptr CreateParserInput(const std::string &str); + shared_ptr CreateParserInput(const char *str); + shared_ptr CreateParserInput(const void *ptr, unsigned len); + shared_ptr CreateParserInputFile(const char *filename); + shared_ptr CreateParserInputFile(FILE *f); + shared_ptr CreateParserInputFile(std::streambuf *sb); + + Parser CreateParser(shared_ptr i, SerializeType type); + Parser CreateParserGuess(shared_ptr i); + Parser JSONParser(shared_ptr i); + Parser YAMLParser(shared_ptr i); + Parser XMLPLISTParser(shared_ptr i); + Parser BundleHdrParser(shared_ptr i); + Parser MsgPackParser(shared_ptr i); +} +#endif diff --git a/src/hos_libvariant/src/include/Variant/ParserInput.h b/src/hos_libvariant/src/include/Variant/ParserInput.h new file mode 100644 index 00000000..5fa66311 --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/ParserInput.h @@ -0,0 +1,104 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_PARSERINPUT_H +#define VARIANT_PARSERINPUT_H +#pragma once +#include +#include +#include +#include + +namespace libvariant { + + class ParserInput { + public: + virtual ~ParserInput(); + // Get a pointer and length to the unprocessed data that is available + // (return null on end of data) len being an in/out parameter, + // the initial value of len is how much the parser wants. An input value of zero + // in means give whatever is currently available. + virtual const void *GetPtr(unsigned &len) = 0; + + // Tell the input that the parser is done with len bytes from the last + // GetPtr + virtual void Release(unsigned len) = 0; + }; + + class ParserStreamInput : public ParserInput { + public: + ParserStreamInput(unsigned buffer_len); + virtual const void *GetPtr(unsigned &len); + virtual void Release(unsigned len); + /// return number of bytes read into ptr, 0 on EOF + // and throw on error + virtual unsigned Read(void *ptr, unsigned len) = 0; + protected: + std::vector buffer; + unsigned num; + unsigned offset; + bool eof; + }; + + class ParserMemoryInput : public ParserInput { + public: + ParserMemoryInput(const void *ptr, unsigned len); + virtual const void *GetPtr(unsigned &len); + virtual void Release(unsigned len); + protected: + const void *data_ptr; + unsigned data_len; + unsigned offset; + }; + + class ParserStringInput : public ParserInput { + public: + ParserStringInput(const std::string &str); + virtual const void *GetPtr(unsigned &len); + virtual void Release(unsigned len); + protected: + const std::string val; + unsigned offset; + }; + + class ParserFileInput : public ParserStreamInput { + public: + ParserFileInput(FILE *f); + virtual unsigned Read(void *ptr, unsigned len); + protected: + FILE *file; + }; + + class ParserFilenameInput : public ParserFileInput { + public: + ParserFilenameInput(const char *filename, const char *mode = "r"); + ~ParserFilenameInput(); + }; + + class ParserStreambufInput : public ParserStreamInput { + public: + ParserStreambufInput(std::streambuf *sb); + unsigned Read(void *ptr, unsigned len); + protected: + std::streambuf *streambuf; + }; + +} +#endif diff --git a/src/hos_libvariant/src/include/Variant/Path.h b/src/hos_libvariant/src/include/Variant/Path.h new file mode 100644 index 00000000..53426fd3 --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/Path.h @@ -0,0 +1,100 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_PATH_H +#define VARIANT_PATH_H + +#pragma once +#include +#include +#include "../../../src/include/Variant/Exceptions.h" +namespace libvariant { + + // A simple xpath like path functionality for Variant + // + // Map keys are specified using a "/" then the key. + // List indeces are specified using [index] + // A "/" at the end of the path is ignored. + // Characters "\/[]" must all be escaped with "\" + // + // For example: + // { + // "key1": [ 1, 2, 3, { "blork": true } ], + // "key2": { + // "subkey": [ "a", { "furple": 1 }, 2 ], + // "sub/key2": true + // } + // } + // + // Then all paths enumerated are: + // Path Value + // "/" Identity + // "/key1" [ 1, 2, 3, { "blork": true } ], + // "/key1[0]" 1 + // "/key1[1]" 2 + // "/key1[2]" 3 + // "/key1[3]" { "blork": true } + // "/key1[3]/blork" true + // "/key2" { "subkey": [ "a", { "furple": 1 }, 2 ], "sub/key2": true } + // "/key2/subkey" [ "a", { "furple": 1 }, 2 ] + // "/key2/subkey[0]" "a" + // "/key2/subkey[1]" { "furple": 1 } + // "/key2/subkey[1]/furple" 1 + // "/key2/subkey[2]" 2 + // "/key2/sub\/key2" true + // + // For all these functions PathList must act like a vector + // It may be of some other type (like deque) + + class PathElement { + public: + enum Type_t { INDEX, KEY }; + PathElement(const std::string &k) : type(KEY), key(k) {} + PathElement(const char *k) : type(KEY), key(k) {} + PathElement(unsigned i) : type(INDEX), index(i) {} + + bool IsNumber() const { return type == INDEX; } + unsigned AsUnsigned() const { + if (type != INDEX) throw BadPathError("Variant path element is not a number"); + return index; + } + bool IsString() const { return type == KEY; } + const std::string &AsString() const { + if (type != KEY) throw BadPathError("Variant path element is not a key"); + return key; + } + private: + Type_t type; + unsigned index; + std::string key; + }; + + typedef std::deque Path; + + //! + // Parse the path string into path tokens. + void ParsePath(Path &parsed_path, const std::string &path); + Path ParsePath(const std::string &path); + + //! Take the set of path tokens and turn it into a path string + std::string PathString(const Path &path); + +} +#endif diff --git a/src/hos_libvariant/src/include/Variant/Payload.h b/src/hos_libvariant/src/include/Variant/Payload.h new file mode 100644 index 00000000..bcb213b5 --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/Payload.h @@ -0,0 +1,129 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_PAYLOAD_H +#define VARIANT_PAYLOAD_H +#pragma once +#include +#include +#include +namespace libvariant { + + // Serialize and Deserialize a header, null byte, and a binary payload + // + // All restrictions of the given serialization format are required. + // + // Parameters for payload data location: + // "length_path": path to where the payload length should be + // placed for serialization and where the payload length should be read + // from for deserialization + // Defaults to: +#define VARIANT_PAYLOAD_LENGTH_PATH "payload/length" +#define VARIANT_BUNDLE_PAYLOAD_LENGTH_PATH "payload.length" + // "data_path": path to where the payload is located for + // serialization and path to store payload for deserialization + // Defaults to: +#define VARIANT_PAYLOAD_DATA_PATH "payload/data" +#define VARIANT_BUNDLE_PAYLOAD_DATA_PATH "payload.data" + // The defaults are the values for compatibility with the bundle format. + // + // Serialize only parameters: + // "ignore_payload": true|false (default false) + // Don't output the payload, only the header, alignment and null byte. + // If the payload exists in the Variant, use the length for the payload length + // value, if not look in parameters for the payload length value, if not there + // look in the Variant for the payload length. + // "payload_length": num + // Payload length override, put this number in as the payload length + // regardless of what size the blob is. + // Note that unless ingnore_payload is true, the emitter will try to output the whole + // payload (and no more) regardless of what this number is. + + void SerializeWithPayload(shared_ptr out, Variant v, SerializeType type, + Variant params = Variant::NullType); + Variant DeserializeWithPayload(shared_ptr in, SerializeType type, + Variant params = Variant::NullType, bool be_safe=true); + + std::string SerializeWithPayload(Variant v, SerializeType type, Variant params = Variant::NullType); + void SerializeWithPayload(const std::string &filename, Variant v, SerializeType type, + Variant params = Variant::NullType); + void SerializeWithPayload(FILE *f, Variant v, SerializeType type, + Variant params = Variant::NullType); + void SerializeWithPayload(std::streambuf *sb, Variant v, SerializeType type, + Variant params = Variant::NullType); + unsigned SerializeWithPayload(void *ptr, unsigned len, Variant v, SerializeType type, + Variant params = Variant::NullType); + + Variant DeserializeWithPayload(const std::string &str, SerializeType type, + Variant params = Variant::NullType); + /// If the be_safe parameter is false, then it is considered OK + // to __/NOT/__ copy the payload and just reference it in the BlobPtr. + // This is only safe when you know your buffer is going to stick around + // until after your done with the resulting Variant. + // (This is to support zero copy) + // No null terminated string version provided as these formats contain nulls. + Variant DeserializeWithPayload(const void *ptr, unsigned len, SerializeType type, + Variant params = Variant::NullType, bool be_safe=true); + Variant DeserializeWithPayloadFile(const char *filename, SerializeType type, + Variant params = Variant::NullType); + Variant DeserializeWithPayloadFile(FILE *f, SerializeType type, + Variant params = Variant::NullType); + Variant DeserializeWithPayloadFile(std::streambuf *sb, SerializeType type, + Variant params = Variant::NullType); + + + /// Bundle is a simple format used internally at ARL for passing around + // a textual key value map plus a binary payload. The payload is often a very large + // array of numbers that would produce unacceptable overhead to serialize into text. + // These serialize routines assume that the passed in Variant is of MapType + // and if a key named "payload.data" exists it is to be written as the payload + // of the Bundle. + // + // If a key "payload.data" does not exist, these are almost the same as using the BundleHdrEmitter + // except it adds a null byte at the end. + inline std::string SerializeBundle(Variant v) + { return SerializeWithPayload(v, SERIALIZE_BUNDLEHDR); } + inline void SerializeBundle(const std::string &filename, Variant v) + { SerializeWithPayload(filename, v, SERIALIZE_BUNDLEHDR); } + inline void SerializeBundle(FILE *f, Variant v) + { SerializeWithPayload(f, v, SERIALIZE_BUNDLEHDR); } + inline void SerializeBundle(std::streambuf *sb, Variant v) + { SerializeWithPayload(sb, v, SERIALIZE_BUNDLEHDR); } + inline unsigned SerializeBundle(void *ptr, unsigned len, Variant v) + { return SerializeWithPayload(ptr, len, v, SERIALIZE_BUNDLEHDR); } + + inline Variant DeserializeBundle(const std::string &str) + { return DeserializeWithPayload(str, SERIALIZE_BUNDLEHDR); } + /// If the be_safe parameter is false, then it is considered OK + // to __/NOT/__ copy the payload and just reference it in the BlobPtr. + // This is only safe when you know your buffer is going to stick around + // until after your done with the resulting Variant. + // (This is to support zero copy) + // No null terminated string version provided as bundles contain nulls. + inline Variant DeserializeBundle(const void *ptr, unsigned len, bool be_safe=true) + { return DeserializeWithPayload(ptr, len, SERIALIZE_BUNDLEHDR, Variant::NullType, be_safe); } + inline Variant DeserializeBundleFile(const char *filename) + { return DeserializeWithPayloadFile(filename, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleFile(FILE *f) { return DeserializeWithPayloadFile(f, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleFile(std::streambuf *sb) + { return DeserializeWithPayloadFile(sb, SERIALIZE_BUNDLEHDR); } + +} +#endif diff --git a/src/hos_libvariant/src/include/Variant/Schema.h b/src/hos_libvariant/src/include/Variant/Schema.h new file mode 100644 index 00000000..235627c2 --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/Schema.h @@ -0,0 +1,175 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief A schema validator. + * + * This code is based on the public domain JSONv4 validator tv4. + * tv4 is available at http://geraintluff.github.com/tv4/ + */ +#ifndef VARIANT_SCHEMA_H +#define VARIANT_SCHEMA_H + +#pragma once +#include "../../../src/include/Variant/Variant.h" +#include +#include +#include +#include +namespace libvariant { + + class SchemaResult; + + class ValidationError { + public: + ValidationError(const std::string &m, const Path &dpath, + const Path &spath); + + void AddSubError(const SchemaResult &err); + + const std::string &GetMessage() const { return message; } + const Path &GetDataPath() const { return data_path; } + std::string GetDataPathStr() const; + const Path &GetSchemaPath() const { return schema_path; } + std::string GetSchemaPathStr() const; + const std::vector &GetSubErrors() const { return sub_errors; } + + std::string PrettyPrintMessage() const; + void PrettyPrintMessage(std::ostream &os, unsigned indent=0) const; + private: + std::string message; + Path data_path; + Path schema_path; + std::vector sub_errors; + }; + + class SchemaError { + public: + SchemaError(const std::string &m, const Path &spath); + + const std::string &GetMessage() const { return message; } + const Path &GetSchemaPath() const { return schema_path; } + std::string GetSchemaPathStr() const; + + std::string PrettyPrintMessage() const; + void PrettyPrintMessage(std::ostream &os, unsigned indent=0) const; + private: + std::string message; + Path schema_path; + }; + + class SchemaResult { + public: + SchemaResult(); + + void AddError(const ValidationError &err); + void AddSchemaError(const SchemaError &err); + + bool Error() const { return !errors.empty() || !schema_errors.empty(); } + bool ValidationErrors() const { return !errors.empty(); } + bool SchemaErrors() const { return !schema_errors.empty(); } + + const std::vector &GetErrors() const { return errors; } + const std::vector &GetSchemaErrors() const { return schema_errors; } + + std::string PrettyPrintMessage() const; + void PrettyPrintMessage(std::ostream &os, unsigned indent=0) const; + private: + std::vector errors; + std::vector schema_errors; + }; + + inline std::ostream &operator<<(std::ostream &os, const SchemaResult &sr) { + sr.PrettyPrintMessage(os); + return os; + } + + class SchemaLoader { + public: + class LoaderError { + public: + LoaderError(); + ~LoaderError(); + void AddError(const std::string &uri, const std::string &msg); + std::string GetErrorMessage() const { return erross.str(); } + private: + std::ostringstream erross; + }; + + typedef bool (*MissingHandlerType)(SchemaLoader*,const std::string&,LoaderError &,void*); + SchemaLoader(); + SchemaLoader(SchemaLoader *b); + virtual ~SchemaLoader(); + // Get the schema at the uri specified. + // Internal lookup first, then call HandleMissing if the uri is not internally available. + // If the schema then is still not available return Variant::NullType. + virtual Variant GetSchema(const std::string &uri); + // Add a schema to the loader at the uri specified. + // returns the schema(s) added with the corresponding uri(s) + virtual std::map AddSchema(const std::string &uri, Variant schema); + // Forget a schema with the specified uri. + virtual void ForgetSchema(const std::string &uri); + // Called when a schema is not in the loader. + // Default implementation is to call the missing handler + // or add a not found error to the LoaderError and return false + // Return true on success, otherwise false, any errors are filled into the LoaderError + virtual bool HandleMissing(const std::string &uri, LoaderError &error); + void SetMissingHandler(MissingHandlerType, void *ctx); + + static void NormSchema(Variant &schema, const std::string &uri); + //! + // A realpath function for schema URIs. + // href is the "current working directory" and base is + // possibly a relative path. + static std::string ResolveURI(const std::string &base, const std::string &href); + + struct URIInfo { + std::string href; // EX: the whole uri if matched + std::string protocol; // EX: http:// + std::string authority; // user:host@hostname:port + std::string pathname; // The path segment + std::string search; // ?q=234 + std::string hash; // #tag + }; + + //! Break a uri into its components and store them into the URIInfo struct + //! returns true if the parsing was successful + static bool ParseURI(URIInfo &info, const std::string &uri); + protected: + + static void SearchForTrustedSchemas(std::map &m, Variant schema, const std::string &uri); + MissingHandlerType missingHandler; + void *missingctx; + std::map schemas; + SchemaLoader *base; + }; + + //! Validate data against a schema. + //! + //! The schema parameter is either a schema, a string uri to a schema, or null. + //! If it is a schema then data is validated against it. + //! If it is a string then it calls loader->GetSchema() and validates data against the result. + //! If schema is null, then look for a key "$schema" in data, set schema to it and proceed as above. + SchemaResult SchemaValidate(Variant schema, Variant data, SchemaLoader *loader=0); + + //! Add the defaults specified in schema to data if they do not exist. + //! Ignores default in some combinations and types that could match multiple entries (not, + //! additionalProperties, patternProperties, etc.) + //! schema is processed the same as for SchemaValidate + void AddSchemaDefaults(Variant schema, VariantRef data, SchemaLoader *loader=0); +} +#endif diff --git a/src/hos_libvariant/src/include/Variant/SchemaLoader.h b/src/hos_libvariant/src/include/Variant/SchemaLoader.h new file mode 100644 index 00000000..e4edd00b --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/SchemaLoader.h @@ -0,0 +1,54 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief An advanced schema loader. + */ +#ifndef VARIANT_SCHEMALOADER_H +#define VARIANT_SCHEMALOADER_H + +#pragma once + +#include "../../../src/include/Variant/Schema.h" + +namespace libvariant { + + //! The advanced schema loader will try to load missing schemas from + //! the file system and optionally curl if built. + //! If the url begins with file:// it will always use LoadFromFile + //! otherwise if the protocol is empty it will try loading from a file + //! then try loading from curl. Otherwise if the protocol is not file:// + //! it will try to load from curl. + class AdvSchemaLoader : public SchemaLoader { + public: + + //! The advanced schema loader will search for a schema in the paths + //! added to it on the file system. If the schema uri looks like a + //! relative path, then it will be searched for in the paths set with + //! this function. If no paths are added, then only absolute paths will + //! be looked up in the file system. + // + void AddPath(const std::string &path); + + virtual bool HandleMissing(const std::string &uri, LoaderError &error); + protected: + bool LoadFromFile(URIInfo &info, LoaderError &error); + bool LoadFromCurl(URIInfo &info, LoaderError &error); + std::vector< std::string > paths; + }; +} +#endif diff --git a/src/hos_libvariant/src/include/Variant/SharedPtr.h b/src/hos_libvariant/src/include/Variant/SharedPtr.h new file mode 100644 index 00000000..ebefcef4 --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/SharedPtr.h @@ -0,0 +1,41 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_SHAREDPTR_H +#define VARIANT_SHAREDPTR_H + +#pragma once +#include "../../../include/hos_libvariant/Config.h" + +#if defined(__GXX_EXPERIMENTAL_CXX0X) || __cplusplus >= 201103L || defined(HAVE_CXX11_SHAREDPTR) +// The C++11 implementation is available +#include +namespace libvariant { + using std::shared_ptr; + using std::dynamic_pointer_cast; +} + +#elif defined(HAVE_TR1_SHAREDPTR) +// Use the tr1 implementation +#include +namespace libvariant { + using std::tr1::shared_ptr; + using std::tr1::dynamic_pointer_cast; +} + +#elif defined(USE_BOOST_SHAREDPTR) +// Use the boost implementation +#include +namespace libvariant { + using boost::shared_ptr; + using boost::dynamic_pointer_cast; +} + +#else + +#error libvariant requires a shared_ptr implementation + +#endif + +#endif diff --git a/src/hos_libvariant/src/include/Variant/Variant.h b/src/hos_libvariant/src/include/Variant/Variant.h new file mode 100644 index 00000000..3b0173e6 --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/Variant.h @@ -0,0 +1,816 @@ +// vim: foldmethod=marker +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= + +/** \file + * + * \brief Main implementation file for Variant and related functions + */ + + +#ifndef VARIANT_VARIANT_H +#define VARIANT_VARIANT_H + +#pragma once +#include "../../../src/include/Variant/Blob.h" +#include "../../../src/include/Variant/SharedPtr.h" +#include "../../../src/include/Variant/Exceptions.h" +#include "../../../src/include/Variant/VariantInternal.h" +#include +#include +#include +#include +#include +#include +#include + +namespace libvariant { + + /** \brief The Variant class. + * This is a variant type inspired by types from several different + * scripting languages. + * + * \author John Bridgman + * + * This class gives the power and convenience of a scripting language variable + * to C++ with all the same /downsides/ that such a variable has as well. The + * main idea is that things should be simple, lists are behind the scenes an + * std::vector and maps are an std::map. + * + * A Variant may be null, a number, a string, a boolean, a reference to a list, + * or a reference to a map. This means that const Variant of a map is not a + * const map but a const reference. Lists and maps are reference counted. If + * one wants to copy use the Copy member function. + * + * If you need a reference to a Variant to assign to it or change its type, + * use VariantRef. + * A const Variant & should be used for an immutable reference. + * E.g., void foo(VariantRef inout_param, const Variant &in_param); + * That is to say, if you think you want Variant &, you don't, you want + * VariantRef. + * The library is written so that: + * Variant v; + * void bar(Variant &); + * bar(v["foo"]); + * is a compile error. + * But + * Variant v; + * void moo(const Variant &); + * moo(v["moo"]); + * is correct. + * + * + * Note that this implementation will let you create a back reference (i.e., a + * map with itself as a member) but unless the user explicitly breaks it, it + * will result in a memory leak. Checking for this case was deemed too + * expensive. + * + * A Variant will only change its own type if the type is null. That is to say + * that a null Variant that gets treated as a map will become a map. But, a + * Variant of any other type will never automatically convert. + * + */ + class Variant : protected Internal::Data, public VariantDefines { + public: + + typedef VariantRefImpl VariantRef; + + typedef std::vector List; + typedef std::map Map; + + typedef Map::iterator MapIterator; + typedef Map::const_iterator ConstMapIterator; + typedef List::iterator ListIterator; + typedef List::const_iterator ConstListIterator; + + Variant() {} + Variant(VariantDefines::Type_t type) { Assign(type); } + Variant(bool v) { Assign(v); } + + Variant(int v) { Assign(v); } + Variant(unsigned v) { Assign(v); } + Variant(long v) { Assign(v); } + Variant(unsigned long v) { Assign(v); } + Variant(long long v) { Assign(v); } + Variant(unsigned long long v) { Assign(v); } + Variant(double v) { Assign(v); } + Variant(long double v) { Assign(v); } + + Variant(BlobPtr b) { Assign(b); } + + Variant(const std::string &v) { Assign(v); } + Variant(const char *v) { Assign(v); } + Variant(const Variant &v) { Assign(v); } + Variant(const VariantRefImpl &v) { Assign(v); } + + /// Construct a list from a std::vector. + template + Variant(const std::vector &v) { Assign(v); } + + /// Construct a map from a std::map. + template + Variant(const std::map &v) { Assign(v); } + + ~Variant(); + + Variant &operator=(const Variant &o) { Assign(o); return *this; } + + Variant &operator=(VariantDefines::Type_t v) { Assign(v); return *this; } + Variant &operator=(bool v) { Assign(v); return *this; } + Variant &operator=(int v) { Assign(v); return *this; } + Variant &operator=(unsigned v) { Assign(v); return *this; } + Variant &operator=(long v) { Assign(v); return *this; } + Variant &operator=(unsigned long v) { Assign(v); return *this; } + Variant &operator=(long long v) { Assign(v); return *this; } + Variant &operator=(unsigned long long v) { Assign(v); return *this; } + Variant &operator=(double v) { Assign(v); return *this; } + Variant &operator=(long double v) { Assign(v); return *this; } + Variant &operator=(BlobPtr v) { Assign(v); return *this; } + Variant &operator=(const std::string & v) { Assign(v); return *this; } + Variant &operator=(const char * v) { Assign(v); return *this; } + + template + Variant &operator=(const std::vector &v) { Assign(v); return *this; } + template + Variant &operator=(const std::map &v) { Assign(v); return *this; } + + // Type query functions + + Type_t GetType() const; ///< Return the type of this Variant + + bool IsNull() const { return NullType == GetType(); } + bool IsBool() const { return BoolType == GetType(); } + bool IsTrue() const { return (BoolType == GetType()) && AsBool(); } + bool IsFalse() const { return (BoolType == GetType()) && !AsBool(); } + bool IsNumber() const + { return IntegerType == GetType() || UnsignedType == GetType() || FloatType == GetType(); } + bool IsInt() const { return IntegerType == GetType(); } + bool IsUnsigned() const { return UnsignedType == GetType(); } + bool IsFloat() const { return FloatType == GetType(); } + bool IsString() const { return StringType == GetType(); } + bool IsList() const { return ListType == GetType(); } + bool IsMap() const { return MapType == GetType(); } + bool IsBlob() const { return BlobType == GetType(); } + + + // Accessor functions + + bool AsBool() const; ///< Return the value as a bool + long double AsLongDouble() const; ///< Return the value as a long double + double AsDouble() const { return (double)AsLongDouble(); } + uintmax_t AsUnsigned() const; ///< Return the value as an unsigned + intmax_t AsInt() const; ///< Return the value as an integer + template + T AsNumber() const { return static_cast(AsLongDouble()); } + std::string AsString() const; ///< Return the value as a string + BlobPtr AsBlob(); + ConstBlobPtr AsBlob() const; + + template + T As() const; + + /// \brief If the type is string, list, map or blob returns its size, + /// otherwise throws an exception + unsigned Size() const; + + /// \brief If the type is string, list or map return if size == 0 otherwise + /// throw an exception + bool Empty() const; + + /// \brief If the type is string, list or map, empty the container otherwise + /// set type to NullType + void Clear(); + + // List specific accessors + List &AsList(); + const List &AsList() const; + ListIterator ListBegin() ///< Equivalent to AsList().begin() + { return AsList().begin(); } + ConstListIterator ListBegin() const ///< Equivalent to AsList().begin() + { return AsList().begin(); } + ListIterator ListEnd() ///< Equivalent to AsList().end() + { return AsList().end(); } + ConstListIterator ListEnd() const ///< Equivalent to AsList().end() + { return AsList().end(); } + VariantRef At(unsigned i); //< Return a proxy/reference to the element at index i + VariantRef At(unsigned i, Variant def); //< sets to def if doesn't exist + const Variant &At(unsigned i) const; + Variant Get(unsigned i) const; //< Return the element at index i or throw + Variant Get(unsigned i, Variant def) const; //< Return the element at index i or return def + Variant &Set(unsigned i, Variant v); //< Set the element at index i to v + /// \brief Only valid when of type ListType Returns *this, so you can + /// do Variant().Append(v1).Append(v2)... + Variant &Append(Variant value); + + /// \brief If list return true if list is at least i in size, if map then convert i + /// to a string, otherwise throw + bool Contains(unsigned i) const; + /// \brief Return the index hat v is at. + /// If v is not contained in the list it return this->Size() + unsigned Index(Variant v) const; + + /// \brief If list set index i to null, if index at end, reduce size by 1 + /// throw if not a list + void Erase(unsigned i); + + // Map specific accessors + Map &AsMap(); + const Map &AsMap() const; + MapIterator MapBegin() ///< Equivalent to AsMap().begin() + { return AsMap().begin(); } + ConstMapIterator MapBegin() const ///< Equivalent to AsMap().begin() + { return AsMap().begin(); } + MapIterator MapEnd() ///< Equivalent to AsMap().end() + { return AsMap().end(); } + ConstMapIterator MapEnd() const ///< Equivalent to AsMap().end() + { return AsMap().end(); } + VariantRef At(const std::string &s); // Return a proxy/reference to the element at key s + VariantRef At(const std::string &s, Variant def); //< Sets to def if doesn't exist and return a reference to it + const Variant &At(const std::string &s) const; + + /// \brief If s in *this: return this->At(s); else throw; + Variant Get(const std::string &s) const; + /// \brief If s in *this: return this->At(s); else return def + /// Only works if type is map + Variant Get(const std::string &s, Variant def) const; + + /// \brief Set the key s to v + // returns *this + Variant &Set(const std::string &s, Variant v); + + /// \brief If map return true if s is a key in the map, if list then convert + /// s to an unsigned and the above Contains, otherwise throw + bool Contains(const std::string &s) const; + /// \brief Erase a key in a map, throws if type is not MapType + void Erase(const std::string &key); + + VariantRef operator[](int i) { return At(i); } + const Variant &operator[](int i) const { return At(i); } + + VariantRef operator[](unsigned i) { return At(i); } + const Variant &operator[](unsigned i) const { return At(i); } + + VariantRef operator[](const std::string &s) { return At(s); } + const Variant &operator[](const std::string &s) const { return At(s); } + + // Path related accessors + // These are the same as the non-path functions but take a path instead. + VariantRef AtPath(const Path &path); + VariantRef AtPath(const std::string &path) { return AtPath(ParsePath(path)); } + VariantRef AtPath(const Path &path, Variant def); + VariantRef AtPath(const std::string &path, Variant def) { return AtPath(ParsePath(path), def); } + const Variant &AtPath(const Path &path) const; + const Variant &AtPath(const std::string &path) const { return AtPath(ParsePath(path)); } + + /// \brief Like Variant::Get but it takes a path instead. + Variant GetPath(const Path &path) const; + Variant GetPath(const std::string &path) const { return GetPath(ParsePath(path)); } + /// \brief Like Variant::Get but it takes a path instead. The path is + /// very like xpath, /key[index]/key/key. See Variant/Path.h + Variant GetPath(const Path &path, Variant def) const; + Variant GetPath(const std::string &path, Variant def) const { return GetPath(ParsePath(path), def); } + + /// \brief Set the value at the path, creating elements if they do not + /// exist. throws if an intermediate path element exists but is not a + /// map or list. returns *this + Variant &SetPath(const Path &path, Variant val); + Variant &SetPath(const std::string &path, Variant val) { return SetPath(ParsePath(path), val); } + + /// \brief Erase a value at a path, if remove_empty is false only erase the very end + /// otherwise erase empty lists and maps in the path. returns *this + Variant &ErasePath(const Path &path, bool remove_empty=false); + Variant &ErasePath(const std::string &path, bool remove_empty=false) + { return ErasePath(ParsePath(path), remove_empty); } + + /// \brief Tester functions for paths, returns true if path is valid and exists. + bool HasPath(const Path &path) const; + bool HasPath(const std::string &path) const { return HasPath(ParsePath(path)); } + + /// \brief Just like Variant::Get except a reference to the value to + /// set is passed in and Variant does the casting. + template + void GetInto(T &lvalue, const std::string &s) const; + + /// \brief An into version of GetPath + template + void GetPathInto(T &lvalue, const Path &path) const; + template + void GetPathInto(T &lvalue, const std::string &path) const + { GetPathInto(lvalue, ParsePath(path)); } + + /// \brief Just like Variant::Get except a reference to the value to + /// set is passed in and Variant does the casting. + template + void GetInto(T &lvalue, const std::string &s, const T &def) const; + + /// \brief An into version of GetPath + template + void GetPathInto(T &lvalue, const Path &path, const T &def) const; + template + void GetPathInto(T &lvalue, const std::string &path, const T &def) const + { GetPathInto(lvalue, ParsePath(path), def); } + + /// \brief This type and other type must be MapType. + /// for (k, v) in other: this[k] = v + void Merge(Variant other); + + /// \brief Comparison operator + /// Returns -1 if we are less than other + /// 0 if we are equal + /// 1 if we are greater than + /// This function always returns 1 if Comparable returns false + /// This compare is not completely consistent + /// i.e. it can be such that two Variants are + /// both < and > (ex map and list types) + int Compare(const Variant &other) const; + + /// \brief Return true if this and other are comparable. Two types are + /// considered comparable if they have the same type or if they are both + /// number types. + bool Comparable(const Variant &other) const; + + void Incr(); + void Decr(); + void Add(const Variant &o); + void Sub(const Variant &o); + void Mul(const Variant &o); + void Div(const Variant &o); + void Rem(const Variant &o); + + Variant Neg() const; + + Variant &operator++() { Incr(); return *this; } + Variant &operator--() { Decr(); return *this; } + Variant operator++(int) { Variant tmp = *this; ++(*this); return tmp; } + Variant operator--(int) { Variant tmp = *this; --(*this); return tmp; } + Variant operator-() const { return Neg(); } + Variant operator+() const { return *this; } + + Variant &operator+=(const Variant &o) { Add(o); return *this; } + Variant &operator-=(const Variant &o) { Sub(o); return *this; } + Variant &operator*=(const Variant &o) { Mul(o); return *this; } + Variant &operator/=(const Variant &o) { Div(o); return *this; } + Variant &operator%=(const Variant &o) { Rem(o); return *this; } + + VariantRef Ref(); //< Return a new VariantRef to this Variant + Variant Copy() const; //< Return a copy of this Variant + Variant &Resolve(); //< Return *this or return the Variant this is a reference to + const Variant &Resolve() const; + /// Return *this or Variant referenced to if exists, otherwise create it with def. + Variant &Resolve(const Variant &def); + /// Return weather or not Resolve() const would throw. + bool Exists() const; + + /// Make this equal other. + void Assign(const Variant &other); + + void Assign(VariantDefines::Type_t type); + void Assign(bool v); + void Assign(int v); + void Assign(unsigned v); + void Assign(long v); + void Assign(unsigned long v); + void Assign(long long v); + void Assign(unsigned long long v); + void Assign(double v); + void Assign(long double v); + void Assign(BlobPtr b); + void Assign(const std::string &v); + void Assign(const char *v); + + template + void Assign(const std::vector &v) { + Assign(VariantDefines::ListType); + AsList().assign(v.begin(), v.end()); + } + + template + void Assign(const std::map &v) { + Assign(VariantDefines::MapType); + AsMap().insert(v.begin(), v.end()); + } + + protected: + Variant(const RefTag &, const Variant &o); + Variant(const RefTag &, Variant &o, Path::const_iterator b, Path::const_iterator e); + /// Reassing this reference, only available through the VariantRef interface. + /// The regular Assign makes what this is refering to equal the new value, this + /// function makes this reference refer to the new value. + void ReassignRef(const Variant &o); + friend class Internal::VTable; + }; + + typedef VariantRefImpl VariantRef; + + inline bool operator==(const Variant &lhs, const Variant &rhs) { return lhs.Compare(rhs) == 0; } + inline bool operator!=(const Variant &lhs, const Variant &rhs) { return lhs.Compare(rhs) != 0; } + inline bool operator<(const Variant &lhs, const Variant &rhs) { return lhs.Compare(rhs) < 0; } + inline bool operator>(const Variant &lhs, const Variant &rhs) { return lhs.Compare(rhs) > 0; } + inline bool operator<=(const Variant &lhs, const Variant &rhs) { return lhs.Compare(rhs) <= 0; } + inline bool operator>=(const Variant &lhs, const Variant &rhs) { return lhs.Compare(rhs) >= 0; } + + inline Variant operator+(const Variant &lhs, const Variant &rhs) { + Variant ret = lhs; + return ret += rhs; + } + inline Variant operator-(const Variant &lhs, const Variant &rhs) { + Variant ret = lhs; + return ret -= rhs; + } + inline Variant operator*(const Variant &lhs, const Variant &rhs) { + Variant ret = lhs; + return ret *= rhs; + } + inline Variant operator/(const Variant &lhs, const Variant &rhs) { + Variant ret = lhs; + return ret /= rhs; + } + inline Variant operator%(const Variant &lhs, const Variant &rhs) { + Variant ret = lhs; + return ret %= rhs; + } + + /// \defgroup variant_cast Template casting operators. + /// These are for use inside templates to extract the value of a Variant into + /// a templated type. + /// @{ + + template + struct VariantCaster { + static T Cast(const Variant &v); + }; + + // Default + template inline T VariantCaster::Cast(const Variant &v) { return T(v); } + + template + inline T variant_cast(const Variant &v) { return VariantCaster::Cast(v); } + + // Provide specializations for all the basic types + template<> inline bool VariantCaster::Cast(const Variant &v) { return v.AsBool(); } + template<> inline char VariantCaster::Cast(const Variant &v) { return (char)v.AsInt(); } + template<> inline unsigned char VariantCaster::Cast(const Variant &v) { return (unsigned char)v.AsUnsigned(); } + template<> inline signed char VariantCaster::Cast(const Variant &v) { return (signed char)v.AsUnsigned(); } + template<> inline short VariantCaster::Cast(const Variant &v) { return (short)v.AsInt(); } + template<> inline unsigned short VariantCaster::Cast(const Variant &v) { return (unsigned short)v.AsUnsigned(); } + template<> inline int VariantCaster::Cast(const Variant &v) { return (int)v.AsInt(); } + template<> inline unsigned VariantCaster::Cast(const Variant &v) { return (unsigned)v.AsUnsigned(); } + template<> inline long VariantCaster::Cast(const Variant &v) { return (long)v.AsInt(); } + template<> inline unsigned long VariantCaster::Cast(const Variant &v) { return (unsigned long)v.AsUnsigned(); } + template<> inline long long VariantCaster::Cast(const Variant &v) { return (long long)v.AsInt(); } + template<> inline unsigned long long VariantCaster::Cast(const Variant &v) { return (unsigned long long)v.AsUnsigned(); } + template<> inline float VariantCaster::Cast(const Variant &v) { return (float)v.AsDouble(); } + template<> inline double VariantCaster::Cast(const Variant &v) { return v.AsDouble(); } + template<> inline long double VariantCaster::Cast(const Variant &v) { return v.AsLongDouble(); } + template<> inline std::string VariantCaster::Cast(const Variant &v) { return v.AsString(); } + + // Allow things like variant_cast< std::vector >(v) to work + template + struct VariantCaster< std::vector > { + static std::vector Cast(const Variant &v); + }; + + template + inline std::vector VariantCaster< std::vector >::Cast(const Variant &v) { + std::vector ret; + for (Variant::ConstListIterator i(v.ListBegin()), e(v.ListEnd()); i != e; ++i) { + ret.push_back( variant_cast( *i ) ); + } + return ret; + } + + template<> inline Variant::List VariantCaster::Cast(const Variant &v) { return v.AsList(); } + + // allow things like variant_cast< std::map >(v) + // to work + template + struct VariantCaster< std::map > { + static std::map Cast(const Variant &v); + }; + + template + inline std::map VariantCaster< std::map >::Cast(const Variant &v) { + std::map ret; + for (Variant::ConstMapIterator i(v.MapBegin()), e(v.MapEnd()); i != e; ++i) { + ret.insert( std::make_pair( i->first, variant_cast( i->second ) ) ); + } + return ret; + } + + template<> inline Variant::Map VariantCaster::Cast(const Variant &v) { return v.AsMap(); } + + template + struct VariantCaster< std::complex > { + static std::complex Cast(const Variant &v); + }; + + template + std::complex VariantCaster< std::complex >::Cast(const Variant &v) { + if (v.IsNull()) { + return std::complex(); + } else if (v.IsNumber()) { + return std::complex(v.As(), T()); + } else if (v.IsMap()) { + T r = variant_cast(v.Get("real", T())); + T c = variant_cast(v.Get("imag", T())); + return std::complex(r, c); + } else if (v.IsList()) { + if (v.Size() > 1) { + return std::complex(v[0].As(), v[1].As()); + } else if (v.Size() > 0) { + return std::complex(v[0].As(), T()); + } else { + return std::complex(); + } + } + throw UnableToConvertError(v.GetType(), "std::complex"); + } + + /// @} + + template + T Variant::As() const { return variant_cast(*this); } + + template + void Variant::GetInto(T &lvalue, const std::string &s) const { + lvalue = variant_cast(Get(s)); + } + + template + void Variant::GetPathInto(T &lvalue, const Path &p) const { + lvalue = variant_cast(GetPath(p)); + } + + template + void Variant::GetInto(T &lvalue, const std::string &s, const T &def) const { + if (Contains(s)) { lvalue = variant_cast(Get(s)); } + else { lvalue = def; } + } + + template + void Variant::GetPathInto(T &lvalue, const Path &p, const T &def) const { + lvalue = variant_cast(GetPath(p, def)); + } + + class Parser; + /// \brief Takes a parser and produces a Variant from it. + Variant ParseVariant(Parser &p); + + class Emitter; + /// Takes a Variant and Emitter and emits the Variant. + Emitter &operator<<(Emitter &e, const Variant &v); + + /// \brief The different types of serialization supported. + enum SerializeType { + // Attempt to guess the format + // Cannot be specified as an output format. + SERIALIZE_GUESS = 0x0, + + // Built in text formats + SERIALIZE_JSON = 0x00000001, + SERIALIZE_YAML, + SERIALIZE_XMLPLIST, + SERIALIZE_BUNDLEHDR, + + // Built in binary formats + SERIALIZE_MSGPACK = 0x000000FF, + + }; + + + /// \brief An iterator that iterates over all documents that the parser will generate + class LoadAllIterator { + public: + typedef Variant value_type; + typedef ptrdiff_t difference_type; + typedef Variant* pointer; + typedef Variant& reference; + typedef std::forward_iterator_tag iterator_category; + + LoadAllIterator(); + explicit LoadAllIterator(Parser &parser); + Variant &operator*() { return Get(); } + Variant *operator->() { return &Get(); } + Variant &Get(); + void Next(); + LoadAllIterator &operator++() { + Next(); + return *this; + } + LoadAllIterator operator++(int) { + LoadAllIterator copy = *this; + Next(); + return copy; + } + bool operator==(const LoadAllIterator &that) const; + bool operator!=(const LoadAllIterator &that) const { return !(*this == that); } + private: + class Impl; + shared_ptr impl; + struct Value; + shared_ptr value; + }; + + // Some convenience functions + // A version is provided that will go to/from a string, + // a memory buffer, a file name, an open FILE*, and + // a streambuf* (usually acquired through iostream.rdbuf()). + + /// \brief Serialize a Variant to a string using format type. + std::string Serialize(Variant v, SerializeType type, Variant params = Variant::NullType); + /// \brief Serialize a Variant to a file using format type. + void Serialize(const std::string &filename, Variant v, SerializeType type, + Variant params = Variant::NullType); + /// \brief Serialize a Variant to a FILE pointer using format type. + void Serialize(FILE *f, Variant v, SerializeType type, + Variant params = Variant::NullType); + /// \brief Serialize a Variant to a streambuf* (iostrem.rdbuf()) using format type. + void Serialize(std::streambuf *sb, Variant v, SerializeType type, + Variant params = Variant::NullType); + /// \brief Serialize a Variant to a memory buffer of length len, using format type + //and return how many bytes produced. + unsigned Serialize(void *ptr, unsigned len, Variant v, SerializeType type, + Variant params = Variant::NullType); + + // The basic deserializing functions + + /// \brief Attempt to deserialize a string in format type to a Variant + Variant Deserialize(const std::string &str, SerializeType type); + /// \brief Attempt to deserialize a null terminated string in format type to a Variant + Variant Deserialize(const char *str, SerializeType type); + /// \brief Attempt to deserialize a pointer and length in format type to a Variant + Variant Deserialize(const void *ptr, unsigned len, SerializeType type); + /// \brief Attempt to deserialize the file to a Variant in format type + Variant DeserializeFile(const char *filename, SerializeType type); + /// \brief Deserialize from a FILE pointer to a Variant in format type + Variant DeserializeFile(FILE *f, SerializeType type); + /// \brief Deserialize from a streambuf to a Variant in format type + Variant DeserializeFile(std::streambuf *sb, SerializeType type); + + /// \defgroup deserialize_guess Guess format + /// These functions attempt to guess the type of the input. The guessing + /// function only looks at the first non-whitespace character to make the + /// decision. As such on sufficiently badly behaved input can select the + /// wrong format. + /// @{ + Variant DeserializeGuess(const std::string &str); + Variant DeserializeGuess(const char *str); + Variant DeserializeGuess(const void *ptr, unsigned len); + Variant DeserializeGuessFile(const char *filename); + Variant DeserializeGuessFile(FILE *f); + Variant DeserializeGuessFile(std::streambuf *sb); + /// @} + + /// \defgroup deserialize_all Deserialize all elements + /// These functions return an iterator. These are for format types that + /// support multiple documents in one stream. Otherwise same as Deserialize + /// functions above. + /// @{ + LoadAllIterator DeserializeAll(const std::string &str, SerializeType type); + LoadAllIterator DeserializeAll(const char *str, SerializeType type); + LoadAllIterator DeserializeAll(const void *ptr, unsigned len, SerializeType type); + LoadAllIterator DeserializeAllFile(const char *filename, SerializeType type); + /// File must remain open for as long as the iterator is referenced + LoadAllIterator DeserializeAllFile(FILE *f, SerializeType type); + /// Streambuf must exist for as long as the iterator is referenced + LoadAllIterator DeserializeAllFile(std::streambuf *sb, SerializeType type); + /// @} + + + // Serialize and Deserializing JSON + // + inline std::string SerializeJSON(Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + return Serialize(v, SERIALIZE_JSON, param); + } + inline void SerializeJSON(const std::string &filename, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + Serialize(filename, v, SERIALIZE_JSON, param); + } + inline void SerializeJSON(FILE *f, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + Serialize(f, v, SERIALIZE_JSON, param); + } + inline void SerializeJSON(std::streambuf *sb, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + Serialize(sb, v, SERIALIZE_JSON, param); + } + inline unsigned SerializeJSON(void *ptr, unsigned len, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + return Serialize(ptr, len, v, SERIALIZE_JSON, param); + } + inline Variant DeserializeJSON(const std::string &str) { return Deserialize(str, SERIALIZE_JSON); } + inline Variant DeserializeJSON(const char *str) { return Deserialize(str, SERIALIZE_JSON); } + inline Variant DeserializeJSON(const void *ptr, unsigned len) { return Deserialize(ptr, len, SERIALIZE_JSON); } + inline Variant DeserializeJSONFile(const char *filename) { return DeserializeFile(filename, SERIALIZE_JSON); } + inline Variant DeserializeJSONFile(FILE *f) { return DeserializeFile(f, SERIALIZE_JSON); } + inline Variant DeserializeJSONFile(std::streambuf *sb) { return DeserializeFile(sb, SERIALIZE_JSON); } + + //Serialize and Deserialize YAML + // + inline std::string SerializeYAML(Variant v) { return Serialize(v, SERIALIZE_YAML); } + inline void SerializeYAML(const std::string &filename, Variant v) { Serialize(filename, v, SERIALIZE_YAML); } + inline void SerializeYAML(FILE *f, Variant v) { Serialize(f, v, SERIALIZE_YAML); } + inline void SerializeYAML(std::streambuf *sb, Variant v) { Serialize(sb, v, SERIALIZE_YAML); } + inline unsigned SerializeYAML(void *ptr, unsigned len, Variant v) { return Serialize(ptr, len, v, SERIALIZE_YAML); } + + inline Variant DeserializeYAML(const std::string &str) { return Deserialize(str, SERIALIZE_YAML); } + inline Variant DeserializeYAML(const char *str) { return Deserialize(str, SERIALIZE_YAML); } + inline Variant DeserializeYAML(const void *ptr, unsigned len) { return Deserialize(ptr, len, SERIALIZE_YAML); } + inline Variant DeserializeYAMLFile(const char *filename) { return DeserializeFile(filename, SERIALIZE_YAML); } + inline Variant DeserializeYAMLFile(FILE *f) { return DeserializeFile(f, SERIALIZE_YAML); } + inline Variant DeserializeYAMLFile(std::streambuf *sb) { return DeserializeFile(sb, SERIALIZE_YAML); } + + inline LoadAllIterator DeserializeYAMLAll(const std::string &str) { return DeserializeAll(str, SERIALIZE_YAML); } + inline LoadAllIterator DeserializeYAMLAll(const char *str) { return DeserializeAll(str, SERIALIZE_YAML); } + inline LoadAllIterator DeserializeYAMLAll(const void *ptr, unsigned len) { return DeserializeAll(ptr, len, SERIALIZE_YAML); } + inline LoadAllIterator DeserializeYAMLAllFile(const char *filename) { return DeserializeAllFile(filename, SERIALIZE_YAML); } + inline LoadAllIterator DeserializeYAMLAllFile(FILE *f) { return DeserializeAllFile(f, SERIALIZE_YAML); } + inline LoadAllIterator DeserializeYAMLAllFile(std::streambuf *sb) { return DeserializeAllFile(sb, SERIALIZE_YAML); } + + //Serialize and Deserialize XML plist + // + inline std::string SerializeXMLPLIST(Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + return Serialize(v, SERIALIZE_XMLPLIST, param); + } + inline void SerializeXMLPLIST(const std::string &filename, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + Serialize(filename, v, SERIALIZE_XMLPLIST, param); + } + inline void SerializeXMLPLIST(FILE *f, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + Serialize(f, v, SERIALIZE_XMLPLIST, param); + } + inline void SerializeXMLPLIST(std::streambuf *sb, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + Serialize(sb, v, SERIALIZE_XMLPLIST, param); + } + inline unsigned SerializeXMLPLIST(void *ptr, unsigned len, Variant v, bool pretty=false) { + Variant param = Variant::MapType; param["pretty"] = pretty; + return Serialize(ptr, len, v, SERIALIZE_XMLPLIST, param); + } + + inline Variant DeserializeXMLPLIST(const std::string &str) { return Deserialize(str, SERIALIZE_XMLPLIST); } + inline Variant DeserializeXMLPLIST(const char *str) { return Deserialize(str, SERIALIZE_XMLPLIST); } + inline Variant DeserializeXMLPLIST(const void *ptr, unsigned len) { return Deserialize(ptr, len, SERIALIZE_XMLPLIST); } + inline Variant DeserializeXMLPLISTFile(const char *filename) { return DeserializeFile(filename, SERIALIZE_XMLPLIST); } + inline Variant DeserializeXMLPLISTFile(FILE *f) { return DeserializeFile(f, SERIALIZE_XMLPLIST); } + inline Variant DeserializeXMLPLISTFile(std::streambuf *sb) { return DeserializeFile(sb, SERIALIZE_XMLPLIST); } + + //Serialize and Deserialize BundleHdr + // + // BundleHdr requires the root element to be of MapType and + // no submaps exist. + // + // Note that these do not add a null byte to the end. + // Use SerializeBundle for that. + + inline std::string SerializeBundleHdr(Variant v) { + Variant param = Variant::MapType; + return Serialize(v, SERIALIZE_BUNDLEHDR, param); + } + inline void SerializeBundleHdr(const std::string &filename, Variant v) { + Variant param = Variant::MapType; + Serialize(filename, v, SERIALIZE_BUNDLEHDR, param); + } + inline void SerializeBundleHdr(FILE *f, Variant v) { + Variant param = Variant::MapType; + Serialize(f, v, SERIALIZE_BUNDLEHDR, param); + } + inline void SerializeBundleHdr(std::streambuf *sb, Variant v) { + Variant param = Variant::MapType; + Serialize(sb, v, SERIALIZE_BUNDLEHDR, param); + } + inline unsigned SerializeBundleHdr(void *ptr, unsigned len, Variant v) { + Variant param = Variant::MapType; + return Serialize(ptr, len, v, SERIALIZE_BUNDLEHDR, param); + } + + inline Variant DeserializeBundleHdr(const std::string &str) { return Deserialize(str, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleHdr(const char *str) { return Deserialize(str, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleHdr(const void *ptr, unsigned len) { return Deserialize(ptr, len, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleHdrFile(const char *filename) { return DeserializeFile(filename, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleHdrFile(FILE *f) { return DeserializeFile(f, SERIALIZE_BUNDLEHDR); } + inline Variant DeserializeBundleHdrFile(std::streambuf *sb) { return DeserializeFile(sb, SERIALIZE_BUNDLEHDR); } + +} + +/// Debug function not inside the namespace to print out a variant (calls SerializeJSON) +void VariantPrint(const libvariant::Variant v); + +#endif diff --git a/src/hos_libvariant/src/include/Variant/VariantDefines.h b/src/hos_libvariant/src/include/Variant/VariantDefines.h new file mode 100644 index 00000000..6a6df997 --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/VariantDefines.h @@ -0,0 +1,50 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_DEFINES_H +#define VARIANT_DEFINES_H + +#ifdef __GNUC__ +#define DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define DEPRECATED __declspec(deprecated) +#else +#pragma message("WARNING: You need to implement DEPRECATED for this compiler") +#define DEPRECATED +#endif + +namespace libvariant { + class VariantDefines { + public: + enum Type_t { + NullType = 0, // Explicitly defined as 0 + BoolType, + IntegerType, + UnsignedType, + FloatType, + StringType, + ListType, + MapType, + BlobType + }; + + }; +} +#endif diff --git a/src/hos_libvariant/src/include/Variant/VariantInternal.h b/src/hos_libvariant/src/include/Variant/VariantInternal.h new file mode 100644 index 00000000..5d9ed0f3 --- /dev/null +++ b/src/hos_libvariant/src/include/Variant/VariantInternal.h @@ -0,0 +1,95 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_BASE_H +#define VARIANT_BASE_H +#include +#include +#include +#include +#include +#include +#include +#include +namespace libvariant { + + struct RefTag {}; + + class Variant; + template class VariantRefImpl; + + + /** + * Action implementation for the VariantRef class. + */ + template + class VariantRefImpl : public Base { + public: + VariantRefImpl(const Variant &o) : Base(RefTag(), o) {} + VariantRefImpl(Variant &o, const Path &path) + : Base(RefTag(), o, path.begin(), path.end()) {} + VariantRefImpl(Variant &o, Path::const_iterator b, Path::const_iterator e) + : Base(RefTag(), o, b, e) {} + VariantRefImpl(const VariantRefImpl &o) + : Base(RefTag(), o) {} + + using Base::operator=; + using Base::As; + using Base::AsNumber; + using Base::GetInto; + using Base::GetPathInto; + using Base::Assign; + + using Base::ReassignRef; + }; + + namespace Internal { + + class VTable; + struct Storage; + struct MapStorage; + struct ListStorage; + struct ProxyStorage; + struct RefData; + + struct Data { + Data(); + const VTable *vtable; + union { + bool b; + long double f; + intmax_t i; + uintmax_t u; + std::string *s; + MapStorage *m; + ListStorage *l; + BlobPtr *blob; + Data *ref; + ProxyStorage *proxy; + }; + shared_ptr ref_data; + shared_ptr storage; + }; + } + + + +} +#endif diff --git a/src/hos_libvariant/src/lib/json/JSON_PARSER_README.htm b/src/hos_libvariant/src/lib/json/JSON_PARSER_README.htm new file mode 100644 index 00000000..b4bfe0d9 --- /dev/null +++ b/src/hos_libvariant/src/lib/json/JSON_PARSER_README.htm @@ -0,0 +1,16 @@ +A JSON parser based on http://www.json.org's JSON_checker code. + +Copyright (c) 2007-2009 Jean Gressmann (jean@0x42.de). + +For license information, see JSON_parser.c. + +JSON parser features: +- arbitrary levels of JSON object/array nesting, +- C-style comments, +- UTF-16 & escape sequence (\uXXXX) decoding to UTF-8. +- Manual processing of floating point values. + +The parser processes UTF-8 encoded JSON only. +JSON object keys and JSON strings are returned as UTF-8 encoded C strings. + + diff --git a/src/hos_libvariant/src/lib/json/JSON_parser.c b/src/hos_libvariant/src/lib/json/JSON_parser.c new file mode 100644 index 00000000..b70c9ae0 --- /dev/null +++ b/src/hos_libvariant/src/lib/json/JSON_parser.c @@ -0,0 +1,1013 @@ +/* +Copyright (c) 2005 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/* + Callbacks, comments, Unicode handling by Jean Gressmann (jean@0x42.de), 2007-2009. + + Changelog: + 2009-10-19 + Replaced long double in JSON_value_struct with double after reports + of strtold being broken on some platforms (charles@transmissionbt.com). + + 2009-05-17 + Incorporated benrudiak@googlemail.com fix for UTF16 decoding. + + 2009-05-14 + Fixed float parsing bug related to a locale being set that didn't + use '.' as decimal point character (charles@transmissionbt.com). + + 2008-10-14 + Renamed states.IN to states.IT to avoid name clash which IN macro + defined in windef.h (alexey.pelykh@gmail.com) + + 2008-07-19 + Removed some duplicate code & debugging variable (charles@transmissionbt.com) + + 2008-05-28 + Made JSON_value structure ansi C compliant. This bug was report by + trisk@acm.jhu.edu + + 2008-05-20 + Fixed bug reported by charles@transmissionbt.com where the switching + from static to dynamic parse buffer did not copy the static parse + buffer's content. +*/ + + + +#include "../../../src/lib/json/JSON_parser.h" + +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef _MSC_VER +# if _MSC_VER >= 1400 /* Visual Studio 2005 and up */ +# pragma warning(disable:4996) // unsecure sscanf +# endif +#endif + + +#define true 1 +#define false 0 +#define __ -1 /* the universal error code */ + +/* values chosen so that the object size is approx equal to one page (4K) */ +#ifndef JSON_PARSER_STACK_SIZE +# define JSON_PARSER_STACK_SIZE 128 +#endif + +#ifndef JSON_PARSER_PARSE_BUFFER_SIZE +# define JSON_PARSER_PARSE_BUFFER_SIZE 3500 +#endif + +typedef unsigned short UTF16; + +struct JSON_parser_struct { + JSON_parser_callback callback; + void* ctx; + signed char state, before_comment_state, type, escaped, comment, allow_comments, handle_floats_manually; + UTF16 utf16_high_surrogate; + long depth; + long top; + signed char* stack; + long stack_capacity; + char decimal_point; + char* parse_buffer; + size_t parse_buffer_capacity; + size_t parse_buffer_count; + size_t comment_begin_offset; + signed char static_stack[JSON_PARSER_STACK_SIZE]; + char static_parse_buffer[JSON_PARSER_PARSE_BUFFER_SIZE]; +}; + +#define COUNTOF(x) (sizeof(x)/sizeof(x[0])) + +/* + Characters are mapped into these character classes. This allows for + a significant reduction in the size of the state transition table. +*/ + + + +enum classes { + C_SPACE, /* space */ + C_WHITE, /* other whitespace */ + C_LCURB, /* { */ + C_RCURB, /* } */ + C_LSQRB, /* [ */ + C_RSQRB, /* ] */ + C_COLON, /* : */ + C_COMMA, /* , */ + C_QUOTE, /* " */ + C_BACKS, /* \ */ + C_SLASH, /* / */ + C_PLUS, /* + */ + C_MINUS, /* - */ + C_POINT, /* . */ + C_ZERO , /* 0 */ + C_DIGIT, /* 123456789 */ + C_LOW_A, /* a */ + C_LOW_B, /* b */ + C_LOW_C, /* c */ + C_LOW_D, /* d */ + C_LOW_E, /* e */ + C_LOW_F, /* f */ + C_LOW_L, /* l */ + C_LOW_N, /* n */ + C_LOW_R, /* r */ + C_LOW_S, /* s */ + C_LOW_T, /* t */ + C_LOW_U, /* u */ + C_ABCDF, /* ABCDF */ + C_E, /* E */ + C_ETC, /* everything else */ + C_STAR, /* * */ + NR_CLASSES +}; + +static int ascii_class[128] = { +/* + This array maps the 128 ASCII characters into character classes. + The remaining Unicode characters should be mapped to C_ETC. + Non-whitespace control characters are errors. +*/ + __, __, __, __, __, __, __, __, + __, C_WHITE, C_WHITE, __, __, C_WHITE, __, __, + __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, + + C_SPACE, C_ETC, C_QUOTE, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, + C_ETC, C_ETC, C_STAR, C_PLUS, C_COMMA, C_MINUS, C_POINT, C_SLASH, + C_ZERO, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, + C_DIGIT, C_DIGIT, C_COLON, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, + + C_ETC, C_ABCDF, C_ABCDF, C_ABCDF, C_ABCDF, C_E, C_ABCDF, C_ETC, + C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, + C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, C_ETC, + C_ETC, C_ETC, C_ETC, C_LSQRB, C_BACKS, C_RSQRB, C_ETC, C_ETC, + + C_ETC, C_LOW_A, C_LOW_B, C_LOW_C, C_LOW_D, C_LOW_E, C_LOW_F, C_ETC, + C_ETC, C_ETC, C_ETC, C_ETC, C_LOW_L, C_ETC, C_LOW_N, C_ETC, + C_ETC, C_ETC, C_LOW_R, C_LOW_S, C_LOW_T, C_LOW_U, C_ETC, C_ETC, + C_ETC, C_ETC, C_ETC, C_LCURB, C_ETC, C_RCURB, C_ETC, C_ETC +}; + + +/* + The state codes. +*/ +enum states { + GO, /* start */ + OK, /* ok */ + OB, /* object */ + KE, /* key */ + CO, /* colon */ + VA, /* value */ + AR, /* array */ + ST, /* string */ + ES, /* escape */ + U1, /* u1 */ + U2, /* u2 */ + U3, /* u3 */ + U4, /* u4 */ + MI, /* minus */ + ZE, /* zero */ + IT, /* integer */ + FR, /* fraction */ + E1, /* e */ + E2, /* ex */ + E3, /* exp */ + T1, /* tr */ + T2, /* tru */ + T3, /* true */ + F1, /* fa */ + F2, /* fal */ + F3, /* fals */ + F4, /* false */ + N1, /* nu */ + N2, /* nul */ + N3, /* null */ + C1, /* / */ + C2, /* / * */ + C3, /* * */ + FX, /* *.* *eE* */ + D1, /* second UTF-16 character decoding started by \ */ + D2, /* second UTF-16 character proceeded by u */ + NR_STATES +}; + +enum actions +{ + CB = -10, /* comment begin */ + CE = -11, /* comment end */ + FA = -12, /* false */ + TR = -13, /* false */ + NU = -14, /* null */ + DE = -15, /* double detected by exponent e E */ + DF = -16, /* double detected by fraction . */ + SB = -17, /* string begin */ + MX = -18, /* integer detected by minus */ + ZX = -19, /* integer detected by zero */ + IX = -20, /* integer detected by 1-9 */ + EX = -21, /* next char is escaped */ + UC = -22 /* Unicode character read */ +}; + + +static int state_transition_table[NR_STATES][NR_CLASSES] = { +/* + The state transition table takes the current state and the current symbol, + and returns either a new state or an action. An action is represented as a + negative number. A JSON text is accepted if at the end of the text the + state is OK and if the mode is MODE_DONE. + + white 1-9 ABCDF etc + space | { } [ ] : , " \ / + - . 0 | a b c d e f l n r s t u | E | * */ +/*start GO*/ {GO,GO,-6,__,-5,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__}, +/*ok OK*/ {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__}, +/*object OB*/ {OB,OB,__,-9,__,__,__,__,SB,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__}, +/*key KE*/ {KE,KE,__,__,__,__,__,__,SB,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__}, +/*colon CO*/ {CO,CO,__,__,__,__,-2,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__}, +/*value VA*/ {VA,VA,-6,__,-5,__,__,__,SB,__,CB,__,MX,__,ZX,IX,__,__,__,__,__,FA,__,NU,__,__,TR,__,__,__,__,__}, +/*array AR*/ {AR,AR,-6,__,-5,-7,__,__,SB,__,CB,__,MX,__,ZX,IX,__,__,__,__,__,FA,__,NU,__,__,TR,__,__,__,__,__}, +/*string ST*/ {ST,__,ST,ST,ST,ST,ST,ST,-4,EX,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST,ST}, +/*escape ES*/ {__,__,__,__,__,__,__,__,ST,ST,ST,__,__,__,__,__,__,ST,__,__,__,ST,__,ST,ST,__,ST,U1,__,__,__,__}, +/*u1 U1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U2,U2,U2,U2,U2,U2,U2,U2,__,__,__,__,__,__,U2,U2,__,__}, +/*u2 U2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U3,U3,U3,U3,U3,U3,U3,U3,__,__,__,__,__,__,U3,U3,__,__}, +/*u3 U3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,U4,U4,U4,U4,U4,U4,U4,U4,__,__,__,__,__,__,U4,U4,__,__}, +/*u4 U4*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,UC,UC,UC,UC,UC,UC,UC,UC,__,__,__,__,__,__,UC,UC,__,__}, +/*minus MI*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,ZE,IT,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__}, +/*zero ZE*/ {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,DF,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__}, +/*int IT*/ {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,DF,IT,IT,__,__,__,__,DE,__,__,__,__,__,__,__,__,DE,__,__}, +/*frac FR*/ {OK,OK,__,-8,__,-7,__,-3,__,__,CB,__,__,__,FR,FR,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__,__}, +/*e E1*/ {__,__,__,__,__,__,__,__,__,__,__,E2,E2,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__}, +/*ex E2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__}, +/*exp E3*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,E3,E3,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__}, +/*tr T1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T2,__,__,__,__,__,__,__}, +/*tru T2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,T3,__,__,__,__}, +/*true T3*/ {__,__,__,__,__,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__,__}, +/*fa F1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__}, +/*fal F2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F3,__,__,__,__,__,__,__,__,__}, +/*fals F3*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,F4,__,__,__,__,__,__}, +/*false F4*/ {__,__,__,__,__,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__,__,__}, +/*nu N1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N2,__,__,__,__}, +/*nul N2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,N3,__,__,__,__,__,__,__,__,__}, +/*null N3*/ {__,__,__,__,__,__,__,__,__,__,CB,__,__,__,__,__,__,__,__,__,__,__,OK,__,__,__,__,__,__,__,__,__}, +/*/ C1*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,C2}, +/*/* C2*/ {C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C3}, +/** C3*/ {C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,CE,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C2,C3}, +/*_. FX*/ {OK,OK,__,-8,__,-7,__,-3,__,__,__,__,__,__,FR,FR,__,__,__,__,E1,__,__,__,__,__,__,__,__,E1,__,__}, +/*\ D1*/ {__,__,__,__,__,__,__,__,__,D2,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__}, +/*\ D2*/ {__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,U1,__,__,__,__}, +}; + + +/* + These modes can be pushed on the stack. +*/ +enum modes { + MODE_ARRAY = 1, + MODE_DONE = 2, + MODE_KEY = 3, + MODE_OBJECT = 4 +}; + +static int +push(JSON_parser jc, int mode) +{ +/* + Push a mode onto the stack. Return false if there is overflow. +*/ + jc->top += 1; + if (jc->depth < 0) { + if (jc->top >= jc->stack_capacity) { + size_t bytes_to_allocate; + jc->stack_capacity *= 2; + bytes_to_allocate = jc->stack_capacity * sizeof(jc->static_stack[0]); + if (jc->stack == &jc->static_stack[0]) { + jc->stack = (signed char*)malloc(bytes_to_allocate); + memcpy(jc->stack, jc->static_stack, sizeof(jc->static_stack)); + } else { + jc->stack = (signed char*)realloc(jc->stack, bytes_to_allocate); + } + } + } else { + if (jc->top >= jc->depth) { + return false; + } + } + + jc->stack[jc->top] = mode; + return true; +} + + +static int +pop(JSON_parser jc, int mode) +{ +/* + Pop the stack, assuring that the current mode matches the expectation. + Return false if there is underflow or if the modes mismatch. +*/ + if (jc->top < 0 || jc->stack[jc->top] != mode) { + return false; + } + jc->top -= 1; + return true; +} + + +#define parse_buffer_clear(jc) \ + do {\ + jc->parse_buffer_count = 0;\ + jc->parse_buffer[0] = 0;\ + } while (0) + +#define parse_buffer_pop_back_char(jc)\ + do {\ + assert(jc->parse_buffer_count >= 1);\ + --jc->parse_buffer_count;\ + jc->parse_buffer[jc->parse_buffer_count] = 0;\ + } while (0) + +void delete_JSON_parser(JSON_parser jc) +{ + if (jc) { + if (jc->stack != &jc->static_stack[0]) { + free((void*)jc->stack); + } + if (jc->parse_buffer != &jc->static_parse_buffer[0]) { + free((void*)jc->parse_buffer); + } + free((void*)jc); + } +} + + +JSON_parser +new_JSON_parser(JSON_config* config) +{ +/* + new_JSON_parser starts the checking process by constructing a JSON_parser + object. It takes a depth parameter that restricts the level of maximum + nesting. + + To continue the process, call JSON_parser_char for each character in the + JSON text, and then call JSON_parser_done to obtain the final result. + These functions are fully reentrant. +*/ + + int depth = 0; + JSON_config default_config; + + JSON_parser jc = malloc(sizeof(struct JSON_parser_struct)); + + memset(jc, 0, sizeof(*jc)); + + + /* initialize configuration */ + init_JSON_config(&default_config); + + /* set to default configuration if none was provided */ + if (config == NULL) { + config = &default_config; + } + + depth = config->depth; + + /* We need to be able to push at least one object */ + if (depth == 0) { + depth = 1; + } + + jc->state = GO; + jc->top = -1; + + /* Do we want non-bound stack? */ + if (depth > 0) { + jc->stack_capacity = depth; + jc->depth = depth; + if (depth <= (int)COUNTOF(jc->static_stack)) { + jc->stack = &jc->static_stack[0]; + } else { + jc->stack = (signed char*)malloc(jc->stack_capacity * sizeof(jc->static_stack[0])); + } + } else { + jc->stack_capacity = COUNTOF(jc->static_stack); + jc->depth = -1; + jc->stack = &jc->static_stack[0]; + } + + /* set parser to start */ + push(jc, MODE_DONE); + + /* set up the parse buffer */ + jc->parse_buffer = &jc->static_parse_buffer[0]; + jc->parse_buffer_capacity = COUNTOF(jc->static_parse_buffer); + parse_buffer_clear(jc); + + /* set up callback, comment & float handling */ + jc->callback = config->callback; + jc->ctx = config->callback_ctx; + jc->allow_comments = config->allow_comments != 0; + jc->handle_floats_manually = config->handle_floats_manually != 0; + + /* set up decimal point */ + jc->decimal_point = *localeconv()->decimal_point; + + return jc; +} + +static void grow_parse_buffer(JSON_parser jc) +{ + size_t bytes_to_allocate; + jc->parse_buffer_capacity *= 2; + bytes_to_allocate = jc->parse_buffer_capacity * sizeof(jc->parse_buffer[0]); + if (jc->parse_buffer == &jc->static_parse_buffer[0]) { + jc->parse_buffer = (char*)malloc(bytes_to_allocate); + memcpy(jc->parse_buffer, jc->static_parse_buffer, jc->parse_buffer_count); + } else { + jc->parse_buffer = (char*)realloc(jc->parse_buffer, bytes_to_allocate); + } +} + +#define parse_buffer_push_back_char(jc, c)\ + do {\ + if (jc->parse_buffer_count + 1 >= jc->parse_buffer_capacity) grow_parse_buffer(jc);\ + jc->parse_buffer[jc->parse_buffer_count++] = c;\ + jc->parse_buffer[jc->parse_buffer_count] = 0;\ + } while (0) + +#define assert_is_non_container_type(jc) \ + assert( \ + jc->type == JSON_T_NULL || \ + jc->type == JSON_T_FALSE || \ + jc->type == JSON_T_TRUE || \ + jc->type == JSON_T_FLOAT || \ + jc->type == JSON_T_INTEGER || \ + jc->type == JSON_T_UNSIGNED || \ + jc->type == JSON_T_STRING) + + +static int parse_parse_buffer(JSON_parser jc) +{ + if (jc->callback) { + JSON_value value, *arg = NULL; + + if (jc->type != JSON_T_NONE) { + assert_is_non_container_type(jc); + + switch(jc->type) { + case JSON_T_FLOAT: + arg = &value; + if (jc->handle_floats_manually) { + value.vu.str.value = jc->parse_buffer; + value.vu.str.length = jc->parse_buffer_count; + } else { + /* not checking with end pointer b/c there may be trailing ws */ + value.vu.float_value = strtod(jc->parse_buffer, NULL); + } + break; + case JSON_T_INTEGER: + arg = &value; + sscanf(jc->parse_buffer, JSON_PARSER_INTEGER_SSCANF_TOKEN, &value.vu.integer_value); + break; + case JSON_T_UNSIGNED: + arg = &value; + sscanf(jc->parse_buffer, JSON_PARSER_UNSIGNED_SSCANF_TOKEN, &value.vu.unsigned_value); + break; + case JSON_T_STRING: + arg = &value; + value.vu.str.value = jc->parse_buffer; + value.vu.str.length = jc->parse_buffer_count; + break; + } + + if (!(*jc->callback)(jc->ctx, jc->type, arg)) { + return false; + } + } + } + + parse_buffer_clear(jc); + + return true; +} + +#define IS_HIGH_SURROGATE(uc) (((uc) & 0xFC00) == 0xD800) +#define IS_LOW_SURROGATE(uc) (((uc) & 0xFC00) == 0xDC00) +#define DECODE_SURROGATE_PAIR(hi,lo) ((((hi) & 0x3FF) << 10) + ((lo) & 0x3FF) + 0x10000) +static unsigned char utf8_lead_bits[4] = { 0x00, 0xC0, 0xE0, 0xF0 }; + +static int decode_unicode_char(JSON_parser jc) +{ + int i; + unsigned uc = 0; + char* p; + int trail_bytes; + + assert(jc->parse_buffer_count >= 6); + + p = &jc->parse_buffer[jc->parse_buffer_count - 4]; + + for (i = 12; i >= 0; i -= 4, ++p) { + unsigned x = *p; + + if (x >= 'a') { + x -= ('a' - 10); + } else if (x >= 'A') { + x -= ('A' - 10); + } else { + x &= ~0x30u; + } + + assert(x < 16); + + uc |= x << i; + } + + /* clear UTF-16 char from buffer */ + jc->parse_buffer_count -= 6; + jc->parse_buffer[jc->parse_buffer_count] = 0; + + /* attempt decoding ... */ + if (jc->utf16_high_surrogate) { + if (IS_LOW_SURROGATE(uc)) { + uc = DECODE_SURROGATE_PAIR(jc->utf16_high_surrogate, uc); + trail_bytes = 3; + jc->utf16_high_surrogate = 0; + } else { + /* high surrogate without a following low surrogate */ + return false; + } + } else { + if (uc < 0x80) { + trail_bytes = 0; + } else if (uc < 0x800) { + trail_bytes = 1; + } else if (IS_HIGH_SURROGATE(uc)) { + /* save the high surrogate and wait for the low surrogate */ + jc->utf16_high_surrogate = uc; + return true; + } else if (IS_LOW_SURROGATE(uc)) { + /* low surrogate without a preceding high surrogate */ + return false; + } else { + trail_bytes = 2; + } + } + + jc->parse_buffer[jc->parse_buffer_count++] = (char) ((uc >> (trail_bytes * 6)) | utf8_lead_bits[trail_bytes]); + + for (i = trail_bytes * 6 - 6; i >= 0; i -= 6) { + jc->parse_buffer[jc->parse_buffer_count++] = (char) (((uc >> i) & 0x3F) | 0x80); + } + + jc->parse_buffer[jc->parse_buffer_count] = 0; + + return true; +} + +static int add_escaped_char_to_parse_buffer(JSON_parser jc, int next_char) +{ + jc->escaped = 0; + /* remove the backslash */ + parse_buffer_pop_back_char(jc); + switch(next_char) { + case 'b': + parse_buffer_push_back_char(jc, '\b'); + break; + case 'f': + parse_buffer_push_back_char(jc, '\f'); + break; + case 'n': + parse_buffer_push_back_char(jc, '\n'); + break; + case 'r': + parse_buffer_push_back_char(jc, '\r'); + break; + case 't': + parse_buffer_push_back_char(jc, '\t'); + break; + case '"': + parse_buffer_push_back_char(jc, '"'); + break; + case '\\': + parse_buffer_push_back_char(jc, '\\'); + break; + case '/': + parse_buffer_push_back_char(jc, '/'); + break; + case 'u': + parse_buffer_push_back_char(jc, '\\'); + parse_buffer_push_back_char(jc, 'u'); + break; + default: + return false; + } + + return true; +} + +#define add_char_to_parse_buffer(jc, next_char, next_class) \ + do { \ + if (jc->escaped) { \ + if (!add_escaped_char_to_parse_buffer(jc, next_char)) \ + return false; \ + } else if (!jc->comment) { \ + if ((jc->type != JSON_T_NONE) | !((next_class == C_SPACE) | (next_class == C_WHITE)) /* non-white-space */) { \ + parse_buffer_push_back_char(jc, (char)next_char); \ + } \ + } \ + } while (0) + + +#define assert_type_isnt_string_null_or_bool(jc) \ + assert(jc->type != JSON_T_FALSE); \ + assert(jc->type != JSON_T_TRUE); \ + assert(jc->type != JSON_T_NULL); \ + assert(jc->type != JSON_T_STRING) + + +int +JSON_parser_char(JSON_parser jc, int next_char) +{ +/* + After calling new_JSON_parser, call this function for each character (or + partial character) in your JSON text. It can accept UTF-8, UTF-16, or + UTF-32. It returns true if things are looking ok so far. If it rejects the + text, it returns false. +*/ + int next_class, next_state; + +/* + Determine the character's class. +*/ + if (next_char < 0) { + return false; + } + if (next_char >= 128) { + next_class = C_ETC; + } else { + next_class = ascii_class[next_char]; + if (next_class <= __) { + return false; + } + } + + add_char_to_parse_buffer(jc, next_char, next_class); + +/* + Get the next state from the state transition table. +*/ + next_state = state_transition_table[jc->state][next_class]; + if (next_state >= 0) { +/* + Change the state. +*/ + jc->state = next_state; + } else { +/* + Or perform one of the actions. +*/ + switch (next_state) { +/* Unicode character */ + case UC: + if(!decode_unicode_char(jc)) { + return false; + } + /* check if we need to read a second UTF-16 char */ + if (jc->utf16_high_surrogate) { + jc->state = D1; + } else { + jc->state = ST; + } + break; +/* escaped char */ + case EX: + jc->escaped = 1; + jc->state = ES; + break; +/* integer detected by minus */ + case MX: + jc->type = JSON_T_INTEGER; + jc->state = MI; + break; +/* integer detected by zero */ + case ZX: + jc->type = JSON_T_UNSIGNED; + jc->state = ZE; + break; +/* integer detected by 1-9 */ + case IX: + jc->type = JSON_T_UNSIGNED; + jc->state = IT; + break; + +/* floating point number detected by exponent*/ + case DE: + assert_type_isnt_string_null_or_bool(jc); + jc->type = JSON_T_FLOAT; + jc->state = E1; + break; + +/* floating point number detected by fraction */ + case DF: + assert_type_isnt_string_null_or_bool(jc); + if (!jc->handle_floats_manually) { +/* + Some versions of strtod (which underlies sscanf) don't support converting + C-locale formated floating point values. +*/ + assert(jc->parse_buffer[jc->parse_buffer_count-1] == '.'); + jc->parse_buffer[jc->parse_buffer_count-1] = jc->decimal_point; + } + jc->type = JSON_T_FLOAT; + jc->state = FX; + break; +/* string begin " */ + case SB: + parse_buffer_clear(jc); + assert(jc->type == JSON_T_NONE); + jc->type = JSON_T_STRING; + jc->state = ST; + break; + +/* n */ + case NU: + assert(jc->type == JSON_T_NONE); + jc->type = JSON_T_NULL; + jc->state = N1; + break; +/* f */ + case FA: + assert(jc->type == JSON_T_NONE); + jc->type = JSON_T_FALSE; + jc->state = F1; + break; +/* t */ + case TR: + assert(jc->type == JSON_T_NONE); + jc->type = JSON_T_TRUE; + jc->state = T1; + break; + +/* closing comment */ + case CE: + jc->comment = 0; + assert(jc->parse_buffer_count == 0); + assert(jc->type == JSON_T_NONE); + jc->state = jc->before_comment_state; + break; + +/* opening comment */ + case CB: + if (!jc->allow_comments) { + return false; + } + parse_buffer_pop_back_char(jc); + if (!parse_parse_buffer(jc)) { + return false; + } + assert(jc->parse_buffer_count == 0); + assert(jc->type != JSON_T_STRING); + switch (jc->stack[jc->top]) { + case MODE_ARRAY: + case MODE_OBJECT: + switch(jc->state) { + case VA: + case AR: + jc->before_comment_state = jc->state; + break; + default: + jc->before_comment_state = OK; + break; + } + break; + default: + jc->before_comment_state = jc->state; + break; + } + jc->type = JSON_T_NONE; + jc->state = C1; + jc->comment = 1; + break; +/* empty } */ + case -9: + parse_buffer_clear(jc); + if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_END, NULL)) { + return false; + } + if (!pop(jc, MODE_KEY)) { + return false; + } + jc->state = OK; + break; + +/* } */ case -8: + parse_buffer_pop_back_char(jc); + if (!parse_parse_buffer(jc)) { + return false; + } + if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_END, NULL)) { + return false; + } + if (!pop(jc, MODE_OBJECT)) { + return false; + } + jc->type = JSON_T_NONE; + jc->state = OK; + break; + +/* ] */ case -7: + parse_buffer_pop_back_char(jc); + if (!parse_parse_buffer(jc)) { + return false; + } + if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_ARRAY_END, NULL)) { + return false; + } + if (!pop(jc, MODE_ARRAY)) { + return false; + } + + jc->type = JSON_T_NONE; + jc->state = OK; + break; + +/* { */ case -6: + parse_buffer_pop_back_char(jc); + if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_OBJECT_BEGIN, NULL)) { + return false; + } + if (!push(jc, MODE_KEY)) { + return false; + } + assert(jc->type == JSON_T_NONE); + jc->state = OB; + break; + +/* [ */ case -5: + parse_buffer_pop_back_char(jc); + if (jc->callback && !(*jc->callback)(jc->ctx, JSON_T_ARRAY_BEGIN, NULL)) { + return false; + } + if (!push(jc, MODE_ARRAY)) { + return false; + } + assert(jc->type == JSON_T_NONE); + jc->state = AR; + break; + +/* string end " */ case -4: + parse_buffer_pop_back_char(jc); + switch (jc->stack[jc->top]) { + case MODE_KEY: + assert(jc->type == JSON_T_STRING); + jc->type = JSON_T_NONE; + jc->state = CO; + + if (jc->callback) { + JSON_value value; + value.vu.str.value = jc->parse_buffer; + value.vu.str.length = jc->parse_buffer_count; + if (!(*jc->callback)(jc->ctx, JSON_T_KEY, &value)) { + return false; + } + } + parse_buffer_clear(jc); + break; + case MODE_ARRAY: + case MODE_OBJECT: + assert(jc->type == JSON_T_STRING); + if (!parse_parse_buffer(jc)) { + return false; + } + jc->type = JSON_T_NONE; + jc->state = OK; + break; + default: + return false; + } + break; + +/* , */ case -3: + parse_buffer_pop_back_char(jc); + if (!parse_parse_buffer(jc)) { + return false; + } + switch (jc->stack[jc->top]) { + case MODE_OBJECT: +/* + A comma causes a flip from object mode to key mode. +*/ + if (!pop(jc, MODE_OBJECT) || !push(jc, MODE_KEY)) { + return false; + } + assert(jc->type != JSON_T_STRING); + jc->type = JSON_T_NONE; + jc->state = KE; + break; + case MODE_ARRAY: + assert(jc->type != JSON_T_STRING); + jc->type = JSON_T_NONE; + jc->state = VA; + break; + default: + return false; + } + break; + +/* : */ case -2: +/* + A colon causes a flip from key mode to object mode. +*/ + parse_buffer_pop_back_char(jc); + if (!pop(jc, MODE_KEY) || !push(jc, MODE_OBJECT)) { + return false; + } + assert(jc->type == JSON_T_NONE); + jc->state = VA; + break; +/* + Bad action. +*/ + default: + return false; + } + } + return true; +} + + +int +JSON_parser_done(JSON_parser jc) +{ + const int result = jc->state == OK && pop(jc, MODE_DONE); + + return result; +} + + +int JSON_parser_is_legal_white_space_string(const char* s) +{ + int c, char_class; + + if (s == NULL) { + return false; + } + + for (; *s; ++s) { + c = *s; + + if (c < 0 || c >= 128) { + return false; + } + + char_class = ascii_class[c]; + + if (char_class != C_SPACE && char_class != C_WHITE) { + return false; + } + } + + return true; +} + + +void init_JSON_config(JSON_config* config) +{ + if (config) { + memset(config, 0, sizeof(*config)); + + config->depth = JSON_PARSER_STACK_SIZE - 1; + } +} diff --git a/src/hos_libvariant/src/lib/json/JSON_parser.h b/src/hos_libvariant/src/lib/json/JSON_parser.h new file mode 100644 index 00000000..93207a3f --- /dev/null +++ b/src/hos_libvariant/src/lib/json/JSON_parser.h @@ -0,0 +1,162 @@ +#ifndef JSON_PARSER_H +#define JSON_PARSER_H +#pragma once + +/* JSON_parser.h */ + + +#include + +/* Windows DLL stuff */ +#ifdef _WIN32 +# ifdef JSON_PARSER_DLL_EXPORTS +# define JSON_PARSER_DLL_API __declspec(dllexport) +# else +# define JSON_PARSER_DLL_API __declspec(dllimport) +# endif +#else +# define JSON_PARSER_DLL_API +#endif + +/* Determine the integer type use to parse non-floating point numbers */ +#if __STDC_VERSION__ >= 199901L || HAVE_LONG_LONG == 1 +typedef long long JSON_int_t; +typedef unsigned long long JSON_uint_t; +#define JSON_PARSER_INTEGER_SSCANF_TOKEN "%lld" +#define JSON_PARSER_INTEGER_SPRINTF_TOKEN "%lld" +#define JSON_PARSER_UNSIGNED_SSCANF_TOKEN "%llu" +#define JSON_PARSER_UNSIGNED_SPRINTF_TOKEN "%llu" +#else +typedef long JSON_int_t; +typedef unsigned long JSON_uint_t; +#define JSON_PARSER_INTEGER_SSCANF_TOKEN "%ld" +#define JSON_PARSER_INTEGER_SPRINTF_TOKEN "%ld" +#define JSON_PARSER_UNSIGNED_SSCANF_TOKEN "%lu" +#define JSON_PARSER_UNSIGNED_SPRINTF_TOKEN "%lu" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + JSON_T_NONE = 0, + JSON_T_ARRAY_BEGIN, + JSON_T_ARRAY_END, + JSON_T_OBJECT_BEGIN, + JSON_T_OBJECT_END, + JSON_T_INTEGER, + JSON_T_UNSIGNED, + JSON_T_FLOAT, + JSON_T_NULL, + JSON_T_TRUE, + JSON_T_FALSE, + JSON_T_STRING, + JSON_T_KEY, + JSON_T_MAX +} JSON_type; + +typedef struct JSON_value_struct { + union { + JSON_int_t integer_value; + + JSON_uint_t unsigned_value; + + double float_value; + + struct { + const char* value; + size_t length; + } str; + } vu; +} JSON_value; + +typedef struct JSON_parser_struct* JSON_parser; + +/*! \brief JSON parser callback + + \param ctx The pointer passed to new_JSON_parser. + \param type An element of JSON_type but not JSON_T_NONE. + \param value A representation of the parsed value. This parameter is NULL for + JSON_T_ARRAY_BEGIN, JSON_T_ARRAY_END, JSON_T_OBJECT_BEGIN, JSON_T_OBJECT_END, + JSON_T_NULL, JSON_T_TRUE, and SON_T_FALSE. String values are always returned + as zero-terminated C strings. + + \return Non-zero if parsing should continue, else zero. +*/ +typedef int (*JSON_parser_callback)(void* ctx, int type, const struct JSON_value_struct* value); + + +/*! \brief The structure used to configure a JSON parser object + + \param depth If negative, the parser can parse arbitrary levels of JSON, otherwise + the depth is the limit + \param Pointer to a callback. This parameter may be NULL. In this case the input is merely checked for validity. + \param Callback context. This parameter may be NULL. + \param depth. Specifies the levels of nested JSON to allow. Negative numbers yield unlimited nesting. + \param allowComments. To allow C style comments in JSON, set to non-zero. + \param handleFloatsManually. To decode floating point numbers manually set this parameter to non-zero. + + \return The parser object. +*/ +typedef struct { + JSON_parser_callback callback; + void* callback_ctx; + int depth; + int allow_comments; + int handle_floats_manually; +} JSON_config; + + +/*! \brief Initializes the JSON parser configuration structure to default values. + + The default configuration is + - 127 levels of nested JSON (depends on JSON_PARSER_STACK_SIZE, see json_parser.c) + - no parsing, just checking for JSON syntax + - no comments + + \param config. Used to configure the parser. +*/ +JSON_PARSER_DLL_API void init_JSON_config(JSON_config* config); + +/*! \brief Create a JSON parser object + + \param config. Used to configure the parser. Set to NULL to use the default configuration. + See init_JSON_config + + \return The parser object. +*/ +JSON_PARSER_DLL_API extern JSON_parser new_JSON_parser(JSON_config* config); + +/*! \brief Destroy a previously created JSON parser object. */ +JSON_PARSER_DLL_API extern void delete_JSON_parser(JSON_parser jc); + +/*! \brief Parse a character. + + \return Non-zero, if all characters passed to this function are part of are valid JSON. +*/ +JSON_PARSER_DLL_API extern int JSON_parser_char(JSON_parser jc, int next_char); + +/*! \brief Finalize parsing. + + Call this method once after all input characters have been consumed. + + \return Non-zero, if all parsed characters are valid JSON, zero otherwise. +*/ +JSON_PARSER_DLL_API extern int JSON_parser_done(JSON_parser jc); + +/*! \brief Determine if a given string is valid JSON white space + + \return Non-zero if the string is valid, zero otherwise. +*/ +JSON_PARSER_DLL_API extern int JSON_parser_is_legal_white_space_string(const char* s); + + +#ifdef __cplusplus +} +#endif + + +#endif /* JSON_PARSER_H */ diff --git a/src/hos_libvariant/src/libvariant.pc.in b/src/hos_libvariant/src/libvariant.pc.in new file mode 100644 index 00000000..07372752 --- /dev/null +++ b/src/hos_libvariant/src/libvariant.pc.in @@ -0,0 +1,10 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@INSTALL_BIN_DIR@ +libdir=@INSTALL_LIB_DIR@ +includedir=@INSTALL_INCLUDE_DIR@ + +Name: libvariant +Description: Scripting language like variable (Variant) in C++ with serializing, deserializing, schema and other features. +Version: @VARIANT_VERSION@ +Libs: -L${libdir} -lVariant +Cflags: -I${includedir} diff --git a/src/hos_libvariant/src/src/ArgParse.cc b/src/hos_libvariant/src/src/ArgParse.cc new file mode 100644 index 00000000..0c48a15a --- /dev/null +++ b/src/hos_libvariant/src/src/ArgParse.cc @@ -0,0 +1,1855 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include "../../src/include/Variant/ArgParse.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../src/include/Variant/Extensions.h" +#include "../../src/include/Variant/Path.h" +#include "../../src/include/Variant/Schema.h" +#include "../../src/src/GuessScalar.h" +#include "../../src/src/ParseBool.h" + +#if 0 +#define DBPRINT(x) std::cout << x +#else +#define DBPRINT(X) +#endif + +namespace libvariant { + + // ----------------- + // Static data + // ----------------- + + extern const char ARG_PARSE_SCHEMA_STR[]; + static const struct ArgParseStatic { + ArgParseStatic() { + schema = DeserializeJSON(ARG_PARSE_SCHEMA_STR); + } + Variant schema; + } arg_parse_static; + + + // ---------------- + // Static and global functions + // ---------------- + + ArgParseAction ArgParseActionFromStr(const std::string &action) { + if (action == "store") { + return ARGACTION_STORE; + } else if (action == "store_const") { + return ARGACTION_STORE_CONST; + } else if (action == "store_true") { + return ARGACTION_STORE_TRUE; + } else if (action == "store_false") { + return ARGACTION_STORE_FALSE; + } else if (action == "append") { + return ARGACTION_APPEND; + } else if (action == "count") { + return ARGACTION_COUNT; + } else if (action == "help") { + return ARGACTION_HELP; + } else if (action == "adv_help") { + return ARGACTION_ADVHELP; + } else if (action == "config") { + return ARGACTION_CONFIG; + } else if (action == "config_json") { + return ARGACTION_CONFIG_JSON; + } else if (action == "config_yaml") { + return ARGACTION_CONFIG_YAML; + } else if (action == "config_plist") { + return ARGACTION_CONFIG_PLIST; + } else if (action == "config_print") { + return ARGACTION_PRINT_CONFIG; + } else { + return ARGACTION_UNKNOWN; + } + } + + std::string ArgParseActionToStr(ArgParseAction action) { + switch (action) { + case ARGACTION_STORE: + return "store"; + case ARGACTION_STORE_CONST: + return "store_const"; + case ARGACTION_STORE_TRUE: + return "store_true"; + case ARGACTION_STORE_FALSE: + return "store_false"; + case ARGACTION_APPEND: + return "append"; + case ARGACTION_COUNT: + return "count"; + case ARGACTION_HELP: + return "help"; + case ARGACTION_ADVHELP: + return "adv_help"; + case ARGACTION_CONFIG: + return "config"; + case ARGACTION_CONFIG_JSON: + return "config_json"; + case ARGACTION_CONFIG_YAML: + return "config_yaml"; + case ARGACTION_CONFIG_PLIST: + return "config_plist"; + case ARGACTION_PRINT_CONFIG: + return "config_print"; + case ARGACTION_UNKNOWN: + default: + throw std::runtime_error("ArgParseActionToStr action enum an unknown value."); + } + } + + static bool ArgParseActionHasArg(ArgParseAction action) { + switch (action) { + case ARGACTION_STORE: + case ARGACTION_APPEND: + case ARGACTION_CONFIG: + case ARGACTION_CONFIG_JSON: + case ARGACTION_CONFIG_YAML: + case ARGACTION_CONFIG_PLIST: + return true; + case ARGACTION_STORE_CONST: + case ARGACTION_STORE_TRUE: + case ARGACTION_STORE_FALSE: + case ARGACTION_COUNT: + case ARGACTION_HELP: + case ARGACTION_ADVHELP: + return false; + default: + return false; + } + } + + static bool ArgParseActionHasResult(ArgParseAction action) { + switch (action) { + case ARGACTION_STORE: + case ARGACTION_APPEND: + case ARGACTION_STORE_CONST: + case ARGACTION_STORE_TRUE: + case ARGACTION_STORE_FALSE: + case ARGACTION_COUNT: + return true; + case ARGACTION_CONFIG: + case ARGACTION_CONFIG_JSON: + case ARGACTION_CONFIG_YAML: + case ARGACTION_CONFIG_PLIST: + case ARGACTION_HELP: + case ARGACTION_ADVHELP: + return false; + default: + return false; + } + } + + ArgParseType ParseType(const Variant &type) { + if (type.IsString()) { + if (type == "string") { return ARGTYPE_STRING; } + if (type == "number") { return ARGTYPE_FLOAT; } + if (type == "integer") { return ARGTYPE_INT; } + if (type == "boolean") { return ARGTYPE_BOOL; } + if (type == "null") { return ARGTYPE_GUESS; } + + std::ostringstream oss; + oss << "libvariant::ArgParse unrecognized type \"" << type.AsString() << "\""; + throw std::runtime_error(oss.str()); + } + return ARGTYPE_GUESS; + } + + std::string TypeString(Variant::Type_t type) { + switch (type) { + case Variant::NullType: + return "null"; + case Variant::BoolType: + return "boolean"; + case Variant::IntegerType: + case Variant::UnsignedType: + return "integer"; + case Variant::FloatType: + return "number"; + case Variant::StringType: + return "string"; + case Variant::ListType: + case Variant::MapType: + case Variant::BlobType: + default: + return "null"; + } + } + + //----------------- + // + + struct ArgParseOptImpl { + ArgParseOptImpl(ArgParseImpl *i, int id, const Path &p, int sOpt, const std::string &lOpt, + const std::string &htxt, ArgParseAction a); + void Set(const std::string &key, Variant v) { opt.Set(key, v); } + bool HasArg() const { return ArgParseActionHasArg(action); } + bool HasResult() { return ArgParseActionHasResult(action); } + void HandleOption(const char *arg) { Handle(ParseArg(arg)); } + void Handle(Variant arg); + void CheckRequirements(Variant val); + Variant ParseArg(const char *arg); + void Init(Variant o); + + void FinalizeResult(); + void FormResult(VariantRef res); + + std::ostream &MakeArgString(std::ostream &os) const; + void HelpLine(std::ostream &os, bool is_arg, bool adv, unsigned indent) const; + Variant GetDescription() const; + void GenerateSchema(VariantRef schema) const; + void GenerateSchema(VariantRef schema, Path::const_iterator i, Path::const_iterator e) const; + void GenerateObjectSchema(VariantRef schema, Path::const_iterator i, Path::const_iterator e) const; + void GenerateArraySchema(VariantRef schema, Path::const_iterator i, Path::const_iterator e) const; + Variant GenerateSchema() const; + + Variant::Type_t type; + Path path; + int id; + std::set groups; + int shortOpt; + std::string longOpt; + ArgParseAction action; + bool required; + bool advanced; + ArgParseImpl *impl; + Variant opt; + Variant result; + }; + + struct ArgString { + ArgString(const ArgParseOptImpl &o) : opt(o) {} + const ArgParseOptImpl &opt; + }; + static std::ostream &operator<<(std::ostream &os, const ArgString &as) { + return as.opt.MakeArgString(os); + } + + struct OptName { + OptName(ArgParseOptImpl *o, bool a=true) : opt(o), arg(a) {} + ArgParseOptImpl *opt; + bool arg; + }; + + static std::ostream &operator<<(std::ostream &os, const OptName &o) { + if (o.opt->longOpt != "") { + os << "option --" << o.opt->longOpt; + if (o.arg) os << " argument"; + } else if (o.opt->shortOpt != 0) { + os << "option -" << (char)o.opt->shortOpt; + if (o.arg) os << " argument"; + } else { + os << "argument " << o.opt->opt.Get("title").AsString(); + } + return os; + } + + struct ArgParseGroupImpl { + + ArgParseGroupImpl(ArgParseImpl *i, const std::string &name_) + : name(name_), + required(false), + mutually_exclusive(false), + advanced(false), + impl(i) + {} + + void Add(const Path &path); + void Add(ArgParseOptImpl *i); + void Init(Variant o); + void FinalizeResult(); + Variant GetDescription() const; + void GenerateSchema(VariantRef schema) const; + void GroupSchema(VariantRef schema, const ArgParseOptImpl *opt, + Path::const_iterator i, Path::const_iterator e) const; + + std::string name; + std::string title; + std::string description; + std::set members; + bool required; + bool mutually_exclusive; + bool advanced; + ArgParseImpl *impl; + }; + + struct ArgParseImpl { + + ArgParseImpl(const std::string &pname, bool addhelp) + : option_count(256), resolve_conflicts(false), have_advanced(false), + add_help(addhelp), print_help(false), + print_adv_help(false), print_config(false) + { + SetProgramName(pname); + } + + ArgParseOptImpl *AddOption(const std::string &keypath, int shortOpt, const std::string &longOpt, + const std::string &helptxt, ArgParseAction action) + { + Path path; + ParsePath(path, keypath); + int id = CheckExisting(path, shortOpt, longOpt); + if (longOpt.empty() && shortOpt == 0) { + throw std::runtime_error("ArgParse: Error attempting to add an option without" + " a short or long option."); + } + options.push_back(id); + optmap_iter i = option_map.insert(std::make_pair(id, + ArgParseOptImpl(this, id, path, shortOpt, longOpt, helptxt, action))).first; + if (!longOpt.empty()) { + longOpts.insert(std::make_pair(longOpt, id)); + } + if (shortOpt > 0) { + shortOpts.insert(std::make_pair((char)shortOpt, id)); + } + paths.insert(std::make_pair(PathString(path), id)); + return &i->second; + } + + ArgParseOptImpl *At(const std::string &keypath) { + Path path; + ParsePath(path, keypath); + return At(path); + } + + ArgParseOptImpl *At(const Path &path) { + std::map::iterator path_iter; + path_iter = paths.find(PathString(path)); + if (path_iter == paths.end()) { + throw std::runtime_error("ArgParse error, attempting to reference an non-existing option"); + } + return GetOpt(path_iter->second); + } + + ArgParseOptImpl *GetOpt(int id) { + return &option_map.find(id)->second; + } + + const ArgParseOptImpl *GetOpt(int id) const { + return &option_map.find(id)->second; + } + + ArgParseOptImpl *AddArgument(const std::string &keypath, const std::string &helptxt, + ArgParseAction action=ARGACTION_STORE) { + Path path; + ParsePath(path, keypath); + int sopt = 0; + int id = CheckExisting(path, sopt, ""); + arguments.push_back(id); + optmap_iter i = option_map.insert(std::make_pair(id, + ArgParseOptImpl(this, id, path, 0, "", helptxt, action) + )).first; + paths.insert(std::make_pair(PathString(path), id)); + i->second.Init(Variant().Set("maxArgs", 1).Set("minArgs", 1)); + return &i->second; + } + + ArgParseOptImpl *At(unsigned arg_index) { + return GetOpt(arguments.at(arg_index)); + } + + ArgParseGroupImpl *GetGroup(const std::string &name) { + return &groups.insert(std::make_pair(name, ArgParseGroupImpl(this, name))).first->second; + } + + void ConflictResolution(bool resolve) { + resolve_conflicts = resolve; + } + + void AddHelp() { + add_help = true; + } + + void AddConfigDefaults() { + AddOption("default-config-load", 0, "config", "Load options from file.", ARGACTION_CONFIG); + AddOption("default-config-print", 0, "print-config", "Print the configuration and exit.", + ARGACTION_PRINT_CONFIG); + } + + int CheckExisting(const Path &path, int &shortOpt, const std::string &longOpt) { + if (paths.find(PathString(path)) != paths.end()) { + std::ostringstream oss; + oss << "ArgParse option key \"" << PathString(path) << "\" already exists in options."; + throw std::runtime_error(oss.str()); + } + if (shortOpt > 0 && shortOpts.find(shortOpt) != shortOpts.end()) { + if (resolve_conflicts) { + shortOpt = 0; + } else { + std::ostringstream oss; + oss << "ArgParse duplicate short option \"" << std::string(1, (char)shortOpt) + << "\""; + throw std::runtime_error(oss.str()); + } + } + if (!longOpt.empty() && longOpts.find(longOpt) != longOpts.end()) { + std::ostringstream oss; + oss << "ArgParse duplicate long option \"" << longOpt << "\""; + throw std::runtime_error(oss.str()); + } + if (shortOpt > 0) { return shortOpt; } + else { return ++option_count; } + } + + void SetProgramName(const std::string &pname, bool do_basename=true); + + void Parse(int argc, char *const *argv); + Variant FormResult(); + + void PrintHelp(bool advanced) const; + void PrintConfig(); + + void MergeDescription(Variant desc); + void MergeOptions(Variant opts); + void MergeOptions(Variant opt, Path &path); + + void GenerateSchema(VariantRef schema) const; + Variant GetDescription() const; + + std::string title; + std::string description; + std::string epilog; + int option_count; + std::map option_map; + typedef std::map::iterator optmap_iter; + std::vector options; + typedef std::vector::iterator opt_iter; + typedef std::vector::const_iterator const_opt_iter; + std::map longOpts; + std::map shortOpts; + std::map paths; + std::vector arguments; + typedef std::vector::iterator arg_iter; + typedef std::vector::const_iterator const_arg_iter; + + std::map groups; + typedef std::map::iterator group_iter; + typedef std::map::const_iterator const_group_iter; + + bool resolve_conflicts; + bool have_advanced; + bool add_help; + bool print_help; + bool print_adv_help; + bool print_config; + }; + + + // ------------- + // ArgParseOption implemenatation + // ------------- + + ArgParseOption &ArgParseOption::Title(const std::string &title) { + impl->Set("title", title); + return *this; + } + + ArgParseOption &ArgParseOption::Action(const std::string &action) { + return Action(ArgParseActionFromStr(action)); + } + + ArgParseOption &ArgParseOption::Action(ArgParseAction action) { + if (action == ARGACTION_UNKNOWN) { + throw std::runtime_error("ArgParse: Unknown action"); + } + impl->action = action; + return *this; + } + + ArgParseOption &ArgParseOption::Type(ArgParseType type) { + switch (type) { + case ARGTYPE_GUESS: + case ARGTYPE_INT: + case ARGTYPE_UINT: + case ARGTYPE_STRING: + case ARGTYPE_BOOL: + case ARGTYPE_FLOAT: + impl->type = (Variant::Type_t)type; + return *this; + default: + throw std::runtime_error("ArgParse: Unknown argument type specified."); + } + } + + ArgParseOption &ArgParseOption::Type(const std::string &type) { + return Type(ParseType(type)); + } + + ArgParseOption &ArgParseOption::Type(Variant::Type_t type) { + if (type == Variant::MapType || type == Variant::ListType) { + std::ostringstream oss; + oss << "ArgParse: Type " << type << " cannot be specified as an option type."; + throw std::runtime_error(oss.str()); + } + impl->type = type; + return *this; + } + + ArgParseOption &ArgParseOption::Const(Variant val) { + impl->Set("const", val); + return *this; + } + + ArgParseOption &ArgParseOption::Default(Variant val) { + impl->Set("default", val); + return *this; + } + + ArgParseOption &ArgParseOption::Env(const char *env) { + impl->Set("env", env); + return *this; + } + + ArgParseOption &ArgParseOption::Minimum(Variant val) { + if (!val.IsNumber()) { + throw std::runtime_error("Minimum requires a number."); + } + if (impl->type == Variant::NullType) { impl->type = Variant::FloatType; } + impl->Set("minimum", val); + return *this; + } + + ArgParseOption &ArgParseOption::Maximum(Variant val) { + if (!val.IsNumber()) { + throw std::runtime_error("Maximum requires a number."); + } + if (impl->type == Variant::NullType) { impl->type = Variant::FloatType; } + impl->Set("maximum", val); + return *this; + } + + ArgParseOption &ArgParseOption::AddChoice(Variant val) { + if (!impl->opt.Contains("enum")) { impl->Set("enum", Variant::ListType); } + Variant e = impl->opt["enum"]; + if (std::find(e.ListBegin(), e.ListEnd(), val) == e.ListEnd()) { + e.Append(val); + } + return *this; + } + + ArgParseOption &ArgParseOption::SetChoices(const std::vector &val) { + impl->Set("enum", val); + return *this; + } + + const std::vector &ArgParseOption::GetChoices() { + return impl->opt["enum"].AsList(); + } + + ArgParseOption &ArgParseOption::Required(bool req) { + impl->required = true; + return *this; + } + + ArgParseOption &ArgParseOption::Help(const std::string &helptxt) { + impl->Set("description", helptxt); + return *this; + } + + ArgParseOption &ArgParseOption::Pattern(const std::string &pattern) { + if (impl->type == Variant::NullType) { impl->type = Variant::StringType; } + impl->Set("pattern", pattern); + return *this; + } + + ArgParseOption &ArgParseOption::MaxLength(unsigned l) { + if (impl->type == Variant::NullType) { impl->type = Variant::StringType; } + impl->Set("maxLength", l); + return *this; + } + + ArgParseOption &ArgParseOption::MinLength(unsigned l) { + if (impl->type == Variant::NullType) { impl->type = Variant::StringType; } + impl->Set("minLength", l); + return *this; + } + + ArgParseOption &ArgParseOption::MinArgs(unsigned l) { + impl->Set("minArgs", l); + if (l > 0 && !impl->required) { + impl->required = true; + } + return *this; + } + + ArgParseOption &ArgParseOption::MaxArgs(unsigned l) { + impl->Set("maxArgs", l); + return *this; + } + + ArgParseOption &ArgParseOption::NumArgs(unsigned l) { + MinArgs(l); + MaxArgs(l); + return *this; + } + + ArgParseOption &ArgParseOption::Group(const std::string &gname) { + impl->impl->GetGroup(gname)->Add(impl); + return *this; + } + + ArgParseOption &ArgParseOption::Advanced(bool adv) { + impl->advanced = adv; + impl->impl->have_advanced = true; + return *this; + } + + OptionGroup &OptionGroup::Title(const std::string &t) { + impl->title = t; + return *this; + } + + OptionGroup &OptionGroup::Description(const std::string &d) { + impl->description = d; + return *this; + } + + OptionGroup &OptionGroup::MutuallyExclusive(bool exclusive) { + impl->mutually_exclusive = exclusive; + return *this; + } + + OptionGroup &OptionGroup::Required(bool req) { + impl->required = req; + return *this; + } + + OptionGroup &OptionGroup::Add(const std::string &keypath) { + Path path; + ParsePath(path, keypath); + impl->Add(path); + return *this; + } + + OptionGroup &OptionGroup::Add(const Path &keypath) { + impl->Add(keypath); + return *this; + } + + OptionGroup &OptionGroup::Advanced(bool adv) { + impl->advanced = adv; + impl->impl->have_advanced = true; + return *this; + } + + // ----------------------- + // ArgParse implementation + // ----------------------- + + ArgParse::ArgParse(bool addhelp) + : impl(shared_ptr(new ArgParseImpl("", addhelp))) + {} + + ArgParse::ArgParse(const std::string &pname, bool addhelp) + : impl(shared_ptr(new ArgParseImpl(pname, addhelp))) + {} + + ArgParseOption ArgParse::AddOption(const std::string &keypath, int shortOpt, const std::string &longOpt, + const std::string &helptxt) + { + return ArgParseOption(impl->AddOption(keypath, shortOpt, longOpt, helptxt, ARGACTION_STORE)); + } + + ArgParseOption ArgParse::At(const std::string &keypath) { + return ArgParseOption(impl->At(keypath)); + } + + ArgParseOption ArgParse::AddFlag(const std::string &keypath, int shortOpt, const std::string &longOpt, + const std::string &helptxt) + { + return ArgParseOption(impl->AddOption(keypath, shortOpt, longOpt, helptxt, ARGACTION_STORE_TRUE)) + .Type(ARGTYPE_BOOL).Default(false); + } + + OptionGroup ArgParse::AddGroup(const std::string &name, const std::string &title, + const std::string &description) { + return OptionGroup(impl->GetGroup(name)).Title(title).Description(description); + } + + OptionGroup ArgParse::GetGroup(const std::string &name) { + return OptionGroup(impl->GetGroup(name)); + } + + ArgParseOption ArgParse::AddArgument(const std::string &keypath, const std::string &helptxt) + { + return ArgParseOption(impl->AddArgument(keypath, helptxt)); + } + + ArgParseOption ArgParse::At(size_t argumentIndex) { + return ArgParseOption(impl->At(argumentIndex)); + } + + void ArgParse::ConflictResolution(bool resolve) { + impl->ConflictResolution(resolve); + } + + void ArgParse::AddConfigDefaults() { + impl->AddConfigDefaults(); + } + + void ArgParse::AddHelp() { + impl->AddHelp(); + } + + void ArgParse::SetDescription(const std::string &txt) { + impl->description = txt; + } + + void ArgParse::SetEpilog(const std::string &txt) { + impl->epilog = txt; + } + + void ArgParse::SetProgramName(const std::string &pname, bool do_basename) { + impl->SetProgramName(pname, do_basename); + } + + std::string ArgParse::GetProgramName() const { + return impl->title; + } + + void ArgParse::Merge(Variant newopts) { + impl->MergeDescription(newopts); + } + + void ArgParse::Merge(const ArgParse &other) { + Merge(other.GetDescription()); + } + + void ArgParse::Validate() const { + SchemaResult result = SchemaValidate(arg_parse_static.schema, GetDescription()); + if (result.Error()) { + throw std::runtime_error(result.PrettyPrintMessage()); + } + } + + Variant ArgParse::Parse(int argc, char *const *argv) { + impl->Parse(argc, argv); + return impl->FormResult(); + } + + void ArgParse::PrintHelp(bool advanced) const { + impl->PrintHelp(advanced); + } + + Variant ArgParse::GetDescription() const { + return impl->GetDescription(); + } + + Variant ArgParse::GenerateSchema() const { + Variant schema = Variant::MapType; + impl->GenerateSchema(schema); + return schema; + } + + //------------------- + // ArgParseGroupImpl + //------------------- + + void ArgParseGroupImpl::Add(const Path &path) { + ArgParseOptImpl *o = impl->At(path); + Add(o); + } + + void ArgParseGroupImpl::Add(ArgParseOptImpl *o) { + members.insert(o); + o->groups.insert(name); + } + + void ArgParseGroupImpl::Init(Variant o) { + o.GetInto(title, "title", title); + o.GetInto(description, "description", description); + o.GetInto(required, "required", required); + o.GetInto(mutually_exclusive, "mutually exclusive", mutually_exclusive); + o.GetInto(advanced, "advanced", false); + if (advanced) { impl->have_advanced = true; } + if (o.Contains("members") && o["members"].IsList()) { + for (Variant::ListIterator i(o["members"].ListBegin()), e(o["members"].ListEnd()); + i != e; ++i) + { + Add(impl->At(i->AsString())); + } + } + } + + void ArgParseGroupImpl::FinalizeResult() { + if (mutually_exclusive) { + ArgParseOptImpl *last = 0; + for (std::set::iterator i(members.begin()), e(members.end()); + i != e; ++i) + { + ArgParseOptImpl *o = *i; + if (!o->result.IsNull()) { + if (!last) { + last = o; + } else { + std::ostringstream oss; + oss << "Error parsing arguments\n" + << OptName(last, false) << " and " << OptName(o, false) + << " are mutually exclusive."; + throw std::runtime_error(oss.str()); + } + } + } + if (required && !last) { + std::ostringstream oss; + oss << "Error parsing arguments\n" + << "One of the following options must be specified:\n"; + for (std::set::iterator i(members.begin()), e(members.end()); + i != e; ++i) + { + oss << "\t" << OptName(*i, false) << "\n"; + } + throw std::runtime_error(oss.str()); + } + } + } + + Variant ArgParseGroupImpl::GetDescription() const { + Variant desc = Variant::MapType; + if (!title.empty()) { desc.Set("title", title); } + if (!description.empty()) { desc.Set("description", description); } + desc.Set("required", required); + desc.Set("mutually exclusive", mutually_exclusive); + Variant mem = Variant::ListType; + for (std::set::iterator i(members.begin()), e(members.end()); + i != e; ++i) + { + mem.Append(PathString((*i)->path)); + } + desc.Set("advanced", advanced); + desc.Set("members", mem); + return desc; + } + + void ArgParseGroupImpl::GenerateSchema(VariantRef schema) const { + // The basic pattern for mutual exclusion with required is: + // "oneOf": [ + // { "required": [ "key" ] }, + // { "required": [ "key2" ] }, + // ] + // just mutual exclusion: + // "oneOf": [ + // { "required": [ "key" ] }, + // { "required": [ "key2" ] }, + // { "not": { "required": [ "key", "key2" ] } + // ] + // What makes things funny is paths. + if (mutually_exclusive) { + Variant oneof = Variant::ListType; + for (std::set::const_iterator i(members.begin()), e(members.end()); + i != e; ++i) + { + Variant instance; + GroupSchema(instance, *i, (*i)->path.begin(), (*i)->path.end()); + oneof.Append(instance); + } + if (!required) { + Variant anyof = Variant().Set("anyOf", oneof.Copy()); + oneof.Append(Variant().Set("not", anyof)); + } + if (!schema.Contains("allOf")) { schema["allOf"] = Variant::ListType; } + schema["allOf"].Append(Variant().Set("oneOf", oneof)); + } + } + + void ArgParseGroupImpl::GroupSchema(VariantRef schema, const ArgParseOptImpl *opt, + Path::const_iterator i, Path::const_iterator e) const + { + if (i != e) { + if (i->IsString()) { + schema["required"].Append(i->AsString()); + GroupSchema(schema["properties"][i->AsString()], opt, i+1, e); + } else if (i->IsNumber()) { + if (!schema.Contains("items")) { schema["items"] = Variant::ListType; } + if (schema["items"].Size() < i->AsUnsigned()) { + schema["items"].AsList().resize(i->AsUnsigned(), Variant::MapType); + } + GroupSchema(schema["items"][unsigned(i->AsUnsigned())], opt, i+1, e); + } + } else { + schema = Variant::MapType; + } + } + + //------------- + // ArgParseImpl + //------------- + +#if __APPLE__ +#include +#endif + void ArgParseImpl::SetProgramName(const std::string &pname, bool do_basename) { + if (pname.length() > 0) { + if (do_basename) { + char buf[pname.size()+1]; + strcpy(buf,pname.c_str()); + title = basename(buf); + } + else { + title = pname; + } + } + else { + // try to figure out the program name on our own + + char *progname = 0; + char buf[PATH_MAX*2]; + memset(buf, 0, PATH_MAX*2); + + #if __linux__ + if (!progname || !strlen(progname)) { + size_t bufsize = sizeof(buf); + if (0 == readlink("/proc/self/exe", buf, bufsize)) { + progname = buf; + } + } + #endif /* __linux__ */ + + #if __APPLE__ + if (!progname || !strlen(progname)) { + uint32_t bufsize = sizeof(buf); + if (0 == _NSGetExecutablePath(buf, &bufsize)) { + progname = buf; + } + } + #endif /* __APPLE__ */ + + if (!progname || !strlen(progname)) { + // Note: this is not accurate if the shell that set "_" + // called a program that called another program + progname = getenv("_"); + } + + if (!progname || !strlen(progname)) { + title = "ArgParse"; + } else { + title = std::string(basename(progname)); + } + } + } + + void ArgParseImpl::Parse(int argc, char *const *argv) { + + if (add_help) { + bool old_conflict = resolve_conflicts; + resolve_conflicts = true; + try { + AddOption("default-help-option", 'h', "help", "Print this message and exit.", ARGACTION_HELP); + if (have_advanced) { + AddOption("default-adv-help-option", 0, "adv-help", "Print help message" + " including options marked as advanced.", ARGACTION_ADVHELP); + } + } catch (const std::runtime_error &) {} + resolve_conflicts = old_conflict; + } + + try { + std::string shortOpts; + std::vector longOpts; + for (optmap_iter i(option_map.begin()), e(option_map.end()); i != e; ++i) { + ArgParseOptImpl &o = i->second; + int id = i->first; + if (o.shortOpt > 0) { + shortOpts.append(1, (char)o.shortOpt); + if (o.HasArg()) { shortOpts.append(1, ':'); } + } + if (!o.longOpt.empty()) { + struct option tmp_option = + { o.longOpt.c_str(), (o.HasArg() ? 1 : 0), 0, id }; + longOpts.push_back(tmp_option); + } + if (o.action == ARGACTION_COUNT) { o.result = 0u; } + // Handle environment variables + if (o.opt.Contains("env")) { + const char *env = getenv(o.opt["env"].AsString().c_str()); + if (env) { o.HandleOption(env); } + } + } + { + // End the option list + struct option tmp_option = {0, 0, 0, 0}; + longOpts.push_back(tmp_option); + } + + optind = 1; // Make sure getopt is in initial state + while (true) { + int c = getopt_long(argc, argv, shortOpts.c_str(), &longOpts[0], 0); + if (c == -1) { break; } + if (c == '?') { PrintHelp(false); } + optmap_iter o = option_map.find(c); + if (o == option_map.end()) { PrintHelp(false); } + ArgParseOptImpl &opt = o->second; + opt.HandleOption(optarg); + } + + // Handle arguments + unsigned minimum_arguments = 0; + for (arg_iter i(arguments.begin()), e(arguments.end()); i != e; ++i) { + ArgParseOptImpl *o = GetOpt(*i); + unsigned minarg; o->opt.GetInto(minarg, "minArgs", 0u); + if (minarg > 0) { minimum_arguments += minarg; } + else { break; } + } + unsigned numarg = argc - optind; + unsigned index = optind; + unsigned maximum_arguments = 0; + for (arg_iter i(arguments.begin()), e(arguments.end()); i != e; ++i) { + unsigned minarg, maxarg; + ArgParseOptImpl *o = GetOpt(*i); + o->opt.GetInto(minarg, "minArgs", 0u); + o->opt.GetInto(maxarg, "maxArgs", 0u); + if (maxarg != 0) { maximum_arguments += maxarg; } + else { maximum_arguments = 0; } + if (i + 1 == e && maxarg != 0 && argc - index > maxarg) { + std::ostringstream oss; + oss << "Error parsing arguments\nToo many arguments specified, " + << numarg << " given, maximum: " << maximum_arguments; + throw std::runtime_error(oss.str()); + } else { + unsigned num = 0; + while (index < (unsigned)argc && (maxarg == 0 || num < maxarg)) { + o->HandleOption(argv[index]); + ++index; + ++num; + } + } + } + if (index < (unsigned)argc) { + throw std::runtime_error("Error parsing arguments\nExtra arguments given."); + } + + for (optmap_iter i(option_map.begin()), e(option_map.end()); i != e; ++i) { + i->second.FinalizeResult(); + } + for (group_iter i(groups.begin()), e(groups.end()); i != e; ++i) { + i->second.FinalizeResult(); + } + if (print_adv_help) { PrintHelp(true); } + if (print_help) { PrintHelp(false); } + if (print_config) { PrintConfig(); } + } catch (const std::exception &e) { + if (print_adv_help) { PrintHelp(true); } + if (print_help) { PrintHelp(false); } + if (print_config) { PrintConfig(); } + std::cerr << e.what() << std::endl; + exit(1); + } + } + + Variant ArgParseImpl::FormResult() { + Variant ret = Variant::MapType; + for (optmap_iter i(option_map.begin()), e(option_map.end()); i != e; ++i) { + i->second.FormResult(ret); + } + return ret; + } + + + struct PrintHelpGroup { + std::string title; + std::string description; + bool advanced; + std::vector members; + }; + + void ArgParseImpl::PrintHelp(bool advanced) const { + std::cerr << title << ": [options]"; + for (const_arg_iter i(arguments.begin()), e(arguments.end()); i != e; ++i) { + const ArgParseOptImpl &arg = *GetOpt(*i); + unsigned minArgs, maxArgs; + arg.opt.GetInto(minArgs, "minArgs", 0u); + arg.opt.GetInto(maxArgs, "maxArgs", 0u); + if (minArgs == 0 && maxArgs == 0) { + std::cerr << " [" << ArgString(arg) << " [" << ArgString(arg) << " ...]]"; + } else { + for (unsigned i = 0; i < minArgs; ++i) { + std::cerr << " " << ArgString(arg); + } + if (maxArgs > minArgs) { + for (unsigned i = minArgs; i < maxArgs; ++i) { + std::cerr << " [" << ArgString(arg); + } + for (unsigned i = minArgs; i < maxArgs; ++i) { + std::cerr << "]"; + } + } else if (maxArgs < minArgs) { + std::cerr << " [" << ArgString(arg) << " ...]"; + } + } + } + std::cerr << "\n\n"; + if (!description.empty()) { + std::cerr << description << "\n\n"; + } + if (!arguments.empty()) { + std::cerr << "Arguments:\n"; + } + for (const_arg_iter i(arguments.begin()), e(arguments.end()); i != e; ++i) { + const ArgParseOptImpl &arg = *GetOpt(*i); + arg.HelpLine(std::cerr, false, true, 1); + } + if (!options.empty()) { + std::cerr << "Options:\n"; + } + std::vector ungrouped; + std::map groupings; + + for (const_opt_iter i(options.begin()), e(options.end()); i != e; ++i) { + bool in_group = false; + const ArgParseOptImpl &opt = *GetOpt(*i); + std::set::const_iterator g(opt.groups.begin()), gend(opt.groups.end()); + for (; g != gend; ++g) { + const_group_iter group_i = groups.find(*g); + if (group_i == groups.end()) { + std::cerr << "Group " << *g << " referenced but does not exist\n"; + continue; + } + const ArgParseGroupImpl *gimpl = &group_i->second; + if (!gimpl->title.empty() || !gimpl->description.empty()) { + in_group = true; + std::map::iterator giter; + giter = groupings.find(*g); + if (giter == groupings.end()) { + PrintHelpGroup group; + group.title = gimpl->title; + group.description = gimpl->description; + group.advanced = gimpl->advanced; + group.members.push_back(&opt); + groupings[*g] = group; + } else { + giter->second.members.push_back(&opt); + } + break; + } + } + if (!in_group) { + ungrouped.push_back(&opt); + } + } + for (std::vector::iterator i(ungrouped.begin()), e(ungrouped.end()); + i != e; ++i) + { + (*i)->HelpLine(std::cerr, true, advanced, 1); + } + for (std::map::iterator i(groupings.begin()), e(groupings.end()); + i != e; ++i) + { + if ( !(!i->second.advanced || advanced) ) { continue; } + std::cerr << "\n"; + if (! i->second.title.empty()) { + std::cerr << i->second.title << "\n"; + } + if (! i->second.description.empty()) { + std::cerr << i->second.description << "\n"; + } + for (std::vector::iterator j(i->second.members.begin()), + je(i->second.members.end()); + j != je; ++j) + { + (*j)->HelpLine(std::cerr, true, advanced, 1); + } + } + if (!epilog.empty()) { + std::cerr << "\n" << epilog << "\n" << std::endl; + } + exit(0); + } + + void ArgParseImpl::PrintConfig() { + Variant config = FormResult(); + Serialize(std::cout.rdbuf(), config, SERIALIZE_JSON, Variant().Set("pretty", true)); + std::cout << std::endl; + exit(0); + } + + void ArgParseImpl::MergeDescription(Variant desc) { + if (!desc.IsMap()) { return; } + if (desc.Contains("options") && desc["options"].IsMap()) { + Variant opts = desc["options"]; + for (Variant::MapIterator i(opts.MapBegin()), e(opts.MapEnd()); + i != e; ++i) + { + Variant o = i->second; + std::string keypath = i->first; + int shortOpt = 0; + if (o.Contains("shortOption")) { + shortOpt = o.Get("shortOption").AsString()[0]; + } + std::string longOpt = o.Get("longOption", "").AsString(); + std::string helptxt = o.Get("description", "").AsString(); + ArgParseAction action = ArgParseActionFromStr(o.Get("action", "store").AsString()); + AddOption(keypath, shortOpt, longOpt, helptxt, action)->Init(o); + } + } + if (desc.Contains("groups") && desc["groups"].IsMap()) { + Variant grps = desc["groups"]; + for (Variant::MapIterator i(grps.MapBegin()), e(grps.MapEnd()); + i != e; ++i) + { + Variant g = i->second; + std::string name = i->first; + GetGroup(name)->Init(g); + } + } + if (desc.Contains("arguments") && desc["arguments"].IsList()) { + Variant args = desc["arguments"]; + for (Variant::ListIterator i(args.ListBegin()), e(args.ListEnd()); + i != e; ++i) + { + Variant o = *i; + if (!o.Contains("keypath")) { continue; } + std::string keypath = o.Get("keypath").AsString(); + std::string helptxt = o.Get("description", "").AsString(); + ArgParseAction action = ArgParseActionFromStr(o.Get("action", "store").AsString()); + AddArgument(keypath, helptxt, action)->Init(o); + } + } + } + + void ArgParseImpl::MergeOptions(Variant opts) { + Path path; + MergeOptions(opts, path); + } + + void ArgParseImpl::MergeOptions(Variant opt, Path &path) { + switch (opt.GetType()) { + case Variant::NullType: + break; + case Variant::BoolType: + case Variant::IntegerType: + case Variant::UnsignedType: + case Variant::FloatType: + case Variant::StringType: + try { + At(path)->Handle(opt); + } catch (const std::runtime_error &) {} + break; + case Variant::ListType: + try { + At(path)->Handle(opt); + } catch (const std::runtime_error &) { + unsigned index = 0; + for (Variant::ListIterator i(opt.ListBegin()), e(opt.ListEnd()); + i != e; ++i, ++index) { + path.push_back(index); + MergeOptions(*i, path); + path.pop_back(); + } + } + break; + case Variant::MapType: + for (Variant::MapIterator i(opt.MapBegin()), e(opt.MapEnd()); i != e; ++i) { + path.push_back(i->first); + MergeOptions(i->second, path); + path.pop_back(); + } + break; + case Variant::BlobType: + break; + } + } + + void ArgParseImpl::GenerateSchema(VariantRef schema) const { + for (const_opt_iter i(options.begin()), e(options.end()); i != e; ++i) { + GetOpt(*i)->GenerateSchema(schema); + } + for (const_arg_iter i(arguments.begin()), e(arguments.end()); i != e; ++i) { + GetOpt(*i)->GenerateSchema(schema); + } + for (const_group_iter i(groups.begin()), e(groups.end()); i != e; ++i) { + i->second.GenerateSchema(schema); + } + } + + Variant ArgParseImpl::GetDescription() const { + Variant desc = Variant::MapType; + desc.Set("title", title); + desc.Set("description", description); + desc.Set("epilog", epilog); + for (const_opt_iter i(options.begin()), e(options.end()); i != e; ++i) { + const ArgParseOptImpl *opt = GetOpt(*i); + desc["options"].Set(PathString(opt->path), opt->GetDescription()); + } + for (const_arg_iter i(arguments.begin()), e(arguments.end()); i != e; ++i) { + const ArgParseOptImpl *opt = GetOpt(*i); + desc["arguments"].Append(opt->GetDescription()); + } + for (const_group_iter i(groups.begin()), e(groups.end()); i != e; ++i) { + desc["groups"].Set(i->first, i->second.GetDescription()); + } + return desc; + } + + // --------------- + // ArgParseOptImpl + // --------------- + + ArgParseOptImpl::ArgParseOptImpl(ArgParseImpl *i, int id_, const Path &p, + int sOpt, const std::string &lOpt, const std::string &htxt, ArgParseAction a) + : type(Variant::NullType), + path(p), + id(id_), + shortOpt(sOpt), + longOpt(lOpt), + action(a), + required(false), + advanced(false), + impl(i), + opt(Variant::MapType), + result(Variant::NullType) + { + if (path.back().IsString()) { + opt["title"] = path.back().AsString(); + } else { + opt["title"] = PathString(path); + } + opt["description"] = htxt; + } + + void ArgParseOptImpl::Handle(Variant arg) { + switch (action) { + case ARGACTION_STORE: + CheckRequirements(arg); + result = arg; + break; + case ARGACTION_STORE_CONST: + result = opt["const"]; + break; + case ARGACTION_STORE_TRUE: + if (arg.IsBool()) { + result = arg; + } else { + result = true; + } + break; + case ARGACTION_STORE_FALSE: + if (arg.IsBool()) { + result = arg; + } else { + result = false; + } + break; + case ARGACTION_APPEND: + if (arg.IsList()) { + for (Variant::ListIterator i(arg.ListBegin()), e(arg.ListEnd()); i != e; ++i) { + CheckRequirements(*i); + result.Append(*i); + } + } else { + CheckRequirements(arg); + result.Append(arg); + } + break; + case ARGACTION_COUNT: + if (arg.IsNumber()) { + result += arg.AsInt(); + } else { + result += 1; + } + break; + case ARGACTION_HELP: + impl->print_help = true; + break; + case ARGACTION_ADVHELP: + impl->print_adv_help = true; + break; + case ARGACTION_CONFIG: + impl->MergeOptions(DeserializeGuessFile(arg.AsString().c_str())); + break; + case ARGACTION_CONFIG_JSON: + impl->MergeOptions(DeserializeFile(arg.AsString().c_str(), SERIALIZE_JSON)); + break; + case ARGACTION_CONFIG_YAML: + impl->MergeOptions(DeserializeFile(arg.AsString().c_str(), SERIALIZE_YAML)); + break; + case ARGACTION_CONFIG_PLIST: + impl->MergeOptions(DeserializeFile(arg.AsString().c_str(), SERIALIZE_XMLPLIST)); + break; + case ARGACTION_PRINT_CONFIG: + impl->print_config = true; + break; + default: + break; + } + } + + void ArgParseOptImpl::CheckRequirements(Variant val) { + + switch (val.GetType()) { + case Variant::StringType: + if (opt.Contains("minLength") && val.Size() < opt["minLength"]) { + std::ostringstream oss; + oss << "Error parsing arguments\n" << OptName(this) << " is too short: " << val.Size() + << " chars, minimum " << opt["minLength"].AsUnsigned(); + throw std::runtime_error(oss.str()); + } + if (opt.Contains("maxLength") && val.Size() > opt["maxLength"]) { + std::ostringstream oss; + oss << "Error parsing arguments\n" << OptName(this) << " is too long: " << val.Size() + << " chars, maximum " << opt["maxLength"].AsUnsigned(); + throw std::runtime_error(oss.str()); + } + if (opt.Contains("pattern")) { + std::string pat = opt["pattern"].AsString(); + regex_t reg; + memset(®, 0, sizeof(regex_t)); + int err; + if ((err = regcomp(®, pat.c_str(), REG_EXTENDED | REG_NOSUB))) { + std::vector buffer(8192); + regerror(err, ®, &buffer[0], buffer.size()); + std::ostringstream oss; + oss << "Error parsing arguments\n"; + oss << "Failed to compile pattern regex \"" << pat << "\" with error: " + << &buffer[0]; + throw std::runtime_error(oss.str()); + } + if (regexec(®, val.AsString().c_str(), 0, 0, 0) != 0) { + regfree(®); + std::ostringstream oss; + oss << "Error parsing arguments\n"; + oss << OptName(this) << " failed to match pattern \"" + << pat << "\""; + throw std::runtime_error(oss.str()); + } + regfree(®); + } + break; + case Variant::IntegerType: case Variant::UnsignedType: case Variant::FloatType: + if (opt.Contains("minimum") && val < opt["minimum"]) { + std::ostringstream oss; + oss << "Error parsing arguments\n" << OptName(this) << " is too small: "; + SerializeJSON(oss.rdbuf(), val); + oss << ", minimum "; + SerializeJSON(oss.rdbuf(), opt["minimum"]); + throw std::runtime_error(oss.str()); + } + if (opt.Contains("maximum") && val > opt["maximum"]) { + std::ostringstream oss; + oss << "Error parsing arguments\n" << OptName(this) << " is too large: "; + SerializeJSON(oss.rdbuf(), val); + oss << ", maximum "; + SerializeJSON(oss.rdbuf(), opt["maximum"]); + throw std::runtime_error(oss.str()); + } + break; + default: + break; + } + + if (opt.Contains("enum")) { + Variant choices = opt["enum"]; + bool pass = false; + for (Variant::ListIterator i(choices.ListBegin()), e(choices.ListEnd()); i != e; ++i) + { + if (val == *i) { pass = true; break; } + } + if (!pass) { + std::ostringstream oss; + oss << "Error parsing arguments\n"; + SerializeJSON(oss.rdbuf(), val); + oss << "\nis not one of the allowed choices for " << OptName(this) << std::endl; + for (Variant::ListIterator i(choices.ListBegin()), e(choices.ListEnd()); i != e; ++i) + { + oss << " - "; + SerializeJSON(oss.rdbuf(), *i); + oss << std::endl; + } + throw std::runtime_error(oss.str()); + } + } + } + + + static void ParseArgIntError(const char *arg) { + std::ostringstream oss; + oss << "Error parsing arguments\nUnable to convert \"" << arg << "\" to an integer"; + throw std::runtime_error(oss.str()); + } + + Variant ArgParseOptImpl::ParseArg(const char *arg) { + + class PAction : public ParserActions { + public: + virtual void Scalar(ParserImpl *p, double v, const char *anchor, const char *tag) + { val = v; } + virtual void Scalar(ParserImpl *p, const char *str, unsigned length, const char *anchor, const char *tag) + { val = std::string(str, length); } + virtual void Scalar(ParserImpl *p, bool v, const char *anchor, const char *tag) + { val = v; } + virtual void Null(ParserImpl *p, const char *anchor, const char *tag) + { val = Variant::NullType; } + virtual void Scalar(ParserImpl *p, intmax_t v, const char *anchor, const char *tag) + { val = v; } + virtual void Scalar(ParserImpl *p, uintmax_t v, const char *anchor, const char *tag) + { val = v; } + Variant val; + }; + + if (!HasArg()) { + if (arg) { + std::ostringstream oss; + oss << "Error parsing arguments\n" + << OptName(this) << " does not take an argument, but argument \"" + << arg << "\" given."; + throw std::runtime_error(oss.str()); + } + return Variant::NullType; + } + + // Was type specified? + unsigned len = strlen(arg); + switch (type) { + case Variant::BoolType: + return Variant(ParseBool(arg)); + case Variant::IntegerType: + { + long long val; + char *end = 0; + val = strtoll(arg, &end, 10); + if (val == 0 && end == arg) { ParseArgIntError(arg); } + if (arg + len != end) { ParseArgIntError(arg); } + if (!(val == LLONG_MAX && errno == ERANGE)) { + return Variant(val); + } + } // Fall through + case Variant::UnsignedType: + { + char *end = 0; + unsigned long long val; + val = strtoull(arg, &end, 10); + if (val == 0 && end == arg) { ParseArgIntError(arg); } + if (arg + len != end) { ParseArgIntError(arg); } + return Variant(val); + } + case Variant::FloatType: + { + char *end = 0; + double val = strtod(arg, &end); + if ((val == 0 && end == arg) || (arg + len != end)) { + std::ostringstream oss; + oss << "Error parsing arguments\nUnable to convert \"" << arg << "\" to a number"; + throw std::runtime_error(oss.str()); + } + return Variant(val); + } + case Variant::StringType: + return Variant(arg); + + case Variant::NullType: case Variant::ListType: case Variant::MapType: case Variant::BlobType: default: + { + PAction a; + GuessScalar(arg, strlen(arg), 0, 0, 0, &a); + return a.val; + } + } + } + + std::ostream &ArgParseOptImpl::MakeArgString(std::ostream &os) const { + switch (action) { + case ARGACTION_STORE: + case ARGACTION_APPEND: + if (opt.Contains("enum") && opt["enum"].IsList()) { + for (Variant::ConstListIterator i(opt["enum"].ListBegin()), + e(opt["enum"].ListEnd()); i != e; ++i) + { + os << i->AsString(); + if (i + 1 != e) { + os << " | "; + } + } + } else { + switch (type) { + case Variant::BoolType: os << "yes|no"; break; + case Variant::IntegerType: case Variant::UnsignedType: + case Variant::NullType: case Variant::FloatType: default: + os << opt.Get("title", "XXX").AsString(); + } + } + break; + case ARGACTION_CONFIG: + case ARGACTION_CONFIG_JSON: + case ARGACTION_CONFIG_YAML: + case ARGACTION_CONFIG_PLIST: + os << "FILE"; + break; + case ARGACTION_PRINT_CONFIG: + default: + break; + } + return os; + } + + void ArgParseOptImpl::Init(Variant o) { + if (o.Contains("type")) { + type = (Variant::Type_t)ParseType(o["type"]); + } + o.GetInto(required, "required", required); + o.GetInto(advanced, "advanced", false); + if (advanced) { impl->have_advanced = true; } + opt.Merge(o); + } + + void ArgParseOptImpl::FinalizeResult() { + if (opt.Contains("default") && result.IsNull()) { + bool add_default = true; + for (std::set::iterator i(groups.begin()), e(groups.end()); + i != e; ++i) + { + ArgParseGroupImpl *g = impl->GetGroup(*i); + if (g->mutually_exclusive) { + for (std::set::iterator o(g->members.begin()), + oend(g->members.end()); o != oend; ++o) + { + ArgParseOptImpl *opt = *o; + if (!opt->result.IsNull()) { + add_default = false; + } + } + } + } + if (add_default) { + switch (action) { + case ARGACTION_STORE: + case ARGACTION_STORE_CONST: + case ARGACTION_STORE_TRUE: + case ARGACTION_STORE_FALSE: + result = opt["default"]; + break; + case ARGACTION_APPEND: + result.Append(opt["default"]); + case ARGACTION_COUNT: + case ARGACTION_HELP: + case ARGACTION_ADVHELP: + case ARGACTION_CONFIG: + case ARGACTION_CONFIG_JSON: + case ARGACTION_CONFIG_YAML: + case ARGACTION_CONFIG_PLIST: + case ARGACTION_PRINT_CONFIG: + default: + break; + } + } + } + if (!result.IsNull()) { + if (action == ARGACTION_APPEND) { + if (opt.Contains("maxArgs") && opt["maxArgs"] != 0) { + if (opt["maxArgs"] < result.Size()) { + std::ostringstream oss; + oss << "Error parsing arguments\n"; + oss << "More than maximum arguments specified for " << OptName(this) << ", "; + oss << result.Size() << " options, maximum: " << opt["maxArgs"].AsUnsigned(); + throw std::runtime_error(oss.str()); + } + } + if (opt.Contains("minArgs")) { + if (opt["minArgs"] > result.Size()) { + std::ostringstream oss; + oss << "Error parsing arguments\n"; + oss << "Less than minimum arguments specified for " << OptName(this) << ", "; + oss << result.Size() << " options, minimum: " << opt["minArgs"].AsUnsigned(); + throw std::runtime_error(oss.str()); + } + } + } + } else if (required) { + std::ostringstream oss; + oss << "Error parsing arguments\n"; + oss << "Required " << OptName(this) << " missing."; + throw std::runtime_error(oss.str()); + } + } + + void ArgParseOptImpl::FormResult(VariantRef res) { + if (!HasResult()) { return; } + if (result.IsNull()) { return; } + res.SetPath(path, result); + } + + void ArgParseOptImpl::HelpLine(std::ostream &os, bool is_arg, bool adv, unsigned indent) const { + if ( !(!advanced || adv) ) { return; } + os << "\t"; + if (shortOpt > 0) { + os << "-" << (char)shortOpt; + } + if (shortOpt > 0 && !longOpt.empty()) { + os << ", "; + } + if (!longOpt.empty()) { + os << "--" << longOpt; + } + if (HasArg()) { + os << " " << ArgString(*this); + } + if (opt.Contains("env")) { + if (shortOpt > 0 || !longOpt.empty()) { + os << "\n\t"; + } + os << "env: $" << opt["env"].AsString(); + if (HasArg()) { + os << "=" << ArgString(*this); + } + } + os << "\n\t\t" << opt["description"].AsString(); + + if (opt.Contains("default")) { + Variant def = opt["default"]; + if (!def.IsMap() && !def.IsList()) { + os << " (default: "; + SerializeJSON(os.rdbuf(), def); + os << ")"; + } + } + os << "\n"; + } + + Variant ArgParseOptImpl::GetDescription() const { + Variant desc; + desc.Merge(opt); + if (type == Variant::NullType) { + desc.Set("type", type); + } else { + desc.Set("type", TypeString(type)); + } + if (shortOpt > 0) { + desc.Set("shortOption", std::string(1, (char)shortOpt)); + } else { + desc.Erase("shortOption"); + } + if (!longOpt.empty()) { + desc.Set("longOption", longOpt); + } else { + desc.Erase("longOption"); + } + desc.Set("action", ArgParseActionToStr(action)); + desc.Set("required", required); + desc.Set("keypath", PathString(path)); + desc.Set("advanced", advanced); + return desc; + } + + void ArgParseOptImpl::GenerateSchema(VariantRef schema) const { + GenerateSchema(schema, path.begin(), path.end()); + } + + void ArgParseOptImpl::GenerateSchema(VariantRef schema, Path::const_iterator i, + Path::const_iterator e) const { + if (i == e) { + schema = GenerateSchema(); + } else { + if (schema.Get("type", "") == "object") { + GenerateObjectSchema(schema, i, e); + } else if (schema.Get("type", "") == "array") { + GenerateArraySchema(schema, i, e); + } else if (i->IsString()) { + GenerateObjectSchema(schema, i, e); + } else if (i->IsNumber()) { + GenerateArraySchema(schema, i, e); + } + } + } + + void ArgParseOptImpl::GenerateObjectSchema(VariantRef schema, Path::const_iterator i, + Path::const_iterator e) const + { + if (schema.IsNull()) { schema = Variant::MapType; } + std::string key = i->AsString(); + if (!schema.Contains("type")) { schema["type"] = "object"; } + if (!schema.Contains("properties")) { schema["properties"] = Variant::MapType; } + if (required) { + if (!schema.Contains("required")) { schema["required"] = Variant::ListType; } + if (std::find(schema["required"].ListBegin(), schema["required"].ListEnd(), Variant(key)) + == schema["required"].ListEnd()) + { + schema["required"].Append(key); + } + } + GenerateSchema(schema["properties"].At(key, Variant::MapType), i+1, e); + } + + void ArgParseOptImpl::GenerateArraySchema(VariantRef schema, Path::const_iterator i, + Path::const_iterator e) const + { + unsigned index = i->AsUnsigned(); + if (!schema.Contains("type")) { schema["type"] = "array"; } + if (!schema.Contains("items")) { schema["items"] = Variant::ListType; } + GenerateSchema(schema["items"].At(index, Variant::MapType), i+1, e); + } + + Variant ArgParseOptImpl::GenerateSchema() const { + Variant s = Variant::MapType; + if (opt.Contains("title")) { s["title"] = opt["title"]; } + if (opt.Contains("description")) { s["description"] = opt["description"]; } + switch (action) { + case ARGACTION_STORE: + if (type != Variant::NullType) { s["type"] = TypeString(type); } + if (opt.Contains("minimum")) { s["minimum"] = opt["minimum"]; } + if (opt.Contains("maximum")) { s["maximum"] = opt["maximum"]; } + if (opt.Contains("minLength")) { s["minLength"] = opt["minLength"]; } + if (opt.Contains("maxLength")) { s["maxLength"] = opt["maxLength"]; } + if (opt.Contains("pattern")) { s["pattern"] = opt["pattern"]; } + if (opt.Contains("enum")) { s["enum"] = opt["enum"].Copy(); } + if (opt.Contains("default")) { s["default"] = opt["default"]; } + break; + case ARGACTION_STORE_CONST: + s["enum"].Append(opt.Get("const")); + break; + case ARGACTION_STORE_TRUE: + case ARGACTION_STORE_FALSE: + s["type"] = "boolean"; + if (opt.Contains("default")) { s["default"] = opt["default"]; } + break; + case ARGACTION_APPEND: + { + Variant itemschema = Variant::MapType; + if (type != Variant::NullType) { itemschema["type"] = TypeString(type); } + if (opt.Contains("minimum")) { itemschema["minimum"] = opt["minimum"]; } + if (opt.Contains("maximum")) { itemschema["maximum"] = opt["maximum"]; } + if (opt.Contains("minLength")) { itemschema["minLength"] = opt["minLength"]; } + if (opt.Contains("maxLength")) { itemschema["maxLength"] = opt["maxLength"]; } + if (opt.Contains("pattern")) { itemschema["pattern"] = opt["pattern"]; } + if (opt.Contains("enum")) { itemschema["enum"] = opt["enum"].Copy(); } + if (opt.Contains("default")) { + s["default"] = Variant::ListType; + s["default"].Append(opt["default"]); + } + s["items"] = itemschema; + } + if (opt.Contains("minArgs") && opt["minArgs"] > 0) { s["minItems"] = opt["minArgs"]; } + if (opt.Contains("maxArgs") && opt["maxArgs"] > 0) { s["maxItems"] = opt["maxArgs"]; } + break; + case ARGACTION_COUNT: + s["type"] = "integer"; + s["minimum"] = 0; + break; + case ARGACTION_HELP: + case ARGACTION_ADVHELP: + case ARGACTION_CONFIG: + case ARGACTION_CONFIG_JSON: + case ARGACTION_CONFIG_YAML: + case ARGACTION_CONFIG_PLIST: + case ARGACTION_UNKNOWN: + default: + break; + } + return s; + } + +} diff --git a/src/hos_libvariant/src/src/Base64.cc b/src/hos_libvariant/src/src/Base64.cc new file mode 100644 index 00000000..99ccc50a --- /dev/null +++ b/src/hos_libvariant/src/src/Base64.cc @@ -0,0 +1,160 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include "Base64.h" + +namespace libvariant { + + unsigned Base64Encode(char *outptr, const void *inptr, unsigned len, unsigned cpl) { + struct iovec iov = { (void*)inptr, len }; + return Base64Encode(outptr, &iov, 1, cpl); + } + + class iov_iterator { + public: + iov_iterator() : iov(0), len(0), slab(0), offset(0) {} + iov_iterator(const iov_iterator &o) : iov(o.iov), len(o.len), slab(o.slab), offset(o.offset) {} + iov_iterator(const struct iovec *v, unsigned l) : iov(v), len(l), slab(0), offset(0) {} + iov_iterator &operator++() { + ++offset; + if (offset >= iov[slab].iov_len) { + ++slab; + offset = 0; + } + return *this; + } + iov_iterator operator++(int) { + iov_iterator o = *this; + ++(*this); + return o; + } + + char operator *() { + return *((char*)(iov[slab].iov_base) + offset); + } + + bool operator==(const iov_iterator &o) { + return (slab == o.slab && offset == o.offset); + } + + bool is_end() { return slab >= len; } + iov_iterator end() { + iov_iterator o = *this; + while (!o.is_end()) { ++o; } + return o; + } + + private: + const struct iovec *iov; + unsigned len; + unsigned slab; + unsigned offset; + }; + + unsigned Base64Encode(char *outptr, const struct iovec *iov, unsigned iov_len, unsigned cpl) { + static const char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + iov_iterator i = iov_iterator(iov, iov_len); + iov_iterator e = i.end(); + unsigned step_count = 0; + char *o = outptr; +#define PUSH_VALUE()\ + do {\ + if (result > 63) { *o++ = '='; }\ + else { *o++ = encoding[(int)result]; }\ + } while (0) + + char result; + char fragment; + while (true) { + // Step A + if (i == e) { break; } + fragment = *i++; + result = (fragment & 0x0FC) >> 2; + PUSH_VALUE(); + result = (fragment & 0x003) << 4; + // Step B + if (i == e) { + PUSH_VALUE(); + *o++ = '='; + *o++ = '='; + break; + } + fragment = *i++; + result |= (fragment & 0x0f0) >> 4; + PUSH_VALUE(); + result = (fragment & 0x00f) << 2; + // Step C + if (i == e) { + PUSH_VALUE(); + *o++ = '='; + break; + } + fragment = *i++; + result |= (fragment & 0x0c0) >> 6; + PUSH_VALUE(); + result = (fragment & 0x03f) >> 0; + PUSH_VALUE(); + ++step_count; + if (cpl > 0 && step_count == cpl/4) { + *o++ = '\n'; + step_count = 0; + } + } +#undef PUSH_VALUE + if (cpl > 0) { *o++ = '\n'; } + *o = '\0'; + return o - outptr; + } + + unsigned Base64EncodeSize(unsigned len, unsigned cpl) { + // Every 3 bytes turns into 4 bytes + unsigned res = (len*4)/3+4; + // There are 2 extra bytes every CPL output bytes plus 2 extras at the end + if (cpl > 0) { res += 2*(res/cpl + 1); } + else { res+= 1; } + return res; + } + + unsigned Base64Decode(void *outptr, const char *inptr, unsigned len) { + static const signed char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51}; + static const signed char decoding_size = sizeof(decoding); + const signed char *i = (const signed char*)inptr; + const signed char *e = i + len; + signed char *o = (signed char*)outptr; + signed char fragment; + signed char result; +#define DECODE_VALUE()\ + do {\ + if (i == e) { return o - (signed char*)outptr; }\ + signed char val = *i++ - 43;\ + if (val < 0 || val > decoding_size) { fragment = -1; }\ + else { fragment = decoding[(int)val]; }\ + } while (fragment < 0) + + while (true) { + // Step A + DECODE_VALUE(); + result = (fragment & 0x03f) << 2; + // Step B + DECODE_VALUE(); + result |= (fragment & 0x030) >> 4; + *o++ = result; + result = (fragment & 0x00f) << 4; + // Step C + DECODE_VALUE(); + result |= (fragment & 0x03c) >> 2; + *o++ = result; + result = (fragment & 0x003) << 6; + // Step D + DECODE_VALUE(); + result |= (fragment & 0x03f); + *o++ = result; + } +#undef DECODE_VALUE + } + + unsigned Base64DecodeSize(unsigned len) { + return (len*3)/4 + 1; + } +} diff --git a/src/hos_libvariant/src/src/Base64.h b/src/hos_libvariant/src/src/Base64.h new file mode 100644 index 00000000..b340483a --- /dev/null +++ b/src/hos_libvariant/src/src/Base64.h @@ -0,0 +1,24 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_BASE64_H +#define VARIANT_BASE64_H +#pragma once +#include +namespace libvariant { + /// Encode the binary blob of len pointed to by inptr + //into a base64 string encoding in the buffer pointed to by + //outptr. The buffer for outptr should be at least Base64EncodeSize(len) + //in length, returns the actual length of the output + unsigned Base64Encode(char *outptr, const void *inptr, unsigned len, unsigned cpl = 72); + unsigned Base64Encode(char *outptr, const struct iovec *iov, unsigned iov_len, unsigned cpl = 72); + unsigned Base64EncodeSize(unsigned len, unsigned cpl=72); + /// Decode a base64 encoded string of length len to a binary blob + //The blob will be no larger than Base64DecodeSize(len) + //returns the actual size of the blob + unsigned Base64Decode(void *outptr, const char *inptr, unsigned len); + unsigned Base64DecodeSize(unsigned len); +} +#endif + diff --git a/src/hos_libvariant/src/src/Blob.cc b/src/hos_libvariant/src/src/Blob.cc new file mode 100644 index 00000000..59b9917a --- /dev/null +++ b/src/hos_libvariant/src/src/Blob.cc @@ -0,0 +1,123 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include "../../src/include/Variant/Blob.h" + +#include +#include +#include +#include + +namespace libvariant { + + static void MallocFree(void *ptr, void *) { + free(ptr); + } + + shared_ptr Blob::Create(void *ptr, unsigned len, BlobFreeFunc ffunc, void *context) + { + struct iovec iov = { ptr, len }; + return shared_ptr(new Blob(&iov, 1, ffunc, context)); + } + + BlobPtr Blob::Create(struct iovec *iov, unsigned iov_len, BlobFreeFunc ffunc, void *context) { + return BlobPtr(new Blob(iov, iov_len, ffunc, context)); + } + + shared_ptr Blob::CreateCopy(const void *ptr, unsigned len) { + struct iovec iov = { (void*)ptr, len }; + return CreateCopy(&iov, 1); + } + + BlobPtr Blob::CreateCopy(const struct iovec *iov, unsigned iov_len) { + unsigned len = 0; + for (unsigned i = 0; i < iov_len; ++i) { len += iov[i].iov_len; } + void *data = 0; +#ifdef __APPLE__ + // TODO: Remove when apple fixes this error. + if (posix_memalign(&data, 64, std::max(len, 1u)) != 0) { + throw std::bad_alloc(); + } +#else + if (posix_memalign(&data, 64, len) != 0) { + throw std::bad_alloc(); + } +#endif + for (unsigned i = 0, copied = 0; i < iov_len; ++i) { + memcpy((char*)data + copied, iov[i].iov_base, iov[i].iov_len); + copied += iov[i].iov_len; + } + struct iovec v = { data, len }; + return shared_ptr(new Blob(&v, 1, MallocFree, 0)); + } + + shared_ptr Blob::CreateFree(void *ptr, unsigned len) { + struct iovec iov = { ptr, len }; + return CreateFree(&iov, 1); + } + + BlobPtr Blob::CreateFree(struct iovec *iov, unsigned iov_len) { + return shared_ptr(new Blob(iov, iov_len, MallocFree, 0)); + } + + shared_ptr Blob::CreateReferenced(void *ptr, unsigned len) { + struct iovec iov = { ptr, len }; + return CreateReferenced(&iov, 1); + } + + BlobPtr Blob::CreateReferenced(struct iovec *iov, unsigned iov_len) { + return shared_ptr(new Blob(iov, iov_len, 0, 0)); + } + + Blob::Blob(struct iovec *v, unsigned l, BlobFreeFunc f, void *c) + : iov(v, v+l), free_func(f), ctx(c) + { + } + + Blob::~Blob() { + if (free_func) { + for (unsigned i = 0; i < iov.size(); ++i) { + free_func(iov[i].iov_base, ctx); + } + } + iov.clear(); + free_func = 0; + ctx = 0; + } + + shared_ptr Blob::Copy() const { + return CreateCopy(&iov[0], iov.size()); + } + + unsigned Blob::GetTotalLength() const { + unsigned size = 0; + for (unsigned i = 0; i < iov.size(); ++i) { + size += iov[i].iov_len; + } + return size; + } + + int Blob::Compare(ConstBlobPtr other) const { + unsigned our_offset = 0; + unsigned oth_offset = 0; + unsigned i = 0, j = 0; + while (i < GetNumBuffers() && j < other->GetNumBuffers()) { + unsigned len = std::min(GetLength(i) - our_offset, other->GetLength(j) - oth_offset); + int res = memcmp((char*)(GetPtr(i)) + our_offset, (char*)(other->GetPtr(j)) + oth_offset, len); + if (res != 0) { return res; } + our_offset += len; + if (our_offset >= GetLength(i)) { + our_offset = 0; + ++i; + } + oth_offset += len; + if (oth_offset >= other->GetLength(j)) { + oth_offset = 0; + ++j; + } + } + return 0; + } +} + diff --git a/src/hos_libvariant/src/src/BlobMagic.h b/src/hos_libvariant/src/src/BlobMagic.h new file mode 100644 index 00000000..31ff9935 --- /dev/null +++ b/src/hos_libvariant/src/src/BlobMagic.h @@ -0,0 +1,20 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_BLOBMAGIC_H +#define VARIANT_BLOBMAGIC_H +#pragma once + +// We implement blobs by prepending the encoding with a special value +// of \0BLOB to identify it for those serialization formats that do not +// provide a method to distinguish strings and binary data. + +// Raw encoding +#define MAGIC_BLOB_TAG "\0BLOB" +// Length of raw encoding +#define MAGIC_BLOB_LENGTH 5 +// The string encoding for json +#define MAGIC_BLOB_JSONSTR "\\u0000BLOB" + +#endif diff --git a/src/hos_libvariant/src/src/BundleHdrEmitter.cc b/src/hos_libvariant/src/src/BundleHdrEmitter.cc new file mode 100644 index 00000000..ec791f81 --- /dev/null +++ b/src/hos_libvariant/src/src/BundleHdrEmitter.cc @@ -0,0 +1,126 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include "../../src/src/BundleHdrEmitter.h" + +#include +#include +#include +#include + +#define BUNDLE_VERSION_KEY "bundle.version" +#define BUNDLE_VERSION "0.0" + +namespace libvariant { + + BundleHdrEmitterImpl::BundleHdrEmitterImpl(shared_ptr o, Variant params) + : output(o), + state(BHE_START), + numeric_precision(std::numeric_limits::digits10+2) + { + } + + + BundleHdrEmitterImpl::~BundleHdrEmitterImpl() { + Close(); + } + + + void BundleHdrEmitterImpl::BeginDocument() { + if (state != BHE_START) { + throw std::runtime_error("BundleHdrEmitter in invalid state for BeginDocument"); + } + Write(BUNDLE_VERSION_KEY ": " BUNDLE_VERSION "\n"); + state = BHE_BEGIN; + } + + void BundleHdrEmitterImpl::EndDocument() { + if (state == BHE_STOP) { + throw std::runtime_error("BundleHdrEmitter in invalid state for EndDocument"); + } + state = BHE_STOP; + Flush(); + } + + void BundleHdrEmitterImpl::BeginMap(int) { + if (state == BHE_START) { + BeginDocument(); + } + if (state != BHE_BEGIN) { + throw std::runtime_error("BundleHdrEmitter in invalid state for BeginDocument"); + } + state = BHE_KEY; + } + + void BundleHdrEmitterImpl::EndMap() { + if (state != BHE_KEY) { + throw std::runtime_error("BundleHdrEmitter in invalid state for EndMap"); + } + state = BHE_END; + } + + void BundleHdrEmitterImpl::BeginList(int) { + if (state != BHE_VALUE) { + throw std::runtime_error("BundleHdrEmitter in invalid state for BeginList"); + } + state = BHE_LIST_START; + } + + void BundleHdrEmitterImpl::EndList() { + if (state != BHE_LIST && state != BHE_LIST_START) { + throw std::runtime_error("BundleHdrEmitter in invalid state for EndList"); + } + Write("|\n"); + state = BHE_KEY; + } + + + void BundleHdrEmitterImpl::EmitNull() { + Value("", 0); + } + + void BundleHdrEmitterImpl::EmitTrue() { + Value("1", 1); + } + + void BundleHdrEmitterImpl::EmitFalse() { + Value("0", 1); + } + + void BundleHdrEmitterImpl::Emit(const char *v) { + Value(v, strlen(v)); + } + + void BundleHdrEmitterImpl::Emit(intmax_t v) { + std::ostringstream oss; + oss << v; + Value(oss.str().c_str(), oss.str().length()); + } + + void BundleHdrEmitterImpl::Emit(uintmax_t v) { + std::ostringstream oss; + oss << v; + Value(oss.str().c_str(), oss.str().length()); + } + + void BundleHdrEmitterImpl::Emit(double v) { + std::ostringstream oss; + oss << std::setprecision(numeric_precision) << std::showpoint << v; + Value(oss.str().c_str(), oss.str().length()); + } + + void BundleHdrEmitterImpl::Emit(ConstBlobPtr b) { + throw std::runtime_error("BundleHdr is not able to serialize the blob type"); + } + + void BundleHdrEmitterImpl::Flush() { output->Flush(); } + + void BundleHdrEmitterImpl::Close() { + if (state != BHE_STOP) { + EndDocument(); + } + Flush(); + } + +} diff --git a/src/hos_libvariant/src/src/BundleHdrEmitter.h b/src/hos_libvariant/src/src/BundleHdrEmitter.h new file mode 100644 index 00000000..277d17e1 --- /dev/null +++ b/src/hos_libvariant/src/src/BundleHdrEmitter.h @@ -0,0 +1,110 @@ +/** \file + * \author John Bridgman + * \brief A simple emitter that will emit a Bundle header + */ +#ifndef VARIANT_BUNDLEHDREMITTER_H +#define VARIANT_BUNDLEHDREMITTER_H + +#pragma once +#include "../../src/include/Variant/Emitter.h" +#include "../../src/include/Variant/EmitterOutput.h" +#include + +namespace libvariant { + + /** + * This emitter is designed so that its output gives predictable + * results for the original bundle parser. This means that the parser + * in this library will not produce identical results. I.e., + * boolian values will be converted to 0, 1. + * + * Parameters: + * "precision": number of digits for a float + */ + class BundleHdrEmitterImpl : public EmitterImpl { + enum BHEState_t { + BHE_START, + BHE_BEGIN, + BHE_KEY, + BHE_VALUE, + BHE_LIST_START, + BHE_LIST, + BHE_END, + BHE_STOP + }; + public: + BundleHdrEmitterImpl(shared_ptr o, Variant params); + + virtual ~BundleHdrEmitterImpl(); + + virtual void BeginDocument(); + virtual void EndDocument(); + virtual void BeginMap(int length); + virtual void EndMap(); + virtual void BeginList(int length); + virtual void EndList(); + + virtual void EmitNull(); + virtual void EmitTrue(); + virtual void EmitFalse(); + virtual void Emit(const char *v); + virtual void Emit(intmax_t v); + virtual void Emit(uintmax_t v); + virtual void Emit(double v); + virtual void Emit(ConstBlobPtr b); + + virtual void Flush(); + virtual void Close(); + + virtual Variant GetParam(const std::string &key) { + if (key == "precision") { return numeric_precision; } + return Variant::NullType; + } + virtual Variant GetParams() { return Variant().Set("precision", numeric_precision); } + virtual void SetParam(const std::string &key, Variant value) { + if (key == "precision") { numeric_precision = value.AsUnsigned(); } + } + private: + + void Value(const char *v, unsigned len) { + switch (state) { + case BHE_KEY: + Write(v, len); + Write(": "); + state = BHE_VALUE; + break; + case BHE_VALUE: + Write(v, len); + Write("\n"); + state = BHE_KEY; + break; + case BHE_LIST_START: + Write(v, len); + state = BHE_LIST; + break; + case BHE_LIST: + Write("|"); + Write(v, len); + break; + default: + throw std::runtime_error("BundleHdrEmitter in invalid state to emit a scalar value."); + } + } + + void Write(const char *str) { + Write(str, strlen(str)); + } + + void Write(const char *str, unsigned len) { + unsigned num_written = 0; + while (num_written < len) { + num_written += output->Write(str + num_written, len - num_written); + } + } + + shared_ptr output; + BHEState_t state; + unsigned numeric_precision; + }; +} +#endif diff --git a/src/hos_libvariant/src/src/BundleHdrParser.cc b/src/hos_libvariant/src/src/BundleHdrParser.cc new file mode 100644 index 00000000..60304495 --- /dev/null +++ b/src/hos_libvariant/src/src/BundleHdrParser.cc @@ -0,0 +1,217 @@ +/** \file + * \author John Bridgman + * \brief A parser for the Bundle header. + */ +#include "BundleHdrParser.h" +#include +#include +#include +#include +#include +#include "GuessScalar.h" + +#define BUNDLE_VERSION_KEY "bundle.version" + +namespace libvariant { + + void BundleHdrParserImpl::ReadLine() { + line_len = 0; + unsigned len = 0; + while (true) { + line = (const char *)input->GetPtr(len); + if (!line || line_len == len) { + line = 0; + return; + } + for (;line_len < len; ++line_len) { + if (line[line_len] == '\n') { + return; + } + } + len += 4096; + } + } + + void BundleHdrParserImpl::RetireLine() { + input->Release(line_len + 1); + line = 0; + line_len = 0; + } + + bool BundleHdrParserImpl::ScanLine() { + // Fill key and value + //if (sscanf(line, " %[^: \t#] : %[^#]", &key[0], &value[0]) >= 1) { + if (line_len == 0) { return false; } + bool loop = true; + const char *c = line; + const char *e = line + line_len; + key.clear(); + value.clear(); + while (isspace(*c) && c != e) { ++c; } + loop = true; + while (loop && c != e) { + switch (*c) { + case ':': + case ' ': + case '\t': + loop = false; + break; + case '#': + return false; + default: + key.push_back(*c); + ++c; + break; + } + } + key.push_back('\0'); + while (isspace(*c) && c != e) { ++c; } + if (*c != ':') { + return false; + } + ++c; + while (isspace(*c) && c != e) { ++c; } + while (c != e && *c != '#') { + value.push_back(*c); + ++c; + } + value.push_back('\0'); + return true; + } + + int BundleHdrParserImpl::Run() { + while (!action_stack.empty()) { + switch (state) { + case START: + { + unsigned len = 0; + const char *ptr = (const char*)input->GetPtr(len); + if (len == 0 || !ptr) { + state = STOP; + return 1; + } + state = BEGIN_MAP; + TopAction()->BeginDocument(this); + } + break; + case BEGIN_MAP: + state = KEY; + TopAction()->BeginMap(this, -1, 0, 0); + break; + case KEY: + while (true) { + ReadLine(); + if (!line) { + state = END_MAP; + break; + } + ++line_num; + bool success = ScanLine(); + RetireLine(); + if (success) { + // If it is the version key, ignore this line + if (strcmp(&key[0], BUNDLE_VERSION_KEY) == 0) { + continue; + } + // Remove whitespace from end of value + char *e = strchr(&value[0], '\0'); + while (--e >= &value[0] && isspace(*e)) { *e = '\0'; } + state = VALUE; + TopAction()->Scalar(this, &key[0], strlen(&key[0]), 0, 0); + key.clear(); + break; + } + } + break; + case VALUE: + { + char *list_context = 0; + int i = 0; + bool bar_at_end = (value.size() > 1 && value[value.size()-2] == '|'); + while (true) { + char *v = strtok_r((i == 0 ? &value[0] : 0), "|", &list_context); + if (!v) { + if (i <= 1 && !bar_at_end) { + state = KEY; + list.clear(); + GuessScalar(&value[0], strlen(&value[0]), 0, 0, this, TopAction()); + break; + } else { + state = LIST; + value.clear(); + TopAction()->BeginList(this, -1, 0, 0); + break; + } + } + list.push_back(v); + ++i; + } + } + break; + case LIST: + if (!list.empty()) { + char *v = list.front(); + list.pop_front(); + GuessScalar(v, strlen(v), 0, 0, this, TopAction()); + } else { + state = KEY; + TopAction()->EndList(this); + } + break; + case END_MAP: + state = END; + TopAction()->EndMap(this); + break; + case END: + state = STOP; + TopAction()->EndDocument(this); + break; + case STOP: + return 1; + default: + errorstr = "BundleHdrParser: Inconsistent state"; + throw std::runtime_error(errorstr); + } + } + return 0; + } + + void BundleHdrParserImpl::Reset() { + state = START; + line = 0; + line_len = 0; + key.clear(); + value.clear(); + list.clear(); + line_num = 0; + } + + BundleHdrParserImpl::BundleHdrParserImpl(shared_ptr i) + : input(i), + state(START), + line(0), + line_len(0), + line_num(0) + {} + + BundleHdrParserImpl::~BundleHdrParserImpl() {} + + unsigned BundleHdrParserImpl::GetLine() const { return line_num; } + + bool BundleHdrParserImpl::Done() const { + return state == STOP; + } + + bool BundleHdrParserImpl::Error() const { + return state > STOP; + } + + bool BundleHdrParserImpl::Ok() const { + return state != STOP; + } + + std::string BundleHdrParserImpl::ErrorStr() const { + return errorstr; + } + +} diff --git a/src/hos_libvariant/src/src/BundleHdrParser.h b/src/hos_libvariant/src/src/BundleHdrParser.h new file mode 100644 index 00000000..bebc57cd --- /dev/null +++ b/src/hos_libvariant/src/src/BundleHdrParser.h @@ -0,0 +1,66 @@ +/** \file + * \author John Bridgman + * \brief A parser for the Bundle header. + */ +#ifndef VARIANT_BUNDLEHDRPARSER_H +#define VARIANT_BUNDLEHDRPARSER_H + +#pragma once +#include "../../src/include/Variant/Parser.h" +#include "../../src/include/Variant/SharedPtr.h" +#include +namespace libvariant { + + /** + * A simple parser for the Bundle header. + * + * Maintanance programmer note: BundleParserImpl + * relies on a lot of the implementation details of this class. + */ + class BundleHdrParserImpl : public ParserImpl { + protected: + enum State_t { + START, + BEGIN_MAP, + KEY, + VALUE, + LIST, + END_MAP, + END, + STOP + }; + + public: + BundleHdrParserImpl(shared_ptr i); + virtual ~BundleHdrParserImpl(); + + virtual int Run(); + + unsigned GetLine() const; + /** + * Resets the parser to the state it was in when just constructed. + */ + virtual void Reset(); + + virtual bool Done() const; + virtual bool Error() const; + virtual bool Ok() const; + virtual std::string ErrorStr() const; + protected: + void ReadLine(); + void RetireLine(); + bool ScanLine(); + + shared_ptr input; + State_t state; + const char *line; + unsigned line_len; + std::vector key; + std::vector value; + std::deque list; + unsigned line_num; + std::string errorstr; + }; + +} +#endif diff --git a/src/hos_libvariant/src/src/CMakeLists.txt b/src/hos_libvariant/src/src/CMakeLists.txt new file mode 100644 index 00000000..f1ffaff9 --- /dev/null +++ b/src/hos_libvariant/src/src/CMakeLists.txt @@ -0,0 +1,60 @@ + +set(sources + Variant.cc + VariantEmitting.cc + VariantParsing.cc + Exceptions.cc + Extensions.cc + Blob.cc + Base64.cc + ParseBool.cc + Path.cc + Emitter.cc + EmitterOutput.cc + JSONEmitter.cc + Parser.cc + ParserInput.cc + JSONParser.cc + ../lib/json/JSON_parser.c + GuessScalar.cc + BundleHdrParser.cc + BundleHdrEmitter.cc + GuessFormat.cc + Payload.cc + ArgParse.cc + argparse-schema.cc + Schema.cc + SchemaLoader.cc + json-schema-v4.cc + StackTrace.cc + EventBuffer.cc + ) + +if(LIBVARIANT_ENABLE_XML) + list(APPEND sources XMLPLISTEmitter.cc XMLPLISTParser.cc) +endif() + +if(LIBVARIANT_ENABLE_YAML) + list(APPEND sources YAMLEmitter.cc YAMLParser.cc) +endif() + +if(LIBVARIANT_ENABLE_MSGPACK) + list(APPEND sources MsgPackEmitter.cc MsgPackParser.cc) +endif() + +include_directories("../lib/json/") + +add_library(Variant ${sources}) +set_target_properties(Variant PROPERTIES VERSION ${LIBVARIANT_VERSION}) +target_link_libraries(Variant ${EXTRA_LIBS}) + +add_executable(varsh varsh.cc) +target_link_libraries(varsh Variant) + +install(TARGETS Variant varsh + EXPORT LibVariantLibraryDepends + RUNTIME DESTINATION ${INSTALL_BIN_DIR} + LIBRARY DESTINATION ${INSTALL_LIB_DIR} + ARCHIVE DESTINATION ${INSTALL_LIB_DIR}) + + diff --git a/src/hos_libvariant/src/src/Emitter.cc b/src/hos_libvariant/src/src/Emitter.cc new file mode 100644 index 00000000..e3f12963 --- /dev/null +++ b/src/hos_libvariant/src/src/Emitter.cc @@ -0,0 +1,219 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#include "../../src/include/Variant/Emitter.h" + +#include "../../src/src/JSONEmitter.h" +#ifdef ENABLE_YAML +#include "../../src/src/YAMLEmitter.h" +#endif +#ifdef ENABLE_XML +#include "../../src/src/XMLPLISTEmitter.h" +#endif +#ifdef ENABLE_MSGPACK +#include "../../src/src/MsgPackEmitter.h" +#endif +#include "../../src/src/BundleHdrEmitter.h" +#include "../../src/include/Variant/EmitterOutput.h" + +namespace libvariant { + EmitterImpl::~EmitterImpl() {} + + void EmitterImpl::SetParams(Variant params) { + if (params.IsMap()) { + for (Variant::MapIterator i(params.MapBegin()), e(params.MapEnd()); i != e; ++i) { + SetParam(i->first, i->second); + } + } + } + + Emitter::Emitter() {} + + Emitter::Emitter(shared_ptr i) + : impl(i) + {} + + Emitter::~Emitter() {} + + Emitter &Emitter::BeginDocument() { + impl->BeginDocument(); + return *this; + } + + Emitter &Emitter::EndDocument() { + impl->EndDocument(); + return *this; + } + + Emitter &Emitter::BeginMap(int length) { + impl->BeginMap(length); + return *this; + } + + Emitter &Emitter::EndMap() { + impl->EndMap(); + return *this; + } + + Emitter &Emitter::BeginList(int length) { + impl->BeginList(length); + return *this; + } + + Emitter &Emitter::EndList() { + impl->EndList(); + return *this; + } + + Emitter &Emitter::EmitNull() { + impl->EmitNull(); + return *this; + } + + Emitter &Emitter::EmitTrue() { + impl->EmitTrue(); + return *this; + } + + Emitter &Emitter::EmitFalse() { + impl->EmitFalse(); + return *this; + } + + Emitter &Emitter::Emit(const std::string &v) { + impl->Emit(v.c_str()); + return *this; + } + + Emitter &Emitter::Emit(const char *v) { + impl->Emit(v); + return *this; + } + + Emitter &Emitter::Emit(intmax_t v) { + impl->Emit(v); + return *this; + } + + Emitter &Emitter::Emit(uintmax_t v) { + impl->Emit(v); + return *this; + } + + Emitter &Emitter::Emit(double v) { + impl->Emit(v); + return *this; + } + + Emitter &Emitter::Emit(ConstBlobPtr b) { + impl->Emit(b); + return *this; + } + + void Emitter::Flush() { + impl->Flush(); + } + + void Emitter::Close() { + impl->Close(); + } + + Variant Emitter::GetParam(const std::string &key) { + return impl->GetParam(key); + } + + Variant Emitter::GetParams() { + return impl->GetParams(); + } + + void Emitter::SetParam(const std::string &key, Variant value) { + impl->SetParam(key, value); + } + + void Emitter::SetParams(Variant params) { + impl->SetParams(params); + } + + shared_ptr CreateEmitterOutput(void *ptr, unsigned len, unsigned *out_len) { + return shared_ptr(new EmitterMemoryOutput(ptr, len, out_len)); + } + + shared_ptr CreateEmitterOutput(const char *filename) { + return shared_ptr(new EmitterFilenameOutput(filename)); + } + + shared_ptr CreateEmitterOutput(FILE *f) { + return shared_ptr(new EmitterFileOutput(f, false)); + } + + shared_ptr CreateEmitterOutput(std::streambuf *sb) { + return shared_ptr(new EmitterStreambufOutput(sb, false)); + } + + + Emitter CreateEmitter(shared_ptr o, SerializeType type, Variant params) { + switch (type) { + case SERIALIZE_JSON: + return JSONEmitter(o, params); + case SERIALIZE_XMLPLIST: + return XMLPLISTEmitter(o, params); + case SERIALIZE_BUNDLEHDR: + return BundleHdrEmitter(o, params); + case SERIALIZE_YAML: + return YAMLEmitter(o, params); + case SERIALIZE_MSGPACK: + return MsgPackEmitter(o, params); + default: + throw std::runtime_error("libvariant: Unsupported emitter serialization type."); + } + } + + Emitter JSONEmitter(shared_ptr o, Variant params) { + return Emitter(shared_ptr(new JSONEmitterImpl(o, params))); + } + + Emitter YAMLEmitter(shared_ptr o, Variant params) { +#ifdef ENABLE_YAML + return Emitter(shared_ptr(new YAMLEmitterImpl(o, params))); +#else + throw std::runtime_error("libvariant not compiled with YAML support."); +#endif + } + + Emitter XMLPLISTEmitter(shared_ptr o, Variant params) { +#ifdef ENABLE_XML + return Emitter(shared_ptr(new XMLPLISTEmitterImpl(o, params))); +#else + throw std::runtime_error("libvariant not compiled with plist xml support."); +#endif + } + + Emitter BundleHdrEmitter(shared_ptr o, Variant params) { + return Emitter(shared_ptr(new BundleHdrEmitterImpl(o, params))); + } + + Emitter MsgPackEmitter(shared_ptr o, Variant params) { +#ifdef ENABLE_MSGPACK + return Emitter(shared_ptr(new MsgPackEmitterImpl(o, params))); +#else + throw std::runtime_error("libvariant not compiled with msgpack support."); +#endif + } +} diff --git a/src/hos_libvariant/src/src/EmitterOutput.cc b/src/hos_libvariant/src/src/EmitterOutput.cc new file mode 100644 index 00000000..609406c2 --- /dev/null +++ b/src/hos_libvariant/src/src/EmitterOutput.cc @@ -0,0 +1,100 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ + +#include "../../src/include/Variant/EmitterOutput.h" + +#include +#include +#include +#include + +namespace libvariant { + + EmitterOutput::~EmitterOutput() {} + + EmitterFileOutput::EmitterFileOutput(FILE *f, bool c) : file(f), num_bytes(0), cls(c) {} + + EmitterFileOutput::~EmitterFileOutput() { + if (cls && file) { + fclose(file); + } + file = 0; + } + + unsigned EmitterFileOutput::Write(const void *ptr, unsigned len) { + unsigned num = fwrite(ptr, 1, len, file); + num_bytes += num; + return num; + } + + void EmitterFileOutput::Flush() { + fflush(file); + } + + EmitterFilenameOutput::EmitterFilenameOutput(const char *filename, const char *mode) + : EmitterFileOutput(fopen(filename, mode), true) + { + if (!file) { + std::ostringstream oss; + oss << "Unable to open \"" << filename << "\" with mode \"" + << mode << "\""; + throw std::runtime_error(oss.str()); + } + } + + EmitterStreambufOutput::EmitterStreambufOutput(std::streambuf *sb, bool d) + : streambuf(sb), num_bytes(0), del(d) {} + + EmitterStreambufOutput::~EmitterStreambufOutput() { + if (del && streambuf) { + delete streambuf; + } + streambuf = 0; + } + + unsigned EmitterStreambufOutput::Write(const void *ptr, unsigned len) { + unsigned num = streambuf->sputn((const char*)ptr, len); + num_bytes += num; + return num; + } + + void EmitterStreambufOutput::Flush() { + streambuf->pubsync(); + } + + EmitterMemoryOutput::EmitterMemoryOutput(void *ptr, unsigned len, unsigned *out_len) + : data_ptr(ptr), length(len), out_length(out_len) + { + if (0 == out_length) { + out_length = &out_length_dummy; + } + } + + unsigned EmitterMemoryOutput::Write(const void *ptr, unsigned len) { + if (*out_length + len > length) { + throw std::length_error("Emitter memory output buffer to small."); + } + memcpy(((char*)data_ptr + *out_length), ptr, len); + *out_length += len; + return len; + } + +} diff --git a/src/hos_libvariant/src/src/EventBuffer.cc b/src/hos_libvariant/src/src/EventBuffer.cc new file mode 100644 index 00000000..43eb533c --- /dev/null +++ b/src/hos_libvariant/src/src/EventBuffer.cc @@ -0,0 +1,283 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include "../../src/src/EventBuffer.h" + +#include +#include +#include +#include + +namespace libvariant { + + EmitterParserActions::~EmitterParserActions() {} + + void EventBuffer::Event::Fire(ParserImpl *that, ParserActions *a) const { + switch (type) { + case BEGIN_DOCUMENT: + a->BeginDocument(that); + break; + case END_DOCUMENT: + a->EndDocument(that); + break; + case BEGIN_MAP: + a->BeginMap(that, val.len, 0, 0); + break; + case END_MAP: + a->EndMap(that); + break; + case BEGIN_LIST: + a->BeginList(that, val.len, 0, 0); + break; + case END_LIST: + a->EndList(that); + break; + case SCALAR_NULL: + a->Null(that, 0, 0); + break; + case SCALAR_BOOL: + a->Scalar(that, val.b, 0, 0); + break; + case SCALAR_STRING: + a->Scalar(that, s.c_str(), s.length(), 0, 0); + break; + case SCALAR_INT: + a->Scalar(that, val.i, 0, 0); + break; + case SCALAR_UINT: + a->Scalar(that, val.u, 0, 0); + break; + case SCALAR_FLOAT: + a->Scalar(that, val.d, 0, 0); + break; + case SCALAR_BLOB: + a->Scalar(that, blob->Copy(), 0, 0); + break; + default: + throw std::runtime_error("EventBuffer::Event::Fire Encountered an incorrect event."); + } + } + + bool EventBuffer::Event::operator==(const Event &o) const { + switch (type) { + case SCALAR_BOOL: + return val.b == o.val.b; + case SCALAR_FLOAT: + return val.d == o.val.d || (val.d != val.d && o.val.d != o.val.d); + case SCALAR_STRING: + return s == o.s; + case SCALAR_INT: + return val.i == o.val.i; + case SCALAR_UINT: + return val.u == o.val.u; + default: + if (type != o.type) { return false; } + break; + } + return true; + } + + void EventBuffer::Event::Print(std::ostream &os) const { + switch (type) { + case BEGIN_DOCUMENT: + os << "Event(BEGIN_DOCUMENT)"; + break; + case END_DOCUMENT: + os << "Event(END_DOCUMENT)"; + break; + case BEGIN_MAP: + os << "Event(BEGIN_MAP, " << val.len << ")"; + break; + case END_MAP: + os << "Event(END_MAP)"; + break; + case BEGIN_LIST: + os << "Event(BEGIN_LIST, " << val.len << ")"; + break; + case END_LIST: + os << "Event(END_LIST)"; + break; + case SCALAR_BOOL: + os << "Event(SCALAR_BOOL, " << std::boolalpha << val.b << ")"; + break; + case SCALAR_FLOAT: + os << "Event(SCALAR_FLOAT, " << val.d << ")"; + break; + case SCALAR_STRING: + os << "Event(SCALAR_STRING, " << s << ")"; + break; + case SCALAR_NULL: + os << "Event(SCALAR_NULL)"; + break; + case SCALAR_INT: + os << "Event(SCALAR_INT, " << val.i << ")"; + break; + case SCALAR_UINT: + os << "Event(SCALAR_UINT, " << val.u << ")"; + break; + case SCALAR_BLOB: + os << "Event(SCALAR_BLOB)"; + break; + default: + os << "Unknown event (" << (int)type << ")"; + break; + } + } + + EventBuffer::EventBuffer(const EventBuffer &eb) + : level(eb.level), events(eb.events) + { + + } + + EventBuffer::~EventBuffer() {} + + + void EventBuffer::FillRandom(EventType_t disallowed_events, int max_level, bool allow_nan) { + bool begin_document = false; + if (!(BEGIN_DOCUMENT & disallowed_events)) { + BeginDocument(); + begin_document = true; + } + disallowed_events = disallowed_events | BEGIN_DOCUMENT; + EventType_t next_event = RandomEventType(disallowed_events | SCALAR_EVENTS | END_EVENTS, max_level); + switch (next_event) { + case BEGIN_MAP: + MapRandomEvent(disallowed_events, max_level, allow_nan); + break; + case BEGIN_LIST: + ListRandomEvent(disallowed_events, max_level, allow_nan); + break; + default: + // should not be reachable + throw std::runtime_error("EventBuffer::FillRandom reached code that should be not reachable"); + } + + if (begin_document) { + EndDocument(); + } + } + + EventBuffer::EventType_t EventBuffer::RandomEventType(EventBuffer::EventType_t disallowed, int max_level) + { + if (level >= max_level) { + disallowed = disallowed | BEGIN_EVENTS; + } + while (true) { + int bit = rand() % 32; + int val = 1<::infinity(); + if ((type&0x4) == 0) { + val = -val; + } + } else if ((type&0x4) == 0) { + val = std::numeric_limits::quiet_NaN(); + } else { + val = std::numeric_limits::signaling_NaN(); + } + Emit(val); + } + break; + case SCALAR_BLOB: + Emit((ConstBlobPtr)GenerateRandomBlob()); + break; + default: + // should not be reachable + throw std::runtime_error("EventBuffer::BasicRandomEvent reached code that should be not reachable"); + } + } + + void EventBuffer::MapRandomEvent(EventType_t disallowed, int max_level, bool allow_nan) { + int map_len = rand()%10; + BeginMap(map_len); + for (int i = 0; i < map_len; ++i) { + std::string key = GenerateRandomString(); + Emit(key.c_str()); + BasicRandomEvent(disallowed, max_level, allow_nan); + } + EndMap(); + } + + void EventBuffer::ListRandomEvent(EventType_t disallowed, int max_level, bool allow_nan) { + int list_len = rand()%10; + BeginList(list_len); + for (int i = 0; i < list_len; ++i) { + BasicRandomEvent(disallowed, max_level, allow_nan); + } + EndList(); + } +} diff --git a/src/hos_libvariant/src/src/EventBuffer.h b/src/hos_libvariant/src/src/EventBuffer.h new file mode 100644 index 00000000..1ef34bfb --- /dev/null +++ b/src/hos_libvariant/src/src/EventBuffer.h @@ -0,0 +1,269 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_EVENTBUFFER_H +#define VARIANT_EVENTBUFFER_H + +#pragma once +#include "../../src/include/Variant/Emitter.h" +#include "../../src/include/Variant/Parser.h" +#include +#include +namespace libvariant { + + class EmitterParserActions : public ParserActions { + public: + EmitterParserActions(EmitterImpl *i) : impl(i) {} + EmitterParserActions(Emitter i) : impl_ptr(i.GetImpl()) { impl = impl_ptr.get(); } + virtual ~EmitterParserActions(); + + virtual void BeginDocument(ParserImpl *p) + { impl->BeginDocument(); } + virtual void EndDocument(ParserImpl *p) + { impl->EndDocument(); } + virtual void BeginMap(ParserImpl *p, int length, const char *anchor, const char *tag) + { impl->BeginMap(length); } + virtual void EndMap(ParserImpl *p) + { impl->EndMap(); } + virtual void BeginList(ParserImpl *p, int length, const char *anchor, const char *tag) + { impl->BeginList(length); } + virtual void EndList(ParserImpl *p) + { impl->EndList(); } + //virtual void Alias(ParserImpl *p, const char *anchor) + virtual void Scalar(ParserImpl *p, double v, const char *anchor, const char *tag) + { impl->Emit(v); } + virtual void Scalar(ParserImpl *p, const char *str, unsigned length, const char *anchor, const char *tag) + { + std::string v(str, length); + impl->Emit(v.c_str()); + } + virtual void Scalar(ParserImpl *p, bool v, const char *anchor, const char *tag) { + if (v) { impl->EmitTrue(); } + else { impl->EmitFalse(); } + } + virtual void Null(ParserImpl *p, const char *anchor, const char *tag) + { impl->EmitNull(); } + virtual void Scalar(ParserImpl *p, intmax_t v, const char *anchor, const char *tag) + { impl->Emit(v); } + virtual void Scalar(ParserImpl *p, uintmax_t v, const char *anchor, const char *tag) + { impl->Emit(v); } + virtual void Scalar(ParserImpl *p, BlobPtr b, const char *anchor, const char *tag) + { impl->Emit((ConstBlobPtr)b); } + private: + EmitterImpl *impl; + shared_ptr impl_ptr; + }; + + class EventBuffer : public EmitterImpl, public ParserImpl { + public: + enum EventType_t { + NO_EVENT = 0, + BEGIN_DOCUMENT = 1, + END_DOCUMENT = 1<<1, + BEGIN_MAP = 1<<2, + END_MAP = 1<<3, + BEGIN_LIST = 1<<4, + END_LIST = 1<<5, + SCALAR_NULL = 1<<6, + SCALAR_BOOL = 1<<7, + SCALAR_STRING = 1<<8, + SCALAR_INT = 1<<9, + SCALAR_UINT = 1<<10, + SCALAR_FLOAT = 1<<11, + SCALAR_BLOB = 1<<12, + NON_SCALARS = BEGIN_DOCUMENT | END_DOCUMENT | BEGIN_MAP | END_MAP | BEGIN_LIST | END_LIST, + BEGIN_EVENTS = BEGIN_DOCUMENT | BEGIN_MAP | BEGIN_LIST, + END_EVENTS = END_DOCUMENT | END_MAP | END_LIST, + SCALAR_EVENTS = SCALAR_NULL | SCALAR_BOOL | SCALAR_STRING | SCALAR_INT | SCALAR_UINT | + SCALAR_FLOAT | SCALAR_BLOB, + ALL_EVENTS = 0x0FFF + }; + + struct Event { + Event(EventType_t t, Event *p) : type(t), parent(p), key(true) { val.len = 0; } + + Event(Event *p, const char *str) : type(SCALAR_STRING), parent(p), s(str) {} + Event(Event *p, intmax_t v) : type(SCALAR_INT), parent(p) { val.i = v; } + Event(Event *p, uintmax_t v) : type(SCALAR_UINT), parent(p) { val.u = v; } + Event(Event *p, double v) : type(SCALAR_FLOAT), parent(p) { val.d = v; } + Event(Event *p, bool v) : type(SCALAR_BOOL), parent(p) { val.b = v; } + Event(Event *p, ConstBlobPtr b) : type(SCALAR_BLOB), parent(p), blob(b) {} + + private: + void Update() { + if (type == BEGIN_MAP) { + if (key) { + key = false; + } else { + key = true; + val.len++; + } + } else if (type == BEGIN_LIST) { + val.len++; + } + } + + Event *Parent() { + if (type == BEGIN_MAP) { return this; } + if (type == BEGIN_LIST) { return this; } + return parent; + } + public: + void Fire(ParserImpl *that, ParserActions *a) const; + bool operator==(const Event &o) const; + void Print(std::ostream &os) const; + private: + friend class EventBuffer; + EventType_t type; + Event *parent; + union { + bool b; + double d; + intmax_t i; + uintmax_t u; + uintmax_t len; + } val; + bool key; + std::string s; + libvariant::ConstBlobPtr blob; + }; + + private: + Event *Parent() { + if (events.empty()) { return 0; } + else { return events.back().Parent(); } + } + + Event *ParentUpdate() { + Event *p = Parent(); + if (p) { p->Update(); } + return p; + } + + Event *GrandParent() { + Event *p = Parent(); + if (p) { return p->parent; } + else { return 0; } + } + public: + + EventBuffer() : level(0) {} + EventBuffer(const EventBuffer &eb); + virtual ~EventBuffer(); + + virtual void BeginDocument() { + events.push_back(Event(BEGIN_DOCUMENT, Parent())); + level++; + } + + virtual void EndDocument() { + events.push_back(Event(END_DOCUMENT, GrandParent())); + level--; + } + + virtual void BeginMap(int) { + events.push_back(Event(BEGIN_MAP, ParentUpdate())); + level++; + } + + virtual void EndMap() { + events.push_back(Event(END_MAP, GrandParent())); + level--; + } + + virtual void BeginList(int) { + events.push_back(Event(BEGIN_LIST, ParentUpdate())); + level++; + } + + virtual void EndList() { + events.push_back(Event(END_LIST, GrandParent())); + level--; + } + + virtual void EmitNull() { events.push_back(Event(SCALAR_NULL, ParentUpdate())); } + virtual void EmitTrue() { events.push_back(Event(ParentUpdate(), true)); } + virtual void EmitFalse() { events.push_back(Event(ParentUpdate(), false)); } + virtual void Emit(const char *v) { events.push_back(Event(ParentUpdate(), v)); } + virtual void Emit(intmax_t v) { events.push_back(Event(ParentUpdate(), v)); } + virtual void Emit(uintmax_t v) { events.push_back(Event(ParentUpdate(), v)); } + virtual void Emit(double v) { events.push_back(Event(ParentUpdate(), v)); } + virtual void Emit(ConstBlobPtr b) { events.push_back(Event(ParentUpdate(), b)); } + + virtual void Flush() {} + virtual void Close() {} + + virtual Variant GetParam(const std::string &key) { return Variant::NullType; } + virtual Variant GetParams() { return Variant::NullType; } + virtual void SetParam(const std::string &key, Variant value) {} + + void Playback(Emitter e) { + Playback(e.GetImpl().get()); + } + + void Playback(EmitterImpl *e) { + shared_ptr action(new EmitterParserActions(e)); + PushAction(action); + while (!Done()) { Run(); } + PopAction(); + } + + void Fill(Parser p) { + shared_ptr action(new EmitterParserActions(this)); + p.PushAction(action); + unsigned start_events = events.size(); + while (!p.Done() && (level > 0 || start_events == events.size()) && p.Run() == 0); + p.PopAction(); + } + + void FillRandom(EventType_t disallowed_events, int max_level, bool allow_nan); + + virtual int Run() { + while (!events.empty() && !action_stack.empty()) { + ParserActions *a = TopAction(); + events.front().Fire(this, a); + events.pop_front(); + } + return 0; + } + + virtual bool Done() const { return events.empty(); } + virtual bool Error() const { return false; } + virtual bool Ok() const { return !events.empty(); } + virtual std::string ErrorStr() const { return ""; } + virtual void Reset() { events.clear(); } + + bool Equal(const EventBuffer &o) const { + return events == o.events; + } + + unsigned NumEvents() const { return events.size(); } + const Event &GetEvent(int i) const { return events[i]; } + int GetLevel() const { return level; } + + private: + EventType_t RandomEventType(EventType_t disallowed, int max_level); + void BasicRandomEvent(EventType_t disallowed, int max_level, bool allow_nan); + void MapRandomEvent(EventType_t disallowed, int max_level, bool allow_nan); + void ListRandomEvent(EventType_t disallowed, int max_level, bool allow_nan); + + int level; + std::deque events; + }; + + inline EventBuffer::EventType_t operator|(EventBuffer::EventType_t lhs, EventBuffer::EventType_t rhs) { + return (EventBuffer::EventType_t)((int)lhs | (int)rhs); + } + + inline EventBuffer::EventType_t operator&(EventBuffer::EventType_t lhs, EventBuffer::EventType_t rhs) { + return (EventBuffer::EventType_t)((int)lhs & (int)rhs); + } + + inline std::ostream &operator<<(std::ostream &os, const EventBuffer::Event &e) { + e.Print(os); + return os; + } + +} +#endif diff --git a/src/hos_libvariant/src/src/Exceptions.cc b/src/hos_libvariant/src/src/Exceptions.cc new file mode 100644 index 00000000..1669eb75 --- /dev/null +++ b/src/hos_libvariant/src/src/Exceptions.cc @@ -0,0 +1,201 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#include "../../src/include/Variant/Exceptions.h" + +#include + +#include "../../src/src/StackTrace.h" + +namespace libvariant { + + std::ostream &operator <<(std::ostream &os, VariantDefines::Type_t type) { + switch (type) { + case VariantDefines::NullType: + os << "NullType"; + break; + case VariantDefines::BoolType: + os << "BoolType"; + break; + case VariantDefines::IntegerType: + os << "IntegerType"; + break; + case VariantDefines::UnsignedType: + os << "UnsignedType"; + break; + case VariantDefines::FloatType: + os << "FloatType"; + break; + case VariantDefines::StringType: + os << "StringType"; + break; + case VariantDefines::ListType: + os << "ListType"; + break; + case VariantDefines::MapType: + os << "MapType"; + break; + case VariantDefines::BlobType: + os << "BlobType"; + break; + default: + os << "Unknown(" << (int)type << ")"; + break; + } + return os; + } + + void AddStackTrace(std::ostream &os, int level) { +#ifdef ENABLE_STACKTRACE + os << "\nBacktrace:\n" << GetStack(level + 2) << "\n"; +#endif + } + + static inline std::string UnknownTypeErrorMessage(VariantDefines::Type_t type) { + std::ostringstream oss; + oss << "Unknown variant type \"" << type << "\""; + AddStackTrace(oss, 2); + return oss.str(); + } + + UnknownTypeError::UnknownTypeError(VariantDefines::Type_t type) throw() + : std::runtime_error(UnknownTypeErrorMessage(type)) + {} + + static inline std::string UnexpectedTypeErrorMessage(VariantDefines::Type_t expected, VariantDefines::Type_t value) { + std::ostringstream oss; + oss << "Unexpected variant type " << value << " expected " << expected; + AddStackTrace(oss, 2); + return oss.str(); + } + + static inline std::string UnexpectedTypeErrorMessage(const std::vector &expected, + VariantDefines::Type_t value) { + std::ostringstream oss; + oss << "Unexpected variant type " << value << " expected one of "; + for (unsigned i = 0; i < expected.size(); ++i) { + if (i != 0) { oss << ", "; } + oss << expected[i]; + } + AddStackTrace(oss, 2); + return oss.str(); + } + + UnexpectedTypeError::UnexpectedTypeError(VariantDefines::Type_t expected, VariantDefines::Type_t value) throw() + : std::runtime_error(UnexpectedTypeErrorMessage(expected, value)) + {} + + UnexpectedTypeError::UnexpectedTypeError(const std::vector &expected, + VariantDefines::Type_t value) throw() + : std::runtime_error(UnexpectedTypeErrorMessage(expected, value)) + {} + + static inline std::string UnableToConvertErrorMessage(VariantDefines::Type_t sourcetype, + const std::string &targettype) { + std::ostringstream oss; + oss << "Unable to convert variant " << sourcetype << " to " << targettype; + AddStackTrace(oss, 2); + return oss.str(); + } + + UnableToConvertError::UnableToConvertError(VariantDefines::Type_t sourcetype, + const std::string &targettype) throw() + : std::runtime_error(UnableToConvertErrorMessage(sourcetype, targettype)) + {} + + static inline std::string TypeNotIndexableErrorMessage(VariantDefines::Type_t type) { + std::ostringstream oss; + oss << "Variant type " << type << " is not an indexable type."; + AddStackTrace(oss, 2); + return oss.str(); + } + + TypeNotIndexableError::TypeNotIndexableError(VariantDefines::Type_t type) throw() + : std::runtime_error(TypeNotIndexableErrorMessage(type)) + {} + + static inline std::string NotNumericTypeErrorMessage(VariantDefines::Type_t type) { + std::ostringstream oss; + oss << "Variant type " << type << " not a numeric type."; + AddStackTrace(oss, 2); + return oss.str(); + } + + NotNumericTypeError::NotNumericTypeError(VariantDefines::Type_t type) throw() + : std::runtime_error(NotNumericTypeErrorMessage(type)) + {} + + static inline std::string KeyErrorMessage(const std::string &key) { + std::ostringstream oss; + oss << "Key \"" << key << "\" not contained in map."; + AddStackTrace(oss, 2); + return oss.str(); + } + + KeyError::KeyError(const std::string &key) throw() + : std::runtime_error(KeyErrorMessage(key)) + {} + + static inline std::string BadPathErrorMessage(VariantDefines::Type_t type) { + std::ostringstream oss; + oss << "Variant paths do not allow " << type << " as a path element."; + AddStackTrace(oss, 2); + return oss.str(); + } + + static inline std::string BadPathErrorMessage(const std::string &msg) { + std::ostringstream oss; + oss << msg; + AddStackTrace(oss, 2); + return oss.str(); + } + + BadPathError::BadPathError(VariantDefines::Type_t type) throw() + : std::runtime_error(BadPathErrorMessage(type)) + {} + + BadPathError::BadPathError(const std::string &msg) throw() + : std::runtime_error(BadPathErrorMessage(msg)) + {} + + static inline std::string InvalidReferenceErrorMessage(const std::string &msg) { + std::ostringstream oss; + oss << msg; + AddStackTrace(oss, 2); + return oss.str(); + } + + InvalidReferenceError::InvalidReferenceError(const std::string &msg) throw() + : std::runtime_error(InvalidReferenceErrorMessage(msg)) + {} + + static inline std::string InvalidOperationErrorMessage(VariantDefines::Type_t type, const std::string &opname) + { + std::ostringstream oss; + oss << "Variant cannot perform operation " << opname << " on type " << type; + AddStackTrace(oss, 2); + return oss.str(); + } + + InvalidOperationError::InvalidOperationError(VariantDefines::Type_t type, const std::string &opname) throw() + : std::runtime_error(InvalidOperationErrorMessage(type, opname)) + {} +} + diff --git a/src/hos_libvariant/src/src/Extensions.cc b/src/hos_libvariant/src/src/Extensions.cc new file mode 100644 index 00000000..22203caa --- /dev/null +++ b/src/hos_libvariant/src/src/Extensions.cc @@ -0,0 +1,797 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author Josh Staley + * \brief Useful extension functions for Variants + */ + +#include "../../src/include/Variant/Extensions.h" + +#include +#include +#include +#include +#include +#include "../../src/include/Variant/Path.h" +#include "../../src/include/Variant/Variant.h" + +using namespace std; + +#if 0 +#include +#define DBPRINT(x) cout << x +#else +#define DBPRINT(x) +#endif + +namespace libvariant { + + bool SimpleList( const Variant & var ) { + if ( !var.IsList() ) + return false; + for ( unsigned i = 0; i < var.Size(); ++i ) + if ( var[i].IsMap() | var[i].IsList() ) + return false; + return true; + } + + Variant ExtensionParams() { + Variant v; + ExtensionParams(v); + return v; + } + + void ExtensionParams( VariantRef params ) { + if ( params.IsNull() ) { + params = Variant::MapType; + } + + if ( !params.IsMap() ) { + throw runtime_error("# ExtensionParams() - params must be a map"); + } + + if ( !(params.Contains("noSimpleLists") && params["noSimpleLists"].IsBool()) ) { + params["noSimpleLists"] = true; + } + + if ( !params.Contains("pathPrefix") ) { + params["pathPrefix"] = ""; + } + if ( !(params["pathPrefix"].IsString() && params["pathPrefix"].Size() <= 1) ) { + throw runtime_error("# ExtensionParams() - Invalid pathPrefix"); + } + + if ( !params.Contains("pathDelimiter") ) { + params["pathDelimiter"] = "/"; + } + // Must have a delimiter + if ( !(params["pathDelimiter"].IsString() && params["pathDelimiter"].Size() == 1) ) { + throw runtime_error("# ExtensionParams() - Invalid pathDelimiter"); + } + + if ( !params.Contains("indexPrefix") ) { + params["indexPrefix"] = "["; + } + // Must have a prefix + if ( !(params["indexPrefix"].IsString() && params["indexPrefix"].Size() == 1) ) { + throw runtime_error("# ExtensionParams() - Invalid indexPrefix"); + } + + if ( !params.Contains("indexSuffix") ) { + params["indexSuffix"] = "]"; + } + if ( !(params["indexSuffix"].IsString() && params["indexSuffix"].Size() <= 1) ) { + throw runtime_error("# ExtensionParams() - Invalid indexSuffix"); + } + + if ( !params.Contains("listDelimiter") ) { + params["listDelimiter"] = ","; + } + // Must have a delimiter + if ( !(params["listDelimiter"].IsString() && params["listDelimiter"].Size() == 1)) { + throw runtime_error("# ExtensionParams() - Invalid listDelimiter"); + } + } + + Variant FlattenPath( const Variant &var, Variant params ) { + Variant flat; + FlattenPathTo( flat, var, params ); + return flat; + } + + Variant ExpandPath( const Variant &var, Variant params ) { + Variant expand; + ExpandPathTo( expand, var, params ); + return expand; + } + + void FlattenPathTo( VariantRef flat, const Variant &var, Variant params, string prefix ) { + switch ( var.GetType() ) { + case Variant::ListType: + if ( (!params["noSimpleLists"].AsBool()) && SimpleList(var) ) { + if( prefix.size() ) { + flat[prefix] = var.Copy(); + } else { + flat = var.Copy(); + } + } else { + for( unsigned i=0; i < var.Size(); ++i ) { + stringstream tmp; + if ( prefix.size() ) { + tmp << prefix; + } + tmp << params["indexPrefix"].AsString(); + tmp << i; + tmp << params["indexSuffix"].AsString(); + FlattenPathTo( flat, var[i], params, tmp.str() ); + } + } + break; + case Variant::MapType: + for( Variant::ConstMapIterator i(var.MapBegin()), e(var.MapEnd()); i != e; ++i ) { + stringstream tmp; + if ( prefix.size() ) { + tmp << prefix + params["pathDelimiter"].AsString(); + } else { + tmp << params["pathPrefix"].AsString(); + } + tmp << i->first; + FlattenPathTo( flat, i->second, params, tmp.str()); + } + break; + default: + if( prefix.size() ) { + flat[ prefix ] = var.Copy(); + } else { + flat = var.Copy(); + } + } + } + + /// The current version of this funtion is fairly simple and cannot fully + /// reverse the operation FlattenPathTo does on a variant with the same params + /// argument. This primarily has to do with lists. + void ExpandPathTo( VariantRef expand, const Variant &var, Variant params ) { + if ( !var.IsMap() ) { + expand = var; + return; + } + + for ( Variant::ConstMapIterator i(var.MapBegin()), e(var.MapEnd()); i != e; ++i ) { + string path = i->first; + string delimiter = params["pathDelimiter"].AsString(); + if ( delimiter.length() != 1 ) { + throw runtime_error("# ExpandPathTo() - Delimiter is not a single char"); + } + for ( unsigned ii = 0; ii < path.length(); ++ii ) { + if (path[ii] == delimiter[0]) { + path[ii] = '/'; + } + } + expand.SetPath( path, i->second ); + } + } + + map< string, string > FlattenPathToStrStrMap ( const Variant &var, Variant params ) { + map< string, string > flatMap; + Variant flat = FlattenPath( var, params ); + + for ( Variant::MapIterator i(flat.MapBegin()), e(flat.MapEnd()); i != e; ++i ) { + stringstream tmp; + + switch (i->second.GetType()) { + case Variant::ListType: + for ( unsigned j = 0; j < i->second.Size(); ++j ) { + if (j != 0){ + tmp << params["listDelimiter"].AsString(); + } + tmp << i->second[j].AsString(); + } + flatMap[i->first] = tmp.str(); + break; + case Variant::BlobType: + throw runtime_error("# FlattenToStrStrMap() - BlobType not supported"); + default: + flatMap[i->first] = i->second.AsString(); + } + } + + return flatMap; + } + + Variant RDiff ( const Variant &base, const Variant &compare ) { + Variant diff(Variant::MapType); + RDiff( diff, base, compare ); + return diff; + } + + void RDiff ( VariantRef diff, const Variant &base, const Variant &compare ) { + switch ( compare.GetType() ) { + case Variant::MapType: + DBPRINT("Start of map" << endl); + + // Replace and break + if ( !base.IsMap() ) { + diff = compare.Copy(); + break; + } + + for ( Variant::ConstMapIterator i(compare.MapBegin()), e(compare.MapEnd()); i != e; ++i ) { + DBPRINT(i->first << endl); + + // Replace and continue + if ( !base.Contains(i->first) ) { + diff[i->first] = i->second.Copy(); + continue; + } + + // Recurse into map + if ( base[i->first] != i->second ) { + diff[i->first] = Variant::MapType; + DBPRINT("recurse for " << i->first << endl); + RDiff( diff[i->first], base[i->first], compare[i->first] ); + } + + // If map diff became null or an empty map, remove - TODO: should this be an option? + if ( diff.Contains(i->first) ) { + if ( (diff[ i->first ].GetType() == Variant::NullType) || + (diff[ i->first ].GetType() == Variant::MapType && diff[ i->first ].Size() == 0) ) { + diff.Erase(i->first); + } + } + } + break; + default: + if( base != compare ) { + diff = compare.Copy(); + } + } + } + + void RUpdate( VariantRef base, const Variant &update ) { + switch ( update.GetType() ) { + case Variant::NullType: + return; + case Variant::MapType: + if ( !base.Exists() || base.IsMap() ) { + for ( Variant::ConstMapIterator i(update.MapBegin()), e(update.MapEnd()); i != e; ++i ) { + RUpdate(base.At( i->first, Variant::MapType ), update[ i->first ]); + } + break; + } + // else we go to default + default: + base = update.Copy(); + } + } + + std::string JSONPointerUnescape(const std::string &fragment) { + std::string ret; + const char *c = fragment.c_str(); + const char *e = c + fragment.size(); + while (c != e) { + switch (*c) { + case '~': + ++c; + if (c != e) { + if (*c == '0') { + ret.append("~"); + } else if (*c == '1') { + ret.append("/"); + } else { + ret.append("~"); + ret.append(c, 1); + } + ++c; + } + break; + default: + ret.append(c, 1); + ++c; + break; + } + } + return ret; + } + + enum Operations_e { + OP_ADD, + OP_REMOVE, + OP_TEST, + OP_GET + }; + + struct Operation_t { + Operation_t() {} + Operation_t(Operations_e o, const std::string &p) + : op(o), success(false), guess(false), replaced(false), pointer(p) {} + + Operations_e op; + Path path; // path that modification /starts at/ + Variant value; + Variant old_value; + bool success; + bool guess; + bool replaced; + std::string pointer; + }; + + static bool IsIndex(const std::string &str, uintmax_t &index) { + const char *b = str.c_str(); + char *e = 0; + unsigned long long v = strtoull(b, &e, 10); + if (e == b) { return false; } + while (e != 0 && *e != '\0' && isspace(*e)) { ++e; } + if (e == 0 || *e != '\0') { return false; } + index = v; + return true; + } + + VariantRef JSONPointerOp(const std::string &pointer, VariantRef v, Operation_t &op) { + if (pointer.empty()) { + switch (op.op) { + case OP_ADD: + if (v.Exists()) { + op.replaced = true; + op.old_value = v; + } + v = op.value; + op.success = true; + return v; + case OP_REMOVE: + op.value = v; + v = Variant::NullType; + op.success = true; + return v; + case OP_TEST: + op.success = (v == op.value); + return v; + case OP_GET: + op.value = v; + op.success = true; + return v; + } + } + if (pointer[0] != '/') { + throw std::runtime_error("JSON Pointer is required to start with '/'"); + } + std::string::size_type nindex = pointer.find('/', 1); + std::string component = JSONPointerUnescape(pointer.substr(1, nindex - 1)); + bool is_last = (nindex >= pointer.size()); + if (!v.Exists()) { + if (op.guess) { + // Best guess + uintmax_t index = 0; + if (IsIndex(component, index)) { + return JSONPointerOp(pointer.substr(nindex), v.At(index), op); + } else { + return JSONPointerOp(pointer.substr(nindex), v.At(component), op); + } + } else { + throw std::runtime_error("Unable to resolve the JSON Pointer."); + } + } else if (v.IsMap()) { + op.path.push_back(component); + if (is_last) { + switch (op.op) { + case OP_ADD: + if (v.Contains(component)) { + op.replaced = true; + op.old_value = v.Get(component); + } + v.Set(component, op.value); + op.success = true; + return v.At(component); + case OP_REMOVE: + op.value = v.At(component); + v.Erase(component); + op.success = true; + return v.At(component); + case OP_TEST: + { + VariantRef ret = v.At(component); + op.success = (ret == op.value); + return ret; + } + case OP_GET: + { + VariantRef ret = v.At(component); + op.value = ret; + op.success = true; + return ret; + } + } + } else { + return JSONPointerOp(pointer.substr(nindex), v.At(component), op); + } + } else if (v.IsList()) { + if (is_last && component == "-") { + op.path.push_back(v.Size()); + if (op.op == OP_ADD) { + v.Append(op.value); + op.success = true; + return v.At(v.Size()); + } + throw std::runtime_error("Attempting to reference past the end of an array"); + } + uintmax_t index = 0; + if (!IsIndex(component, index)) { + throw std::runtime_error("Attempting to index an array with a string"); + } + op.path.push_back(index); + if (is_last) { + switch (op.op) { + case OP_ADD: + if (v.Contains(index)) { + op.old_value = v.Get(index); + op.replaced = true; + } + v.AsList().insert(v.ListBegin()+index, op.value); + op.success = true; + return v.At(index); + case OP_REMOVE: + op.value = v.At(component); + v.Erase(index); + op.success = true; + return v.At(index); + case OP_TEST: + { + VariantRef ret = v.At(index); + op.success = (ret == op.value); + return ret; + } + case OP_GET: + { + VariantRef ret = v.At(index); + op.value = ret; + op.success = true; + return ret; + } + } + } else { + return JSONPointerOp(pointer.substr(nindex), v.At(index), op); + } + } + std::ostringstream oss; + oss << "The JSON Pointer does not match the document, " + << v.GetType() << " is not a indexable type"; + throw std::runtime_error(oss.str()); + } + + void JSONPointerAdd(const std::string &pointer, VariantRef v, Variant data) { + Operation_t op(OP_ADD, pointer); + op.value = data; + try { + JSONPointerOp(op.pointer, v, op); + } catch (const std::exception &e) { + std::ostringstream oss; + oss << "Error adding a value with the JSON Pointer \"" + << op.pointer << "\" at path \"" + << PathString(op.path) << "\": " << e.what(); + throw std::runtime_error(oss.str()); + } + } + + void JSONPointerRemove(const std::string &pointer, VariantRef v) { + Operation_t op(OP_REMOVE, pointer); + try { + JSONPointerOp(op.pointer, v, op); + } catch (const std::exception &e) { + std::ostringstream oss; + oss << "Error removing a value with the JSON Pointer \"" + << op.pointer << "\" at path \"" + << PathString(op.path) << "\": " << e.what(); + throw std::runtime_error(oss.str()); + } + } + + void JSONPointerReplace(const std::string &pointer, VariantRef v, Variant data) { + Operation_t op(OP_GET, pointer); + try { + if (JSONPointerOp(op.pointer, v, op).Exists()) { + v.SetPath(op.path, data); + } else { + throw std::runtime_error("The target does not exist"); + } + } catch (const std::exception &e) { + std::ostringstream oss; + oss << "Error replacing a value with the JSON Pointer \"" + << op.pointer << "\" at path \"" + << PathString(op.path) << "\": " << e.what(); + throw std::runtime_error(oss.str()); + } + } + + void JSONPointerMove(const std::string &src, const std::string &dst, VariantRef v) { + Operation_t op(OP_REMOVE, src); + try { + JSONPointerOp(op.pointer, v, op); + Variant data = op.value; + Path path = op.path; + try { + op = Operation_t(OP_ADD, dst); + op.value = data; + JSONPointerOp(op.pointer, v, op); + } catch (const std::exception &e) { + v.SetPath(path, data); + throw e; + } + } catch (const std::exception &e) { + std::ostringstream oss; + oss << "Error moving a value with the JSON Pointer \"" + << op.pointer << "\" at path \"" + << PathString(op.path) << "\": " << e.what(); + throw std::runtime_error(oss.str()); + } + } + + void JSONPointerCopy(const std::string &src, const std::string &dst, VariantRef v) { + Operation_t op(OP_GET, src); + try { + VariantRef s = JSONPointerOp(op.pointer, v, op); + if (s.Exists()) { + op = Operation_t(OP_ADD, dst); + op.value = s.Copy(); + JSONPointerOp(op.pointer, v, op); + } else { + throw std::runtime_error("The src does not exist"); + } + } catch (const std::exception &e) { + std::ostringstream oss; + oss << "Error copying a value with the JSON Pointer \"" + << op.pointer << "\" at path \"" + << PathString(op.path) << "\": " << e.what(); + throw std::runtime_error(oss.str()); + } + } + + VariantRef JSONPointerLookup(const std::string &pointer, VariantRef v) { + Operation_t op(OP_GET, pointer); + try { + return JSONPointerOp(op.pointer, v, op); + } catch (const std::exception &e) { + std::ostringstream oss; + oss << "Error looking up a value with the JSON Pointer \"" + << op.pointer << "\" at path \"" + << PathString(op.path) << "\": " << e.what(); + throw std::runtime_error(oss.str()); + } + } + + std::string FormJSONPointer(const Path &path) { + std::ostringstream ret; + for (Path::const_iterator i(path.begin()), e(path.end()); i != e; ++i) { + if (i->IsNumber()) { + ret << "/" << i->AsUnsigned(); + } else { + ret << "/" << i->AsString(); + } + } + return ret.str(); + } + + struct Patch_t { + Patch_t(Operations_e o, Path p, Variant v) : op(o), path(p), value(v) {} + Patch_t(Operations_e o, Path p) : op(o), path(p) {} + Operations_e op; + Path path; + Variant value; + }; + + void JSONPatchUndo(VariantRef v, std::deque *undo) { + while (!undo->empty()) { + const Patch_t &p = undo->back(); + switch (p.op) { + case OP_ADD: + { + Path path = p.path; + if (path.size() > 0) { + PathElement elem = path.back(); + path.pop_back(); + VariantRef r = v.AtPath(path); + if (r.IsList()) { + r.AsList().insert(r.ListBegin()+elem.AsUnsigned(), p.value); + } else { + r.Set(elem.AsString(), p.value); + } + } else { + v = p.value; + } + } + break; + case OP_REMOVE: + v.ErasePath(p.path); + break; + case OP_TEST: + case OP_GET: + throw std::runtime_error("Unable to perform operation here"); + } + undo->pop_back(); + } + } + + + bool JSONPatchOp(VariantRef v, const Variant &diff, std::deque *undo) { + std::string oper = diff.Get("op").AsString(); + Operation_t op; + try { + if (oper == "add") { + op = Operation_t(OP_ADD, diff.Get("path").AsString()); + op.value = diff.Get("value"); + JSONPointerOp(op.pointer, v, op); + if (op.replaced) { + undo->push_back(Patch_t(OP_ADD, op.path, op.old_value)); + } else { + undo->push_back(Patch_t(OP_REMOVE, op.path)); + } + return op.success; + } else if (oper == "remove") { + op = Operation_t(OP_REMOVE, diff.Get("path").AsString()); + JSONPointerOp(op.pointer, v, op); + undo->push_back(Patch_t(OP_ADD, op.path, op.value)); + return op.success; + } else if (oper == "replace") { + op = Operation_t(OP_GET, diff.Get("path").AsString()); + VariantRef r = JSONPointerOp(op.pointer, v, op); + if (r.Exists()) { + r = diff.Get("value"); + } else { + return false; + } + undo->push_back(Patch_t(OP_ADD, op.path, op.value)); + return op.success; + } else if (oper == "move") { + op = Operation_t(OP_REMOVE, diff.Get("from").AsString()); + JSONPointerOp(op.pointer, v, op); + Variant data = op.value; + undo->push_back(Patch_t(OP_ADD, op.path, data)); + op = Operation_t(OP_ADD, diff.Get("path").AsString()); + op.value = data; + JSONPointerOp(op.pointer, v, op); + if (op.replaced) { + undo->push_back(Patch_t(OP_ADD, op.path, op.old_value)); + } else { + undo->push_back(Patch_t(OP_REMOVE, op.path)); + } + return op.success; + } else if (oper == "copy") { + op = Operation_t(OP_GET, diff.Get("from").AsString()); + JSONPointerOp(op.pointer, v, op); + Variant data = op.value; + op = Operation_t(OP_ADD, diff.Get("path").AsString()); + op.value = data; + JSONPointerOp(op.pointer, v, op); + if (op.replaced) { + undo->push_back(Patch_t(OP_ADD, op.path, op.old_value)); + } else { + undo->push_back(Patch_t(OP_REMOVE, op.path)); + } + return op.success; + } else if (oper == "test") { + op = Operation_t(OP_TEST, diff.Get("path").AsString()); + op.value = diff.Get("value"); + JSONPointerOp(op.pointer, v, op); + return op.success; + } + } catch (const std::exception &e) { + std::ostringstream oss; + oss << "Error executing patch op \"" << oper << "\" for pointer: " << op.pointer + << " stopped at: " << PathString(op.path) << "\n\twhat:\n" << e.what(); + throw std::runtime_error(oss.str()); + } + throw std::runtime_error("Unknown JSON Patch operation: " + oper); + } + + std::pair JSONPatch(VariantRef v, const Variant &diff) { + std::deque undo; + try { + bool success = true; + if (diff.IsList()) { + Variant::ConstListIterator i(diff.ListBegin()), e(diff.ListEnd()); + for (;i != e && success; ++i) { + success = JSONPatchOp(v, *i, &undo); + } + } else { + success = JSONPatchOp(v, diff, &undo); + } + std::string msg; + if (!success) { + JSONPatchUndo(v, &undo); + msg = "Failure"; + } + return std::make_pair(success, msg); + } catch (const std::exception &e) { + JSONPatchUndo(v, &undo); + return std::make_pair(false, std::string(e.what())); + } + } + + void JSONDiffRef(VariantRef src, VariantRef dst, VariantRef diff, Path &path) { + if (!dst.Exists()) { + diff.Append( + Variant() + .Set("op", "remove") + .Set("path", FormJSONPointer(path)) + ); + return; + } + if (!src.Exists()) { + diff.Append( + Variant() + .Set("op", "add") + .Set("path", FormJSONPointer(path)) + .Set("value", dst) + ); + return; + } + if (src.GetType() != dst.GetType()) { + diff.Append( + Variant() + .Set("op", "replace") + .Set("path", FormJSONPointer(path)) + .Set("value", dst) + ); + return; + } + if (src != dst) { + switch (src.GetType()) { + case Variant::ListType: + { + uintmax_t len = std::max(src.Size(), dst.Size()); + for (uintmax_t i = 0; i < len; ++i) { + path.push_back(PathElement(i)); + JSONDiffRef(src.At(i), dst.At(i), diff, path); + path.pop_back(); + } + } + break; + case Variant::MapType: + { + std::set keys; + Variant::ConstMapIterator i, e; + for (i = dst.MapBegin(), e = dst.MapEnd(); i != e; ++i) { + keys.insert(i->first); + } + for (i = src.MapBegin(), e = src.MapEnd(); i != e; ++i) { + keys.insert(i->first); + } + for (std::set::iterator i(keys.begin()), e(keys.end()); i != e; ++i) { + path.push_back(PathElement(*i)); + JSONDiffRef(src.At(*i), dst.At(*i), diff, path); + path.pop_back(); + } + } + break; + default: + diff.Append( + Variant() + .Set("op", "replace") + .Set("path", FormJSONPointer(path)) + .Set("value", dst) + ); + break; + } + } + } + + Variant JSONDiff(const Variant &src, const Variant &dst) { + Path path; + Variant diff = Variant::ListType; + JSONDiffRef(src, dst, diff, path); + return diff; + } +} diff --git a/src/hos_libvariant/src/src/GuessFormat.cc b/src/hos_libvariant/src/src/GuessFormat.cc new file mode 100644 index 00000000..51543fc7 --- /dev/null +++ b/src/hos_libvariant/src/src/GuessFormat.cc @@ -0,0 +1,54 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include "../../src/include/Variant/GuessFormat.h" + +#include + +namespace libvariant { + SerializeType GuessFormat(ParserInput* in) { + unsigned len = 0; + const char *ptr = (const char*)in->GetPtr(len); + if (!ptr) { +#ifdef ENABLE_YAML + return SERIALIZE_YAML; +#endif + throw std::runtime_error( + "libvariant::GuessFormat: Unable to guess input format, unexpected end of input." + ); + } + unsigned i = 0; + while (true) { + if (i >= len) { + unsigned l = i+1; + ptr = (const char*)in->GetPtr(l); + if (!ptr) { + throw std::runtime_error( + "libvariant::GuessFormat: Unable to guess input format, unexpected end of input." + ); + } + len = l; + } + if (!isspace(ptr[i])) { + if (ptr[i] == '<') { +#ifdef ENABLE_XML + return SERIALIZE_XMLPLIST; +#else + throw std::runtime_error("libvariant::GuessFormat: Input looks like XML but XML support is not available."); +#endif + } else { + // Even if the start looks like JSON it could still be YAML. + // YAML can also deserialize everything the JSON parser can, + // so choose YAML over JSON. +#ifdef ENABLE_YAML + return SERIALIZE_YAML; +#else + return SERIALIZE_JSON; +#endif + } + } + ++i; + } + } +} diff --git a/src/hos_libvariant/src/src/GuessScalar.cc b/src/hos_libvariant/src/src/GuessScalar.cc new file mode 100644 index 00000000..ccedb43d --- /dev/null +++ b/src/hos_libvariant/src/src/GuessScalar.cc @@ -0,0 +1,120 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include "../../src/src/GuessScalar.h" + +#include +#include +#include +#include +#include +#include + +namespace libvariant { + + namespace { + // Apparently the first match result is the match of the entire pattern + static const char *match_string = "^[[:space:]\n]*(" + "(null|Null|NULL|~)" // Null 2 + "|(true|True|TRUE)" // True 3 + "|(false|False|FALSE)" // False 4 + "|([-+]?[0-9]+)" // int10 5 + "|0o([0-7]+)" // int8 6 + "|0x([0-9a-fA-F]+)" // int16 7 + "|([-+]?((\\.[0-9]+)|([0-9]+(\\.[0-9]*)?))([eE][-+]?[0-9]+)?)" // float 8 (9,10,11,12,13) + "|([-+]?\\.inf|\\.Inf|\\.INF)" // inf 14 + "|(\\.nan|\\.Nan|\\.NAN)" // nan 15 + ")[[:space:]\n]*$"; + enum { + MATCH_NULL = 2, + MATCH_TRUE = 3, + MATCH_FALSE = 4, + MATCH_INT10 = 5, + MATCH_INT8 = 6, + MATCH_INT16 = 7, + MATCH_FLOAT = 8, + MATCH_INF = 14, + MATCH_NAN = 15, + MATCH_MAX = 16 + }; + + class GuessRegex { + public: + GuessRegex(); + ~GuessRegex(); + regex_t guessregex; + + }; + + GuessRegex::GuessRegex() { + int err = 0; + memset(&guessregex, 0, sizeof(regex_t)); + err = regcomp(&guessregex, match_string, REG_EXTENDED); + if (err) { + std::vector buffer(8192); + regerror(err, &guessregex, &buffer[0], buffer.size()); + std::ostringstream oss; + oss << "libvariant library initialization failure: Failed to initialize type guessing regex with error: " + << &buffer[0]; + fputs(oss.str().c_str(), stderr); + throw std::runtime_error(oss.str()); + } + } + + + GuessRegex::~GuessRegex() { + regfree(&guessregex); + } + } + + void GuessScalar(const char *value, unsigned length, const char *anchor, const char *tag, + ParserImpl *p, ParserActions *action) { + static GuessRegex guessregex; + regmatch_t match[MATCH_MAX]; + if (regexec(&guessregex.guessregex, value, MATCH_MAX, &match[0], 0) == 0) { + if (match[MATCH_NULL].rm_so != -1) { + action->Null(p, anchor, tag); + } else if (match[MATCH_TRUE].rm_so != -1) { + action->Scalar(p, true, anchor, tag); + } else if (match[MATCH_FALSE].rm_so != -1) { + action->Scalar(p, false, anchor, tag); + } else if (match[MATCH_INT10].rm_so != -1) { + long long val; + val = strtoll(&value[match[MATCH_INT10].rm_so], 0, 10); + if (val == LLONG_MAX && errno == ERANGE) { + unsigned long long v; + v = strtoull(&value[match[MATCH_INT10].rm_so], 0, 10); + action->Scalar(p, uintmax_t(v), anchor, tag); + } else { + action->Scalar(p, intmax_t(val), anchor, tag); + } + } else if (match[MATCH_INT8].rm_so != -1) { + unsigned long long val; + val = strtoull(&value[match[MATCH_INT8].rm_so], 0, 8); + action->Scalar(p, uintmax_t(val), anchor, tag); + } else if (match[MATCH_INT16].rm_so != -1) { + unsigned long long val; + val = strtoull(&value[match[MATCH_INT16].rm_so], 0, 16); + action->Scalar(p, uintmax_t(val), anchor, tag); + } else if (match[MATCH_FLOAT].rm_so != -1) { + double val = strtod(&value[match[MATCH_FLOAT].rm_so], 0); + action->Scalar(p, val, anchor, tag); + } else if (match[MATCH_INF].rm_so != -1) { + double val = std::numeric_limits::infinity(); + if (value[match[MATCH_INF].rm_so] == '-') { + val = -val; + } + action->Scalar(p, val, anchor, tag); + } else if (match[MATCH_NAN].rm_so != -1) { + double val = std::numeric_limits::quiet_NaN(); + action->Scalar(p, val, anchor, tag); + } else { + action->Scalar(p, value, length, anchor, tag); + } + } else { + action->Scalar(p, value, length, anchor, tag); + } + } + +} diff --git a/src/hos_libvariant/src/src/GuessScalar.h b/src/hos_libvariant/src/src/GuessScalar.h new file mode 100644 index 00000000..88e654c8 --- /dev/null +++ b/src/hos_libvariant/src/src/GuessScalar.h @@ -0,0 +1,14 @@ +/** \file + * \author John Bridgman + * \brief A simple routine that "guesses" what type a scalar is. + */ +#ifndef VARIANT_GUESSSCALAR_H +#define VARIANT_GUESSSCALAR_H + +#pragma once +#include "../../src/include/Variant/Parser.h" +namespace libvariant { + void GuessScalar(const char *value, unsigned length, const char *anchor, const char *tag, + ParserImpl *p, ParserActions *action); +} +#endif diff --git a/src/hos_libvariant/src/src/JSONEmitter.cc b/src/hos_libvariant/src/src/JSONEmitter.cc new file mode 100644 index 00000000..7b9a8ec0 --- /dev/null +++ b/src/hos_libvariant/src/src/JSONEmitter.cc @@ -0,0 +1,299 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= + +#include "../../src/src/JSONEmitter.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../src/include/Variant/EmitterOutput.h" +#include "../../src/src/Base64.h" +#include "../../src/src/BlobMagic.h" + +using namespace std; + +// We do some small buffering optimizations so that we aren't calling +// Write over and over again with very small amounts. + +#define MAX_BUFFER_LEN 512u +#define BUFFER_THRESHOLD 128u + +namespace libvariant { + + JSONEmitterImpl::JSONEmitterImpl(shared_ptr o, Variant params) + : output(o), pretty(false), strict(false), num_indent(4), + numeric_precision(std::numeric_limits::digits10+2), + buffer(MAX_BUFFER_LEN, 0), buffer_len(0) + { + if (params.IsMap()) { + params.GetInto(pretty, "pretty", pretty); + params.GetInto(strict, "strict", strict); + params.GetInto(num_indent, "indent", num_indent); + params.GetInto(numeric_precision, "precision", numeric_precision); + } + } + + JSONEmitterImpl::~JSONEmitterImpl() { + Close(); + } + + void JSONEmitterImpl::BeginDocument() { + } + + void JSONEmitterImpl::EndDocument() { + } + + void JSONEmitterImpl::BeginMap(int length) { + CheckSeparator(); + EmitRaw("{"); + state.push_back(MAP_FIRST); + } + + void JSONEmitterImpl::EndMap() { + state.pop_back(); + EmitIndent(); + EmitRaw("}"); + Flush(); + } + + void JSONEmitterImpl::BeginList(int length) { + CheckSeparator(); + EmitRaw("["); + state.push_back(LIST_FIRST); + } + + void JSONEmitterImpl::EndList() { + state.pop_back(); + EmitIndent(); + EmitRaw("]"); + Flush(); + } + + void JSONEmitterImpl::EmitNull() { + CheckSeparator(); + EmitRaw("null"); + } + + void JSONEmitterImpl::EmitTrue() { + CheckSeparator(); + EmitRaw("true"); + } + + void JSONEmitterImpl::EmitFalse() { + CheckSeparator(); + EmitRaw("false"); + } + + void JSONEmitterImpl::Emit(const char *v) { + CheckSeparator(); + EmitString(v, strlen(v)); + } + + void JSONEmitterImpl::Emit(intmax_t v) { + CheckSeparator(); + std::ostringstream oss; + oss << v; + EmitRaw(oss.str().c_str(), oss.str().length()); + } + + void JSONEmitterImpl::Emit(uintmax_t v) { + CheckSeparator(); + std::ostringstream oss; + oss << v; + EmitRaw(oss.str().c_str(), oss.str().length()); + } + + void JSONEmitterImpl::Emit(double v) { + CheckSeparator(); + std::ostringstream oss; + if (strict && (std::isnan(v) || std::isinf(v))) { + throw std::runtime_error("JSONEmitter: The JSON specification does not permit" + " numeric types that cannot be represented as a series of digits."); + } else if (std::isnan(v) || std::isinf(v)) { + oss << "null"; + } else { + oss << std::setprecision(numeric_precision) << std::showpoint << v; + } + EmitRaw(oss.str().c_str(), oss.str().length()); + } + + void JSONEmitterImpl::Emit(ConstBlobPtr b) { + if (strict) { + throw std::runtime_error("JSONEmitter: Cannot serialize a BlobType" + " in strict JSON mode."); + } + CheckSeparator(); + EmitRaw("\""); + EmitRaw(MAGIC_BLOB_JSONSTR); + std::vector buf(Base64EncodeSize(b->GetTotalLength(), 0)); + unsigned len = Base64Encode(&buf[0], b->GetIOVec(), b->GetNumBuffers(), 0); + EmitRaw(&buf[0], len); + EmitRaw("\""); + } + + void JSONEmitterImpl::Flush() { + if (buffer_len > 0) { + unsigned num_written = 0; + while (num_written < buffer_len) { + num_written += output->Write(&buffer[num_written], buffer_len - num_written); + } + buffer_len = 0; + } + output->Flush(); + } + + void JSONEmitterImpl::Close() { + Flush(); + } + + Variant JSONEmitterImpl::GetParam(const std::string &key) { + if (key == "pretty") { return pretty; } + if (key == "indent") { return num_indent; } + if (key == "precision") { return numeric_precision; } + return Variant::NullType; + } + + Variant JSONEmitterImpl::GetParams() { + Variant ret; + ret["pretty"] = pretty; + ret["indent"] = num_indent; + ret["precision"] = numeric_precision; + return ret; + } + + void JSONEmitterImpl::SetParam(const std::string &key, Variant value) { + if (key == "pretty") { + pretty = value.AsBool(); + } + if (key == "indent") { + num_indent = value.AsUnsigned(); + } + if (key == "precision") { + numeric_precision = value.AsUnsigned(); + } + } + + void JSONEmitterImpl::CheckSeparator() { + if (state.empty()) return; + switch (state.back()) { + case MAP_FIRST: + state.back() = IN_MAP_VALUE; + EmitIndent(); + break; + case IN_MAP_KEY: + state.back() = IN_MAP_VALUE; + EmitRaw(","); + EmitIndent(); + break; + case IN_MAP_VALUE: + state.back() = IN_MAP_KEY; + EmitRaw(": "); + break; + case LIST_FIRST: + state.back() = IN_LIST; + EmitIndent(); + break; + case IN_LIST: + EmitRaw(","); + EmitIndent(); + break; + default: + break; + } + } + + void JSONEmitterImpl::EmitIndent() { + if (!pretty) return; + EmitRaw("\n"); + unsigned indent = state.size() * num_indent; + if (indent > BUFFER_THRESHOLD) { + Flush(); + memset(&buffer[buffer_len], ' ', BUFFER_THRESHOLD); + unsigned num_written = 0; + while (num_written < indent) { + num_written += output->Write(&buffer[buffer_len], min(indent - num_written, BUFFER_THRESHOLD)); + } + } else { + if (indent + buffer_len > MAX_BUFFER_LEN) { + Flush(); + } + memset(&buffer[buffer_len], ' ', indent); + buffer_len += indent; + } + } + + void JSONEmitterImpl::EmitString(const char *text, unsigned len) { + EmitRaw("\""); + const char *end = text + len; + while (text != end) { + if (*text == '\\') { + EmitRaw("\\\\"); + } else if (*text == '\"') { + EmitRaw("\\\""); + //} else if (*text == '/') { + //EmitRaw("\\/"); + } else if (*text == '\b') { + EmitRaw("\\b"); + } else if (*text == '\f') { + EmitRaw("\\f"); + } else if (*text == '\n') { + EmitRaw("\\n"); + } else if (*text == '\r') { + EmitRaw("\\r"); + } else if (*text == '\t') { + EmitRaw("\\t"); + } else if (*text < 0) { + EmitRaw(text, 1); + } else if (*text < 0x20) { + char buffer[7]; + int val = (unsigned char)*text; + snprintf(buffer, sizeof(buffer), "\\u%4.4x", val); + EmitRaw(&buffer[0]); + } else { + EmitRaw(text, 1); + } + ++text; + } + EmitRaw("\""); + } + + void JSONEmitterImpl::EmitRaw(const char *text) { + EmitRaw(text, strlen(text)); + } + void JSONEmitterImpl::EmitRaw(const char *text, unsigned len) { + if (len > BUFFER_THRESHOLD) { + Flush(); + unsigned num_written = 0; + while (num_written < len) { + num_written += output->Write(&text[num_written], len - num_written); + } + } else { + if (len + buffer_len > MAX_BUFFER_LEN) { + Flush(); + } + memcpy(&buffer[buffer_len], text, len); + buffer_len += len; + } + } + +} diff --git a/src/hos_libvariant/src/src/JSONEmitter.h b/src/hos_libvariant/src/src/JSONEmitter.h new file mode 100644 index 00000000..c6707089 --- /dev/null +++ b/src/hos_libvariant/src/src/JSONEmitter.h @@ -0,0 +1,105 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * A simple JSON emitter class to emit valid JSON. + */ +#ifndef VARIANT_JSONEMITTER_H +#define VARIANT_JSONEMITTER_H + +#pragma once +#include +#include +#include +#include +#include "../../src/include/Variant/Emitter.h" + +namespace libvariant { + + /** + * A simple JSON emitter class to make it simple to emit + * valid JSON in a program. + * Does minimal error checking. + * All strings are assumed to be UTF-8 encoded. + * + * This class buffers with a small buffer otherwise it would internally + * perform many calls to write with 1 or 2 bytes. + * Flush automatically happens on EndMap and EndList. + * + * Supported parameters are: + * "pretty": boolean + * "indent": integer (number of spaces to indent when pretty is on, + * default 4) + * "precision": integer (number of digits for a float) + * "strict": be more strict about emitting correct json + */ + class JSONEmitterImpl : public EmitterImpl { + enum State_t { + NONE, + MAP_FIRST, + IN_MAP_KEY, + IN_MAP_VALUE, + LIST_FIRST, + IN_LIST + }; + public: + JSONEmitterImpl(shared_ptr o, Variant params); + + ~JSONEmitterImpl(); + + virtual void BeginDocument(); + virtual void EndDocument(); + virtual void BeginMap(int length); + virtual void EndMap(); + virtual void BeginList(int length); + virtual void EndList(); + + virtual void EmitNull(); + virtual void EmitTrue(); + virtual void EmitFalse(); + virtual void Emit(const char *v); + virtual void Emit(intmax_t v); + virtual void Emit(uintmax_t v); + virtual void Emit(double v); + virtual void Emit(ConstBlobPtr b); + + virtual void Flush(); + virtual void Close(); + + virtual Variant GetParam(const std::string &key); + virtual Variant GetParams(); + virtual void SetParam(const std::string &key, Variant value); + private: + + void CheckSeparator(); + void EmitIndent(); + void EmitString(const char *text, unsigned len); + void EmitRaw(const char *text); + void EmitRaw(const char *text, unsigned len); + + shared_ptr output; + bool pretty; + bool strict; + unsigned num_indent; + unsigned numeric_precision; + std::deque state; + std::vector buffer; + unsigned buffer_len; + }; + +} +#endif diff --git a/src/hos_libvariant/src/src/JSONParser.cc b/src/hos_libvariant/src/src/JSONParser.cc new file mode 100644 index 00000000..5ae0785b --- /dev/null +++ b/src/hos_libvariant/src/src/JSONParser.cc @@ -0,0 +1,214 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + */ +#include "../../src/src/JSONParser.h" + +#include "../../src/src/BlobMagic.h" + +namespace libvariant { + + int JSONParserImpl::StaticCallback(void *ctx, int type, const struct JSON_value_struct* value) { + JSONParserImpl *impl = (JSONParserImpl*)ctx; + if (impl->status == S_BEGIN) { + impl->status = S_OK; + } + // If an exception is thrown from here, the parser will be in an + // inconsistent state. So, set our state to error. + try { + switch(type) { + case JSON_T_ARRAY_BEGIN: + ++impl->depth; + impl->TopAction()->BeginList(impl, -1, 0, 0); + break; + case JSON_T_ARRAY_END: + --impl->depth; + impl->TopAction()->EndList(impl); + break; + case JSON_T_OBJECT_BEGIN: + ++impl->depth; + impl->TopAction()->BeginMap(impl, -1, 0, 0); + break; + case JSON_T_OBJECT_END: + --impl->depth; + impl->TopAction()->EndMap(impl); + break; + case JSON_T_INTEGER: + impl->TopAction()->Scalar(impl, intmax_t(value->vu.integer_value), 0, 0); + break; + case JSON_T_UNSIGNED: + impl->TopAction()->Scalar(impl, uintmax_t(value->vu.unsigned_value), 0, 0); + break; + case JSON_T_FLOAT: + impl->TopAction()->Scalar(impl, value->vu.float_value, 0, 0); + break; + case JSON_T_NULL: + impl->TopAction()->Null(impl, 0, 0); + break; + case JSON_T_TRUE: + impl->TopAction()->Scalar(impl, true, 0, 0); + break; + case JSON_T_FALSE: + impl->TopAction()->Scalar(impl, false, 0, 0); + break; + case JSON_T_KEY: + impl->TopAction()->Scalar(impl, value->vu.str.value, value->vu.str.length, 0, 0); + break; + case JSON_T_STRING: + if (value->vu.str.length >= MAGIC_BLOB_LENGTH && + memcmp(value->vu.str.value, MAGIC_BLOB_TAG, MAGIC_BLOB_LENGTH) == 0) { + void *ptr = 0; + if (posix_memalign(&ptr, 64, Base64DecodeSize(value->vu.str.length)) != 0) { + throw std::bad_alloc(); + } + unsigned len = Base64Decode(ptr, value->vu.str.value+MAGIC_BLOB_LENGTH, + value->vu.str.length-MAGIC_BLOB_LENGTH); + BlobPtr blob = Blob::CreateFree(ptr, len); + impl->TopAction()->Scalar(impl, blob, 0, 0); + } else { + impl->TopAction()->Scalar(impl, value->vu.str.value, value->vu.str.length, 0, 0); + } + break; + default: + break; + } + } catch (...) { + impl->status = S_ERROR; + throw; + } + return true; + } + + JSONParserImpl::JSONParserImpl(shared_ptr i) + : parser(0), + status(S_START), + line(1), + column(0), + charcount(0), + depth(0), + input(i) + { + AllocParser(); + } + + JSONParserImpl::~JSONParserImpl() { + delete_JSON_parser(parser); + parser = 0; + } + + void JSONParserImpl::Reset() { + if (parser) { delete_JSON_parser(parser); } + parser = 0; + status = S_START; + line = 1; + column = 0; + charcount = 0; + depth = 0; + AllocParser(); + } + + void JSONParserImpl::AllocParser() { + JSON_config config; + init_JSON_config(&config); + config.callback = StaticCallback; + config.callback_ctx = this; + config.depth = -1; + config.allow_comments = 1; + parser = new_JSON_parser(&config); + } + + void JSONParserImpl::Parse() { + while ( (status == S_OK || status == S_BEGIN) && !action_stack.empty() ) { + unsigned len = 0; + const unsigned char *ptr = (const unsigned char*)input->GetPtr(len); + const unsigned char *c = ptr; + const unsigned char *end = ptr + len; + if (len == 0 || !ptr) { + if (JSON_parser_done(parser)) { status = S_END; } + else { status = S_ERROR; } + return; + } + while ( c != end && ( status == S_OK || status == S_BEGIN) && !action_stack.empty() ) { + ++charcount; + if (*c == '\n') { + column = 0; + ++line; + } else { ++column; } + if (JSON_parser_char(parser, *c)) { + if (depth == 0) { + if (status == S_OK) { + if (JSON_parser_done(parser)) { status = S_END; } + else { status = S_ERROR; } + } + } + } else if (status == S_OK) { status = S_ERROR; } + ++c; + } + input->Release(c - ptr); + } + } + + int JSONParserImpl::Run() { + while (!action_stack.empty()) { + switch (status) { + case S_START: + TopAction()->BeginDocument(this); + status = S_BEGIN; + return 0; + case S_BEGIN: + Parse(); + break; + case S_OK: + Parse(); + break; + case S_ERROR: + { + std::ostringstream oss; + oss << "JSONParser: An error occurred on line " << line << " column " << column; + errorstr = oss.str(); + throw std::runtime_error(errorstr); + } + case S_END: + status = S_DONE; + TopAction()->EndDocument(this); + return 1; + case S_DONE: + return 1; + default: + { + std::ostringstream oss; + oss << "JSONParser in inconsistent state (line: " << line << " column: " << column << ")"; + errorstr = oss.str(); + throw std::runtime_error("JSONParser in inconsistent state."); + } + } + } + return 0; + } + + JSONParserImpl::Status_t JSONParserImpl::GetStatus() const { return status; } + bool JSONParserImpl::Done() const { return status == S_DONE; } + bool JSONParserImpl::Error() const { return status == S_ERROR; } + bool JSONParserImpl::Ok() const { return status == S_OK; } + + std::string JSONParserImpl::ErrorStr() const { return errorstr; } + + unsigned JSONParserImpl::GetLine() const { return line; } + unsigned JSONParserImpl::GetColumn() const { return column; } + unsigned JSONParserImpl::GetByteCount() const { return charcount; } +} diff --git a/src/hos_libvariant/src/src/JSONParser.h b/src/hos_libvariant/src/src/JSONParser.h new file mode 100644 index 00000000..8fba1a5d --- /dev/null +++ b/src/hos_libvariant/src/src/JSONParser.h @@ -0,0 +1,90 @@ +//============================================================================= +// Computational Process Networks class library +// Copyright (C) 1997-2006 Gregory E. Allen and The University of Texas +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + */ +#ifndef JSON_PARSER_HPP +#define JSON_PARSER_HPP +#pragma once +#include "Base64.h" +#include +#include "JSON_parser.h" +#include +#include +#include +#include +#include +#include +#include + + +namespace libvariant { + /** + * A class that encapsulates the JSON_parser with the Parser interface + */ + class JSONParserImpl : public ParserImpl { + public: + enum Status_t { + S_START, + S_BEGIN, + S_OK, + S_ERROR, + S_END, + S_DONE + }; + JSONParserImpl(shared_ptr i); + virtual ~JSONParserImpl(); + + virtual int Run(); + + /** + * \return the status of the parser. + */ + Status_t GetStatus() const; + virtual bool Done() const; + virtual bool Error() const; + virtual bool Ok() const; + virtual std::string ErrorStr() const; + unsigned GetLine() const; + unsigned GetColumn() const; + unsigned GetByteCount() const; + /** + * Resets the parser to the state it was in when just constructed. + */ + virtual void Reset(); + private: + + void AllocParser(); + + void Parse(); + + static int StaticCallback(void *ctx, int type, const struct JSON_value_struct* value); + + JSON_parser_struct *parser; + Status_t status; + unsigned line; + unsigned column; + unsigned charcount; + unsigned depth; + shared_ptr input; + std::string errorstr; + }; +} +#endif diff --git a/src/hos_libvariant/src/src/MsgPackEmitter.cc b/src/hos_libvariant/src/src/MsgPackEmitter.cc new file mode 100644 index 00000000..6c679af1 --- /dev/null +++ b/src/hos_libvariant/src/src/MsgPackEmitter.cc @@ -0,0 +1,135 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include "../../src/src/MsgPackEmitter.h" + +#include "../../src/src/BlobMagic.h" + +static void msgpack_pack_string(msgpack_packer *packer, const char *str, unsigned len) { + msgpack_pack_raw(packer, len); + msgpack_pack_raw_body(packer, str, len); +} + +namespace libvariant { + + int MsgPackPackerWrite(void* data, const char* buf, unsigned int len) { + return static_cast(data)->Write(buf, len); + } + + MsgPackEmitterImpl::MsgPackEmitterImpl(shared_ptr out, Variant params) + : output(out) + { + msgpack_packer_init(&packer, output.get(), MsgPackPackerWrite); + } + + MsgPackEmitterImpl::~MsgPackEmitterImpl() { + Close(); + } + + + void MsgPackEmitterImpl::BeginDocument() { + } + + void MsgPackEmitterImpl::EndDocument() { + Flush(); + } + + void MsgPackEmitterImpl::BeginMap(int length) { + if (buffer) { buffer->BeginMap(length); } + else if (length < 0) { + buffer.reset(new EventBuffer); + buffer->BeginMap(length); + } else { + msgpack_pack_map(&packer, length); + } + } + + void MsgPackEmitterImpl::EndMap() { + if (buffer) { + buffer->EndMap(); + if (buffer->GetLevel() <= 0) { + shared_ptr buf = buffer; + buffer.reset(); + buf->Playback(this); + } + } + } + + void MsgPackEmitterImpl::BeginList(int length) { + if (buffer) { buffer->BeginList(length); } + else if (length < 0) { + buffer.reset(new EventBuffer); + buffer->BeginList(length); + } else { + msgpack_pack_array(&packer, length); + } + } + + void MsgPackEmitterImpl::EndList() { + if (buffer) { + buffer->EndList(); + if (buffer->GetLevel() <= 0) { + shared_ptr buf = buffer; + buffer.reset(); + buf->Playback(this); + } + } + } + + void MsgPackEmitterImpl::EmitNull() { + if (buffer) { buffer->EmitNull(); } + else { msgpack_pack_nil(&packer); } + } + + void MsgPackEmitterImpl::EmitTrue() { + if (buffer) { buffer->EmitTrue(); } + else { msgpack_pack_true(&packer); } + } + + void MsgPackEmitterImpl::EmitFalse() { + if (buffer) { buffer->EmitFalse(); } + else { msgpack_pack_false(&packer); } + } + + void MsgPackEmitterImpl::Emit(const char *v) { + if (buffer) { buffer->Emit(v); } + else { msgpack_pack_string(&packer, v, strlen(v)); } + } + + void MsgPackEmitterImpl::Emit(intmax_t v) { + if (buffer) { buffer->Emit(v); } + else { msgpack_pack_int64(&packer, v); } + } + + void MsgPackEmitterImpl::Emit(uintmax_t v) { + if (buffer) { buffer->Emit(v); } + else { msgpack_pack_uint64(&packer, v); } + } + + void MsgPackEmitterImpl::Emit(double v) { + if (buffer) { buffer->Emit(v); } + else { msgpack_pack_double(&packer, v); } + } + + void MsgPackEmitterImpl::Emit(ConstBlobPtr b) { + if (buffer) { buffer->Emit(b); } + else { + msgpack_pack_raw(&packer, b->GetTotalLength() + MAGIC_BLOB_LENGTH); + msgpack_pack_raw_body(&packer, MAGIC_BLOB_TAG, MAGIC_BLOB_LENGTH); + for (int i = 0, num = b->GetNumBuffers(); i < num; ++i) { + msgpack_pack_raw_body(&packer, b->GetPtr(i), b->GetLength(i)); + } + } + } + + void MsgPackEmitterImpl::Flush() { + output->Flush(); + } + + void MsgPackEmitterImpl::Close() { + output->Flush(); + } + +} diff --git a/src/hos_libvariant/src/src/MsgPackEmitter.h b/src/hos_libvariant/src/src/MsgPackEmitter.h new file mode 100644 index 00000000..08a80877 --- /dev/null +++ b/src/hos_libvariant/src/src/MsgPackEmitter.h @@ -0,0 +1,51 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_MSGPACK_H +#define VARIANT_MSGPACK_H + +#pragma once +#include "../../src/include/Variant/Variant.h" +#include "../../src/include/Variant/EmitterOutput.h" +#include "../../src/include/Variant/ParserInput.h" +#include "../../src/include/Variant/Parser.h" +#include "../../src/include/Variant/Emitter.h" +#include "../../src/src/EventBuffer.h" +#include +namespace libvariant { + + class MsgPackEmitterImpl : public EmitterImpl { + public: + MsgPackEmitterImpl(shared_ptr out, Variant params); + ~MsgPackEmitterImpl(); + virtual void BeginDocument(); + virtual void EndDocument(); + virtual void BeginMap(int length); + virtual void EndMap(); + virtual void BeginList(int length); + virtual void EndList(); + + virtual void EmitNull(); + virtual void EmitTrue(); + virtual void EmitFalse(); + virtual void Emit(const char *v); + virtual void Emit(intmax_t v); + virtual void Emit(uintmax_t v); + virtual void Emit(double v); + virtual void Emit(ConstBlobPtr b); + + virtual void Flush(); + virtual void Close(); + + virtual Variant GetParam(const std::string &key) { return Variant::NullType; } + virtual Variant GetParams() { return Variant::NullType; } + virtual void SetParam(const std::string &key, Variant value) {} + private: + shared_ptr output; + shared_ptr buffer; + msgpack_packer packer; + }; + +} +#endif diff --git a/src/hos_libvariant/src/src/MsgPackParser.cc b/src/hos_libvariant/src/src/MsgPackParser.cc new file mode 100644 index 00000000..636ceb00 --- /dev/null +++ b/src/hos_libvariant/src/src/MsgPackParser.cc @@ -0,0 +1,250 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include "../../src/src/MsgPackParser.h" + +#include +#include +#include "../../src/src/BlobMagic.h" + +// vmpu = variant msg pack unpack + +struct vmpu_user { + libvariant::MsgPackParserImpl *impl; +}; + +struct vmpu_object { + vmpu_object() : count(0) {} + uint64_t count; +}; + +#define msgpack_unpack_struct(name) \ +struct vmpu ## name + +#define msgpack_unpack_func(ret, name) \ +ret vmpu ## name + +#define msgpack_unpack_callback(name) \ +vmpu_callback ## name + +#define msgpack_unpack_object vmpu_object + +#define msgpack_unpack_user vmpu_user + + +typedef struct vmpu_context vmpu_context; + +static void vmpu_init(vmpu_context* ctx); + +//static vmpu_object vmpu_data(vmpu_context* ctx); + +static int vmpu_execute(vmpu_context* ctx, + const char* data, size_t len, size_t* off); + + +static inline vmpu_object vmpu_callback_root(vmpu_user* u) +{ return vmpu_object(); } + +static inline int vmpu_callback_uint8(vmpu_user* u, uint8_t d, vmpu_object* o) +{ + u->impl->TopAction()->Scalar(u->impl, uint64_t(d), 0, 0); + return 0; +} + +static inline int vmpu_callback_uint16(vmpu_user* u, uint16_t d, vmpu_object* o) +{ + u->impl->TopAction()->Scalar(u->impl, uint64_t(d), 0, 0); + return 0; +} + +static inline int vmpu_callback_uint32(vmpu_user* u, uint32_t d, vmpu_object* o) +{ + u->impl->TopAction()->Scalar(u->impl, uint64_t(d), 0, 0); + return 0; +} + +static inline int vmpu_callback_uint64(vmpu_user* u, uint64_t d, vmpu_object* o) +{ + u->impl->TopAction()->Scalar(u->impl, uint64_t(d), 0, 0); + return 0; +} + +static inline int vmpu_callback_int8(vmpu_user* u, int8_t d, vmpu_object* o) +{ + u->impl->TopAction()->Scalar(u->impl, int64_t(d), 0, 0); + return 0; +} + +static inline int vmpu_callback_int16(vmpu_user* u, int16_t d, vmpu_object* o) +{ + u->impl->TopAction()->Scalar(u->impl, int64_t(d), 0, 0); + return 0; +} + +static inline int vmpu_callback_int32(vmpu_user* u, int32_t d, vmpu_object* o) +{ + u->impl->TopAction()->Scalar(u->impl, int64_t(d), 0, 0); + return 0; +} + +static inline int vmpu_callback_int64(vmpu_user* u, int64_t d, vmpu_object* o) +{ + u->impl->TopAction()->Scalar(u->impl, int64_t(d), 0, 0); + return 0; +} + +static inline int vmpu_callback_float(vmpu_user* u, float d, vmpu_object* o) +{ + u->impl->TopAction()->Scalar(u->impl, double(d), 0, 0); + return 0; +} + +static inline int vmpu_callback_double(vmpu_user* u, double d, vmpu_object* o) +{ + u->impl->TopAction()->Scalar(u->impl, double(d), 0, 0); + return 0; +} + +static inline int vmpu_callback_nil(vmpu_user* u, vmpu_object* o) +{ + u->impl->TopAction()->Null(u->impl, 0, 0); + return 0; +} + +static inline int vmpu_callback_true(vmpu_user* u, vmpu_object* o) +{ + u->impl->TopAction()->Scalar(u->impl, true, 0, 0); + return 0; +} + +static inline int vmpu_callback_false(vmpu_user* u, vmpu_object* o) +{ + u->impl->TopAction()->Scalar(u->impl, false, 0, 0); + return 0; +} + +static inline int vmpu_callback_array(vmpu_user* u, unsigned int n, vmpu_object* o) +{ + u->impl->TopAction()->BeginList(u->impl, n, 0, 0); + o->count = n; + if (n == 0) { + u->impl->TopAction()->EndList(u->impl); + } + return 0; +} + +static inline int vmpu_callback_array_item(vmpu_user* u, vmpu_object* c, vmpu_object o) +{ + c->count--; + if (c->count == 0) { + u->impl->TopAction()->EndList(u->impl); + } + return 0; +} + +static inline int vmpu_callback_map(vmpu_user* u, unsigned int n, vmpu_object* o) +{ + u->impl->TopAction()->BeginMap(u->impl, n, 0, 0); + o->count = n; + if (n == 0) { + u->impl->TopAction()->EndMap(u->impl); + } + return 0; +} + +static inline int vmpu_callback_map_item(vmpu_user* u, vmpu_object* c, + vmpu_object k, vmpu_object v) +{ + c->count--; + if (c->count == 0) { + u->impl->TopAction()->EndMap(u->impl); + } + return 0; +} + +static inline int vmpu_callback_raw(vmpu_user* u, const char* b, const char* p, + unsigned int l, vmpu_object* o) +{ + if (l >= MAGIC_BLOB_LENGTH && memcmp(MAGIC_BLOB_TAG, p, MAGIC_BLOB_LENGTH) == 0) { + u->impl->TopAction()->Scalar(u->impl, + libvariant::Blob::CreateCopy(p + MAGIC_BLOB_LENGTH, l - MAGIC_BLOB_LENGTH), 0, 0); + } else { + u->impl->TopAction()->Scalar(u->impl, p, l, 0, 0); + } + return 0; +} + +#include + +namespace libvariant { + + MsgPackParserImpl::MsgPackParserImpl(shared_ptr in) + : state(START), input(in), + ctx(new vmpu_context), + bytecount(0) + { + vmpu_init(ctx.get()); + ctx->user.impl = this; + } + + MsgPackParserImpl::~MsgPackParserImpl() + {} + + int MsgPackParserImpl::Run() { + while (!action_stack.empty()) { + unsigned len = 0; + const char *ptr = 0; + size_t off = 0; + int ret = 0; + switch (state) { + case START: + TopAction()->BeginDocument(this); + state = OK; + break; + case OK: + while (state == OK) { + if (off > 0) { len = 0; } + else { len += 1; } + ptr = (const char *)input->GetPtr(len); + if (!ptr || len == 0) { + throw std::runtime_error("unexpected end of data"); + } + off = 0; + ret = vmpu_execute(ctx.get(), ptr, len, &off); + if (ret < 0) { + std::ostringstream oss; + oss << "MsgPack: A parse error occured at byte offset " + << off + bytecount; + errorstr = oss.str(); + state = ERROR; + throw std::runtime_error(errorstr); + } else { + bytecount += off; + input->Release(off); + if (ret > 0) { + state = END; + } + } + } + break; + case END: + TopAction()->EndDocument(this); + state = DONE; + break; + case DONE: + return 1; + case ERROR: + throw std::runtime_error(errorstr); + } + } + return 0; + } + + void MsgPackParserImpl::Reset() { + state = START; + vmpu_init(ctx.get()); + ctx->user.impl = this; + } +} diff --git a/src/hos_libvariant/src/src/MsgPackParser.h b/src/hos_libvariant/src/src/MsgPackParser.h new file mode 100644 index 00000000..6ac54e3c --- /dev/null +++ b/src/hos_libvariant/src/src/MsgPackParser.h @@ -0,0 +1,49 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#ifndef VARIANT_MSGPACKPARSER_H +#define VARIANT_MSGPACKPARSER_H + +#pragma once +#include "../../src/include/Variant/ParserInput.h" +#include "../../src/include/Variant/Parser.h" +#include + +struct vmpu_context; + +namespace libvariant { + + class MsgPackParserImpl : public ParserImpl { + public: + enum State_t { + START, + OK, + END, + DONE, + ERROR + }; + + MsgPackParserImpl(shared_ptr in); + virtual ~MsgPackParserImpl(); + + virtual int Run(); + + virtual bool Done() const { return state == DONE; } + virtual bool Error() const { return state == ERROR; } + virtual bool Ok() const { return state == OK; } + /// Return a string describing the last error suitable for presentation to a user + virtual std::string ErrorStr() const { return errorstr; } + /// Reset the parser + virtual void Reset(); + private: + State_t state; + shared_ptr input; + shared_ptr ctx; + std::string errorstr; + unsigned bytecount; + }; +} + +#endif diff --git a/src/hos_libvariant/src/src/ParseBool.cc b/src/hos_libvariant/src/src/ParseBool.cc new file mode 100644 index 00000000..c57fdfcb --- /dev/null +++ b/src/hos_libvariant/src/src/ParseBool.cc @@ -0,0 +1,55 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + */ +#include "../../src/src/ParseBool.h" + +#include + + +bool ParseBool(const std::string &str) { + static const char NO_STR[] = "no"; + static const char FALSE_STR[] = "false"; + bool result = true; + std::string::const_iterator cur = str.begin(); + const std::string::const_iterator end = str.end(); + while (cur != end && isspace(*cur)) { ++cur; } + if (cur == end) return result; + const char *cmpstr = 0; + if (tolower(*cur) == NO_STR[0]) { + cmpstr = &NO_STR[1]; + } else if (tolower(*cur) == FALSE_STR[0]) { + cmpstr = &FALSE_STR[1]; + } else if (*cur == '0') { + ++cur; + while (cur != end && *cur == '0') { ++cur; } + while (cur != end && isspace(*cur)) { ++cur; } + if (cur == end) { result = false; } + return result; + } + if (cmpstr != 0) { + ++cur; + int i = 0; + while (cur != end && cmpstr[i] != '\0' && tolower(*cur) == cmpstr[i]) { + ++cur; ++i; + } + while (cur != end && isspace(*cur)) { ++cur; } + if (cur == end) { result = false; } + } + return result; +} diff --git a/src/hos_libvariant/src/src/ParseBool.h b/src/hos_libvariant/src/src/ParseBool.h new file mode 100644 index 00000000..f6773f8e --- /dev/null +++ b/src/hos_libvariant/src/src/ParseBool.h @@ -0,0 +1,37 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + */ +#ifndef PARSEBOOL_H +#define PARSEBOOL_H +#pragma once +#include +/** + * \brief Parses string for a boolean value. + * + * Considers no, false, 0 and any abreviation + * like " f" to be false + * and everything else to be true (including + * the empty string). + * Ignores whitespace. + * Note "false blah" is true! + * \return true or false + * \param str the string to parse + */ +bool ParseBool(const std::string &str); +#endif diff --git a/src/hos_libvariant/src/src/Parser.cc b/src/hos_libvariant/src/src/Parser.cc new file mode 100644 index 00000000..a0cdb393 --- /dev/null +++ b/src/hos_libvariant/src/src/Parser.cc @@ -0,0 +1,127 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ + +#include "../../src/include/Variant/Parser.h" + +#include + +#include "../../src/include/Variant/ParserInput.h" +#include "../../src/src/JSONParser.h" +#ifdef ENABLE_YAML +#include "../../src/src/YAMLParser.h" +#endif +#ifdef ENABLE_XML +#include "../../src/src/XMLPLISTParser.h" +#endif +#ifdef ENABLE_MSGPACK +#include "../../src/src/MsgPackParser.h" +#endif +#include "../../src/src/BundleHdrParser.h" +#include "../../src/include/Variant/GuessFormat.h" +namespace libvariant { + + ParserActions::~ParserActions() {} + + ParserImpl::~ParserImpl() {} + + void ParserImpl::Reset() { + throw std::runtime_error("Parser does not support reset."); + } + + Parser::Parser() {} + Parser::Parser(shared_ptr pi) : impl(pi) {} + Parser::~Parser() {} + + shared_ptr CreateParserInput(const std::string &str) { + return CreateParserInput(str.c_str(), str.length()); + } + + shared_ptr CreateParserInput(const char *str) { + return shared_ptr(new ParserMemoryInput(str, strlen(str))); + } + shared_ptr CreateParserInput(const void *ptr, unsigned len) { + return shared_ptr(new ParserMemoryInput(ptr, len)); + } + shared_ptr CreateParserInputFile(const char *filename) { + return shared_ptr(new ParserFilenameInput(filename)); + } + + shared_ptr CreateParserInputFile(FILE *f) { + return shared_ptr(new ParserFileInput(f)); + } + + shared_ptr CreateParserInputFile(std::streambuf *sb) { + return shared_ptr(new ParserStreambufInput(sb)); + } + + Parser CreateParser(shared_ptr i, SerializeType type) { + switch (type) { + case SERIALIZE_XMLPLIST: + return XMLPLISTParser(i); + case SERIALIZE_JSON: + return JSONParser(i); + case SERIALIZE_BUNDLEHDR: + return BundleHdrParser(i); + case SERIALIZE_GUESS: + return CreateParserGuess(i); + case SERIALIZE_MSGPACK: + return MsgPackParser(i); + case SERIALIZE_YAML: + default: + return YAMLParser(i); + } + } + + Parser CreateParserGuess(shared_ptr i) { + SerializeType type = GuessFormat(i.get()); + return CreateParser(i, type); + } + + Parser JSONParser(shared_ptr i) { + return Parser(shared_ptr(new JSONParserImpl(i))); + } + Parser YAMLParser(shared_ptr i) { +#ifdef ENABLE_YAML + return Parser(shared_ptr(new YAMLParserImpl(i))); +#else + throw std::runtime_error("libvariant not compiled with YAML support."); +#endif + } + Parser XMLPLISTParser(shared_ptr i) { +#ifdef ENABLE_XML + return Parser(shared_ptr(new XMLPLISTParserImpl(i))); +#else + throw std::runtime_error("libvariant not compiled with plist xml support."); +#endif + } + + Parser BundleHdrParser(shared_ptr i) { + return Parser(shared_ptr(new BundleHdrParserImpl(i))); + } + + Parser MsgPackParser(shared_ptr i) { +#ifdef ENABLE_MSGPACK + return Parser(shared_ptr(new MsgPackParserImpl(i))); +#else + throw std::runtime_error("libvariant not compiled with msgpack support."); +#endif + } +} diff --git a/src/hos_libvariant/src/src/ParserInput.cc b/src/hos_libvariant/src/src/ParserInput.cc new file mode 100644 index 00000000..ff8329ca --- /dev/null +++ b/src/hos_libvariant/src/src/ParserInput.cc @@ -0,0 +1,164 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ + +#include "../../src/include/Variant/ParserInput.h" + +#include +#include +#include +#include +#include + +namespace libvariant { + + //---------------------------------------------------------------------- + // ParserInput + + ParserInput::~ParserInput() {} + + //---------------------------------------------------------------------- + // ParserStreamInput + + ParserStreamInput::ParserStreamInput(unsigned buffer_len) + : buffer(buffer_len), + num(0), + offset(0), + eof(false) + { + + } + + const void *ParserStreamInput::GetPtr(unsigned &len) { + if (eof) { + len = num; + if (num == 0) { return 0; } + return &buffer[offset]; + } + if (len <= num && num > 0) { + len = num; + return &buffer[offset]; + } + if (len + offset > buffer.size()) { + if (len > buffer.size()) { + std::vector newbuffer(len); + memmove(&newbuffer[0], &buffer[offset], num); + std::swap(newbuffer, buffer); + } else { + memmove(&buffer[0], &buffer[offset], num); + } + offset = 0; + } + while (!eof && (num < len || num == 0)) { + unsigned to_read = buffer.size() - num - offset; + unsigned num_read = Read(&buffer[num + offset], to_read); + if (num_read < to_read) { eof = true; } + num += num_read; + } + len = num; + if (num == 0 && eof) { return 0; } + return &buffer[offset]; + } + + void ParserStreamInput::Release(unsigned len) { + if (len > num) { + throw std::runtime_error("ParserStreamInput: trying to release more than was aquired."); + } else if (len == num) { + num = 0; + offset = 0; + } else { + offset += len; + num -= len; + } + } + + //---------------------------------------------------------------------- + // ParserMemoryInput + + ParserMemoryInput::ParserMemoryInput(const void *ptr, unsigned len) + : data_ptr(ptr), data_len(len), offset(0) {} + + const void *ParserMemoryInput::GetPtr(unsigned &len) { + if (offset > data_len) { + throw std::length_error("Parser input buffer underflow."); + } + len = data_len - offset; + if (len > 0) { + return (const void*)((char*)data_ptr + offset); + } else { + return 0; + } + } + + void ParserMemoryInput::Release(unsigned len) { + offset += len; + } + + //---------------------------------------------------------------------- + // ParserFileInput + + ParserFileInput::ParserFileInput(FILE *f) + : ParserStreamInput(8192), file(f) + { + } + + unsigned ParserFileInput::Read(void *ptr, unsigned len) { + unsigned num_read = fread(ptr, 1, len, file); + int error = errno; + if (num_read) return num_read; + if (ferror(file)) { + std::ostringstream oss; + oss << "Error reading from file: "; + oss << strerror(error); + throw std::runtime_error(oss.str()); + } + return 0; + } + + //---------------------------------------------------------------------- + // ParserFilenameInput + + ParserFilenameInput::ParserFilenameInput(const char *filename, const char *mode) + : ParserFileInput(fopen(filename, mode)) + { + if (!file) { + std::ostringstream oss; + oss << "Unable to open " << filename; + throw std::runtime_error(oss.str()); + } + } + + ParserFilenameInput::~ParserFilenameInput() { + fclose(file); + } + + //---------------------------------------------------------------------- + // ParserStreambufInput + + ParserStreambufInput::ParserStreambufInput(std::streambuf *sb) + : ParserStreamInput(8192), streambuf(sb) + { + } + + unsigned ParserStreambufInput::Read(void *ptr, unsigned len) { + return streambuf->sgetn((char*)ptr, len); + } +} + diff --git a/src/hos_libvariant/src/src/Path.cc b/src/hos_libvariant/src/src/Path.cc new file mode 100644 index 00000000..715fe8be --- /dev/null +++ b/src/hos_libvariant/src/src/Path.cc @@ -0,0 +1,117 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include "../../src/include/Variant/Path.h" + +#include + +namespace libvariant { + + void ParsePath(Path &parsed_path, const std::string &path) { + const char *c = path.c_str(); + const char *e = c + path.length(); + std::string frag; + bool escape = false; + bool index = false; + bool key = false; + while (c != e) { + if (escape) { + frag.append(c, 1); + escape = false; + } else if (index) { + if (*c == ']') { + std::istringstream iss(frag); + unsigned long long i = 0; + if (!(iss >> i)) { + throw std::runtime_error("Error parsing Variant path: \"" + frag + "\" is not a number."); + } + parsed_path.push_back(i); + frag.clear(); + index = false; + } else { + frag.append(c, 1); + } + } else if (key) { + switch (*c) { + case '/': + parsed_path.push_back(frag); + frag.clear(); + break; + case '[': + parsed_path.push_back(frag); + frag.clear(); + key = false; + index = true; + break; + case '\\': + escape = true; + break; + default: + frag.append(c, 1); + break; + } + } else { + switch (*c) { + case '/': + frag.clear(); + key = true; + break; + case '[': + frag.clear(); + index = true; + break; + default: + frag.clear(); + key = true; + frag.append(c, 1); + break; + } + } + ++c; + } + if (!frag.empty()) { parsed_path.push_back(frag); } + } + + Path ParsePath(const std::string &path) { + Path parsed_path; + ParsePath(parsed_path, path); + return parsed_path; + } + + std::string PathString(const Path &path) { + if (path.empty()) { return "/"; } + std::ostringstream oss; + for (Path::const_iterator i(path.begin()), e(path.end()); i != e; ++i) { + if (i->IsString()) { + std::string fragment = i->AsString(); + oss << "/"; + for (unsigned i = 0; i < fragment.size(); ++i) { + switch (fragment[i]) { + case '/': + oss << "\\/"; + break; + case '[': + oss << "\\["; + break; + case ']': + oss << "\\]"; + break; + case '\\': + oss << "\\\\"; + break; + default: + oss << fragment[i]; + break; + } + } + } else if (i->IsNumber()) { + oss << "[" << i->AsUnsigned() << "]"; + } else { + throw BadPathError("Unknown path element type"); + } + } + return oss.str(); + } + +} diff --git a/src/hos_libvariant/src/src/Payload.cc b/src/hos_libvariant/src/src/Payload.cc new file mode 100644 index 00000000..8ed64df4 --- /dev/null +++ b/src/hos_libvariant/src/src/Payload.cc @@ -0,0 +1,347 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include "../../src/include/Variant/Payload.h" + +#include +#include +#include +#include "../../src/include/Variant/Path.h" + +#define PADDING_MOD 32 + +namespace libvariant { + + struct PayloadEmitState { + Emitter e; + Path::iterator len_end; + Path::iterator data_end; + uintmax_t payload_len; + }; + + void PayloadEmit( + const Variant &v, + Path::iterator len_i, + bool on_len_path, + Path::iterator data_i, + bool on_data_path, + PayloadEmitState &state) + { + if (on_len_path && len_i == state.len_end) { + state.e.Emit(state.payload_len); + return; + } + if (on_data_path && data_i == state.data_end) { + state.e.EmitNull(); + return; + } + + bool output_len = false; + unsigned index = 0; + unsigned length = 0; + + switch (v.GetType()) { + case Variant::NullType: + state.e.EmitNull(); + break; + case Variant::BoolType: + if (v.AsBool()) { + state.e.EmitTrue(); + } else { + state.e.EmitFalse(); + } + break; + case Variant::IntegerType: + state.e.Emit(v.AsInt()); + break; + case Variant::UnsignedType: + state.e.Emit(v.AsUnsigned()); + break; + case Variant::FloatType: + state.e.Emit(v.AsDouble()); + break; + case Variant::StringType: + state.e.Emit(v.AsString()); + break; + case Variant::ListType: + length = v.Size(); + if (on_len_path && length <= len_i->AsUnsigned()) { length = len_i->AsUnsigned() + 1; } + state.e.BeginList(length); + for (Variant::ConstListIterator i(v.ListBegin()), e(v.ListEnd()); i != e; ++i, ++index) { + bool on_len = on_len_path && index == len_i->AsUnsigned(); + bool on_data = on_data_path && index == data_i->AsUnsigned(); + PayloadEmit(*i, + (on_len ? len_i + 1 : len_i), on_len, + (on_data ? data_i + 1 : data_i), on_data, + state); + } + if (on_len_path && len_i->AsUnsigned() < index) { + while (len_i->AsUnsigned() < index) { + state.e.EmitNull(); + ++index; + } + if (len_i+1 != state.len_end) { + Variant tmp; + Path newpath(len_i+1, state.len_end); + tmp.SetPath(newpath, state.payload_len); + state.e << tmp; + } else { + state.e.Emit(state.payload_len); + } + } + state.e.EndList(); + break; + case Variant::MapType: + length = v.Size(); + if (on_len_path && !v.Contains(len_i->AsString())) { length++; } + if (on_data_path && v.Contains(data_i->AsString())) { length--; } + state.e.BeginMap(length); + for (Variant::ConstMapIterator i(v.MapBegin()), e(v.MapEnd()); i != e; ++i) { + bool on_len = on_len_path && i->first == len_i->AsString(); + if (on_len) { output_len = true; } + bool on_data = on_data_path && i->first == data_i->AsString(); + if ( !(on_data && data_i + 1 == state.data_end) ) { + state.e.Emit(i->first); + PayloadEmit(i->second, + (on_len ? len_i + 1 : len_i), on_len, + (on_data ? data_i + 1 : data_i), on_data, + state); + } + } + if (on_len_path && !output_len) { + state.e.Emit(len_i->AsString()); + if (len_i+1 != state.len_end) { + Variant tmp; + Path newpath(len_i+1, state.len_end); + tmp.SetPath(newpath, state.payload_len); + state.e << tmp; + } else { + state.e.Emit(state.payload_len); + } + } + state.e.EndMap(); + break; + case Variant::BlobType: + state.e << v.AsBlob(); + break; + default: + throw UnknownTypeError(v.GetType()); + } + } + + void SerializeWithPayload(shared_ptr out, Variant v, SerializeType type, Variant params) + { + if (!v.IsMap()) { + throw std::runtime_error("libvariant: Serializing with payload requires root element to be a map."); + } + + Path dpath; + Path lpath; + if (type == SERIALIZE_BUNDLEHDR) { + ParsePath(dpath, params.Get("data_path", VARIANT_BUNDLE_PAYLOAD_DATA_PATH).AsString()); + ParsePath(lpath, params.Get("length_path", VARIANT_BUNDLE_PAYLOAD_LENGTH_PATH).AsString()); + } else { + ParsePath(dpath, params.Get("data_path", VARIANT_PAYLOAD_DATA_PATH).AsString()); + ParsePath(lpath, params.Get("length_path", VARIANT_PAYLOAD_LENGTH_PATH).AsString()); + } + bool ignore_payload = params.Get("ignore_payload", false).AsBool(); + uintmax_t payload_length = 0; + + bool payload_exists = v.HasPath(dpath); + BlobPtr blob; + if (payload_exists) { + blob = v.GetPath(dpath).AsBlob(); + payload_length = blob->GetTotalLength(); + } else if (ignore_payload) { + payload_length = v.GetPath(lpath, 0).AsUnsigned(); + } + payload_length = params.Get("payload_length", payload_length).AsUnsigned(); + + + Emitter emitter = CreateEmitter(out, type, params); + PayloadEmitState state; + state.e = emitter; + state.len_end = lpath.end(); + state.data_end = dpath.end(); + state.payload_len = payload_length; + + emitter.BeginDocument(); + PayloadEmit(v, lpath.begin(), true, dpath.begin(), true, state); + emitter.EndDocument(); + emitter.Flush(); + + // plus 1 because we want a payload to be aligned when adding 1 null byte + unsigned num = PADDING_MOD - (out->NumBytesWritten() + 1) % PADDING_MOD; + std::vector buf(num, '\n'); + buf.push_back('\0'); + unsigned written = 0; + while (written < num) { + written += out->Write(&buf[written], buf.size() - written); + } + + if (payload_exists && !ignore_payload) { + unsigned num_slabs = blob->GetNumBuffers(); + for (unsigned slab = 0; slab < num_slabs; ++slab) { + unsigned to_write = blob->GetLength(slab); + char *ptr = (char*)blob->GetPtr(slab); + while (to_write > 0) { + unsigned num = out->Write(ptr, to_write); + ptr += num; + to_write -= num; + } + } + out->Flush(); + } + } + + class ProxyInput : public ParserInput { + public: + ProxyInput(shared_ptr i); + virtual ~ProxyInput(); + virtual const void *GetPtr(unsigned &len); + virtual void Release(unsigned len); + private: + shared_ptr base_input; + unsigned scanned_to; + }; + + ProxyInput::ProxyInput(shared_ptr i) + : base_input(i), scanned_to(0) + {} + + ProxyInput::~ProxyInput() {} + + const void *ProxyInput::GetPtr(unsigned &len) { + const void *retptr = base_input->GetPtr(len); + if (retptr) { + const char *ptr = (const char*)retptr; + if (ptr[scanned_to] != '\0') { + scanned_to += strnlen(&ptr[scanned_to], len-scanned_to); + + } + len = std::min(len, scanned_to); + } + return retptr; + } + + void ProxyInput::Release(unsigned len) { + scanned_to -= len; + base_input->Release(len); + } + + Variant DeserializeWithPayload(shared_ptr in, SerializeType type, Variant params, bool be_safe) + { + Path dpath; + Path lpath; + if (type == SERIALIZE_BUNDLEHDR) { + ParsePath(dpath, params.Get("data_path", VARIANT_BUNDLE_PAYLOAD_DATA_PATH).AsString()); + ParsePath(lpath, params.Get("length_path", VARIANT_BUNDLE_PAYLOAD_LENGTH_PATH).AsString()); + } else { + ParsePath(dpath, params.Get("data_path", VARIANT_PAYLOAD_DATA_PATH).AsString()); + ParsePath(lpath, params.Get("length_path", VARIANT_PAYLOAD_LENGTH_PATH).AsString()); + } + + shared_ptr input(new ProxyInput(in)); + Parser parser = CreateParser(input, type); + Variant ret = ParseVariant(parser); + + // Read any remaining bytes up to and including a terminating null if present. + bool loop = true; + while (loop) { + unsigned len = 1; + const char *ptr = (const char *)in->GetPtr(len); + if (len > 0) { + unsigned i; + for (i = 0; i < len && loop; ++i) { + if (ptr[i] == '\0') { + loop = false; + } + } + in->Release(i); + } else { loop = false; } + } + + uintmax_t payload_length = ret.GetPath(lpath, 0u).AsUnsigned(); + + if (payload_length > 0) { + // Note: make a copy when be_safe is true, otherwise just + // reference the buffer that the input returns. This is only + // a valid thing to do when the input is a memory buffer input + unsigned len = payload_length; + const void *ptr = in->GetPtr(len); + if (len < payload_length) { + throw std::runtime_error("libvariant: Error parsing payload, " + "unexpected EOF encountered when reading payload"); + } + BlobPtr payload; + if (be_safe) { + payload = Blob::CreateCopy(ptr, payload_length); + } else { + payload = Blob::CreateReferenced((void*)ptr, payload_length); + } + in->Release(payload_length); + ret.SetPath(dpath, payload); + } + return ret; + } + + std::string SerializeWithPayload(Variant v, SerializeType type, Variant params) { + std::ostringstream oss; + SerializeWithPayload(oss.rdbuf(), v, type, params); + return oss.str(); + } + + void SerializeWithPayload(const std::string &filename, Variant v, SerializeType type, + Variant params) { + shared_ptr o = CreateEmitterOutput(filename.c_str()); + SerializeWithPayload(o, v, type, params); + } + + void SerializeWithPayload(FILE *f, Variant v, SerializeType type, + Variant params) { + shared_ptr o = CreateEmitterOutput(f); + SerializeWithPayload(o, v, type, params); + } + + void SerializeWithPayload(std::streambuf *sb, Variant v, SerializeType type, + Variant params) { + shared_ptr o = CreateEmitterOutput(sb); + SerializeWithPayload(o, v, type, params); + } + + unsigned SerializeWithPayload(void *ptr, unsigned len, Variant v, SerializeType type, + Variant params) { + unsigned out_len = 0; + shared_ptr o = CreateEmitterOutput(ptr, len, &out_len); + SerializeWithPayload(o, v, type, params); + return out_len; + } + + Variant DeserializeWithPayload(const std::string &str, SerializeType type, Variant params) { + return DeserializeWithPayload(str.c_str(), str.length(), type, params); + } + + Variant DeserializeWithPayload(const void *ptr, unsigned len, SerializeType type, + Variant params, bool be_safe) + { + shared_ptr i = CreateParserInput(ptr, len); + return DeserializeWithPayload(i, type, params, be_safe); + } + + Variant DeserializeWithPayloadFile(const char *filename, SerializeType type, Variant params) { + shared_ptr i = CreateParserInputFile(filename); + return DeserializeWithPayload(i, type, params); + } + + Variant DeserializeWithPayloadFile(FILE *f, SerializeType type, Variant params) { + shared_ptr i = CreateParserInputFile(f); + return DeserializeWithPayload(i, type, params); + } + + Variant DeserializeWithPayloadFile(std::streambuf *sb, SerializeType type, Variant params) { + shared_ptr i = CreateParserInputFile(sb); + return DeserializeWithPayload(i, type, params); + } + +} diff --git a/src/hos_libvariant/src/src/Schema.cc b/src/hos_libvariant/src/src/Schema.cc new file mode 100644 index 00000000..8ff405cb --- /dev/null +++ b/src/hos_libvariant/src/src/Schema.cc @@ -0,0 +1,995 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + * + * This code is based on the public domain JSONv4 validator tv4. + * tv4 is available at http://geraintluff.github.com/tv4/ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FLOAT_TOLERANCE 100*std::numeric_limits::epsilon() +#define RECURSION_LIMIT 100 + +namespace libvariant { + + struct StopValidation : public std::exception { + virtual const char *what() const throw() { return "stop validation"; } + }; + + struct SchemaContext { + SchemaContext(const SchemaContext &o) + : data_path(o.data_path), + schema_path(o.schema_path), + depth(o.depth), + loader(o.loader) + {} + + SchemaContext(SchemaLoader *l) + : depth(0), + loader(l) + {} + + void AddError(const std::string &m) { AddError(ValidationError(m, data_path, schema_path)); } + void AddError(const std::string &m, const SchemaContext &o) { + ValidationError err(m, data_path, schema_path); + err.AddSubError(o.result); + AddError(err); + } + + void AddError(const ValidationError &err) { + result.AddError(err); + throw StopValidation(); + } + + void AddSchemaError(const std::string &m) { AddSchemaError(SchemaError(m, schema_path)); } + void AddSchemaError(const SchemaError &err) { result.AddSchemaError(err); } + + void IncrDepth() { + depth += 1; + if (depth > RECURSION_LIMIT) { + std::ostringstream oss; + oss << "SchemaValidate reached recursion limit."; + AddSchemaError(oss.str()); + throw StopValidation(); + } + } + + void DecrDepth() { + depth -= 1; + } + + Path data_path; + Path schema_path; + unsigned depth; + SchemaResult result; + SchemaLoader *loader; + }; + + struct AutoDataPath { + AutoDataPath(SchemaContext &c, const PathElement &p) : ctx(c) { ctx.data_path.push_back(p); } + ~AutoDataPath() { ctx.data_path.pop_back(); } + SchemaContext &ctx; + }; + + struct AutoSchemaPath { + AutoSchemaPath(SchemaContext &c, const PathElement &p) : ctx(c) { ctx.schema_path.push_back(p); } + ~AutoSchemaPath() { ctx.schema_path.pop_back(); } + SchemaContext &ctx; + }; + + struct AutoDepth { + AutoDepth(SchemaContext &c) : ctx(c) { ctx.IncrDepth(); } + ~AutoDepth() { ctx.DecrDepth(); } + SchemaContext &ctx; + }; + + void SchemaValidate(SchemaContext &ctx, Variant schema, Variant data); + + void ValidateNot(SchemaContext &ctx, Variant schema, Variant data) { + if (!schema.Contains("not")) { return; } + AutoSchemaPath spath(ctx, "not"); + SchemaContext notctx(ctx); + try { + SchemaValidate(notctx, schema["not"], data); + } catch (const StopValidation &) { + return; + } + if (notctx.result.Error()) { return; } + ctx.AddError("Data matches schema from \"not\""); + } + + void ValidateOneOf(SchemaContext &ctx, Variant schema, Variant data) { + if (!schema.Contains("oneOf")) { return; } + AutoSchemaPath spath(ctx, "oneOf"); + if (!schema["oneOf"].IsList()) { + ctx.AddSchemaError("\"oneOf\" must be a list of schemas"); + return; + } + ValidationError error("Data does not match any schemas from \"oneOf\"", + ctx.data_path, ctx.schema_path); + unsigned num_validates = 0; + unsigned index = 0; + unsigned validIndex = 0; + for (Variant::ListIterator i(schema["oneOf"].ListBegin()), e(schema["oneOf"].ListEnd()); + i != e; ++i, ++index) + { + SchemaContext subctx(ctx); + try { + AutoSchemaPath spath(subctx, index); + SchemaValidate(subctx, *i, data); + if (!subctx.result.Error()) { num_validates++; } + } catch (const StopValidation &) {} + if (subctx.result.Error()) { error.AddSubError(subctx.result); } + if (num_validates == 1) { + validIndex = index; + } else if (num_validates > 1) { + std::ostringstream oss; + oss << "Data is valid against more than one schema from \"oneOf\": indeces " + << validIndex << " and " << index; + ctx.AddError(oss.str()); + } + } + if (num_validates == 0) { + ctx.AddError(error); + } + } + + void ValidateAnyOf(SchemaContext &ctx, Variant schema, Variant data) { + if (!schema.Contains("anyOf")) { return; } + AutoSchemaPath spath(ctx, "anyOf"); + if (!schema["anyOf"].IsList()) { + ctx.AddSchemaError("\"anyOf\" must be a list of schemas"); + return; + } + ValidationError error("Data does not match any schema from \"anyOf\"", + ctx.data_path, ctx.schema_path); + unsigned index = 0; + for (Variant::ListIterator i(schema["anyOf"].ListBegin()), e(schema["anyOf"].ListEnd()); + i != e; ++i, ++index) + { + SchemaContext subctx(ctx); + try { + AutoSchemaPath spath(subctx, index); + SchemaValidate(subctx, *i, data); + if (!subctx.result.Error()) { return; } + } catch (const StopValidation &) {} + error.AddSubError(subctx.result); + } + ctx.AddError(error); + } + + void ValidateAllOf(SchemaContext &ctx, Variant schema, Variant data) { + if (!schema.Contains("allOf")) { return; } + AutoSchemaPath spath(ctx, "allOf"); + if (!schema["allOf"].IsList()) { + ctx.AddSchemaError("\"allOf\" must be a list of schemas"); + return; + } + unsigned index = 0; + for (Variant::ListIterator i(schema["allOf"].ListBegin()), e(schema["allOf"].ListEnd()); + i != e; ++i, ++index) + { + AutoSchemaPath spath(ctx, index); + SchemaValidate(ctx, *i, data); + } + } + + void ValidateCombinations(SchemaContext &ctx, Variant schema, Variant data) { + ValidateAllOf(ctx, schema, data); + ValidateAnyOf(ctx, schema, data); + ValidateOneOf(ctx, schema, data); + ValidateNot(ctx, schema, data); + } + + void ValidateObjectDependenciesHelper(SchemaContext &ctx, const std::string &dep, Variant data) { + if (!data.Contains(dep)) { + std::ostringstream oss; + oss << "Dependency failed - key must exist: " << dep; + ctx.AddError(oss.str()); + } + } + + void ValidateObjectDependencies(SchemaContext &ctx, Variant schema, Variant data) { + if (schema.Contains("dependencies")) { + Variant deps = schema["dependencies"]; + AutoSchemaPath spath(ctx, "dependencies"); + if (!deps.IsMap()) { + ctx.AddSchemaError("Schema key \"dependencies\" must be an object."); + return; + } + for (Variant::MapIterator i(deps.MapBegin()), e(deps.MapEnd()); i != e; ++i) { + if (data.Contains(i->first)) { + AutoSchemaPath spath(ctx, i->first); + if (i->second.IsString()) { + ValidateObjectDependenciesHelper(ctx, i->second.AsString(), data); + } else if (i->second.IsList()) { + for (unsigned j = 0; j < i->second.Size(); ++j) { + AutoSchemaPath spath(ctx, j); + ValidateObjectDependenciesHelper(ctx, i->second[j].AsString(), data); + } + } else if (i->second.IsMap()) { + SchemaValidate(ctx, i->second, data); + } else { + ctx.AddSchemaError("Values for dependencies must be either a key, a list of" + " keys, or a schema."); + } + } + } + } + } + + // Helper class for ValidateObjectProperties + class PatternProperty { + public: + PatternProperty(const std::string &patternkey, Variant schm) + : key(patternkey), schema(schm) + { + memset(&pattern, 0, sizeof(regex_t)); + int err; + if ((err = regcomp(&pattern, key.c_str(), REG_EXTENDED | REG_NOSUB))) { + std::vector buffer(8192); + regerror(err, &pattern, &buffer[0], buffer.size()); + std::ostringstream oss; + oss << "Failed to compile patternProperty regex \"" << key << "\" with error: " + << &buffer[0]; + throw std::runtime_error(oss.str()); + } + } + ~PatternProperty() { + regfree(&pattern); + } + bool Test(const std::string &k) { + return regexec(&pattern, k.c_str(), 0, 0, 0) == 0; + } + Variant GetSchema() { return schema; } + std::string GetKey() { return key; } + private: + // Can't tell if it is safe to copy regex_t structures... + PatternProperty(const PatternProperty &); + std::string key; + regex_t pattern; + Variant schema; + }; + + void ValidateObjectProperties(SchemaContext &ctx, Variant schema, Variant data) { + // Precompile because we always match against all of them for every key + std::vector< shared_ptr > patternProperties; + if (schema.Contains("patternProperties")) { + AutoSchemaPath spath(ctx, "patternProperties"); + if (schema["patternProperties"].IsMap()) { + for (Variant::MapIterator i(schema["patternProperties"].MapBegin()), + e(schema["patternProperties"].MapEnd()); i != e; ++i) + { + try { + patternProperties.push_back( + shared_ptr( + new PatternProperty(i->first, i->second) + ) + ); + } catch (const std::runtime_error &e) { + AutoSchemaPath spath(ctx, i->first); + ctx.AddSchemaError(e.what()); + } + } + } else { + ctx.AddSchemaError("\"patternProperties\" must be an object"); + } + } + Variant properties = schema.Get("properties", Variant::MapType); + if (!properties.IsMap()) { + ctx.AddSchemaError("\"properties\" must be an object"); + properties = Variant::MapType; + } + for (Variant::MapIterator i(data.MapBegin()), e(data.MapEnd()); + i != e; ++i) + { + bool matchFound = false; + AutoDataPath dpath(ctx, i->first); + // Validate against property declarations + if (properties.Contains(i->first)) { + AutoSchemaPath spath(ctx, "properties"); + AutoSchemaPath spath2(ctx, i->first); + matchFound = true; + SchemaValidate(ctx, properties[i->first], i->second); + } + // Validate against all matching patternProperties declarations + for (unsigned j = 0; j < patternProperties.size(); ++j) { + if (patternProperties[j]->Test(i->first)) { + AutoSchemaPath spath(ctx, "patternProperties"); + AutoSchemaPath spath2(ctx, patternProperties[j]->GetKey()); + matchFound = true; + SchemaValidate(ctx, patternProperties[j]->GetSchema(), i->second); + } + } + // If no match was found for either of the previous cases validate + // against additionalProperties + if (!matchFound && schema.Contains("additionalProperties")) { + Variant additionalProps = schema["additionalProperties"]; + AutoSchemaPath spath(ctx, "additionalProperties"); + if (additionalProps.IsBool()) { + if (!additionalProps.AsBool()) { + ctx.AddError("Additional properties not allowed."); + } + } else { + SchemaValidate(ctx, additionalProps, i->second); + } + } + } + } + + void ValidateObjectRequiredProperties(SchemaContext &ctx, Variant schema, Variant data) { + if (schema.Contains("required")) { + unsigned index = 0; + Variant required = schema["required"]; + AutoSchemaPath spath(ctx, "required"); + if (!required.IsList()) { + ctx.AddSchemaError("\"required\" must be a list of required keys"); + return; + } + for (Variant::ListIterator i(required.ListBegin()), e(required.ListEnd()); + i != e; ++i, ++index) + { + AutoSchemaPath spath(ctx, index); + if (i->IsString()) { + std::string key = i->AsString(); + if (!data.Contains(key)) { + std::ostringstream oss; + oss << "Missing required property: " << key; + ctx.AddError(oss.str()); + } + } else { + ctx.AddSchemaError("Elements of the \"required\" list must be strings"); + } + } + } + // TODO: Add v3 compatibility by checking required keys in properties? + } + + void ValidateObjectMinMaxProperties(SchemaContext &ctx, Variant schema, Variant data) { + if (schema.Contains("minProperties")) { + AutoSchemaPath spath(ctx, "minProperties"); + if (schema["minProperties"].IsNumber()) { + uintmax_t minprops = schema["minProperties"].AsUnsigned(); + if (data.Size() < minprops) { + std::ostringstream oss; + oss << "Too few properties defined (" << data.Size() << "), minimum " << minprops; + ctx.AddError(oss.str()); + } + } else { + ctx.AddSchemaError("\"minProperties\" must be a number"); + } + } + if (schema.Contains("maxProperties")) { + AutoSchemaPath spath(ctx, "maxProperties"); + if (schema["maxProperties"].IsNumber()) { + uintmax_t maxprops = schema["maxProperties"].AsUnsigned(); + if (data.Size() > maxprops) { + std::ostringstream oss; + oss << "Too many properties defined (" << data.Size() << "), maximum " << maxprops; + ctx.AddError(oss.str()); + } + } else { + ctx.AddSchemaError("\"minProperties\" must be a number"); + } + } + } + + void ValidateObject(SchemaContext &ctx, Variant schema, Variant data) { + if (!data.IsMap() || data.IsNull()) { return; } + ValidateObjectMinMaxProperties(ctx, schema, data); + ValidateObjectRequiredProperties(ctx, schema, data); + ValidateObjectProperties(ctx, schema, data); + ValidateObjectDependencies(ctx, schema, data); + } + + void ValidateArrayItems(SchemaContext &ctx, Variant schema, Variant data) { + if (!schema.Contains("items")) { return; } + if (!data.IsList()) { return; } + if (schema["items"].IsList()) { + Variant items = schema["items"]; + unsigned datalength = data.Size(); + unsigned itemlength = items.Size(); + for (unsigned i(0); i < datalength; ++i) { + AutoDataPath dpath(ctx, i); + if (i < itemlength) { + AutoSchemaPath spath(ctx, "items"); + AutoSchemaPath spath2(ctx, i); + SchemaValidate(ctx, items[i], data[i]); + } else if (schema.Contains("additionalItems")) { + AutoSchemaPath spath(ctx, "additionalItems"); + if (schema["additionalItems"].IsBool()) { + if (!schema["additionalItems"].AsBool()) { + ctx.AddError("Additional items not allowed"); + } + } else { + SchemaValidate(ctx, schema["additionalItems"], data[i]); + } + } + } + } else { + unsigned datalength = data.Size(); + AutoSchemaPath spath(ctx, "items"); + for (unsigned i(0); i < datalength; ++i) { + AutoDataPath dpath(ctx, i); + SchemaValidate(ctx, schema["items"], data[i]); + } + } + } + + void ValidateArrayUniqueItems(SchemaContext &ctx, Variant schema, Variant data) { + if (!schema.Contains("uniqueItems")) { return; } + AutoSchemaPath spath(ctx, "uniqueItems"); + if (!schema["uniqueItems"].IsBool()) { + ctx.AddSchemaError("\"uniqueItems\" must be a boolean"); + return; + } + if (!schema["uniqueItems"].AsBool()) { return; } + unsigned length = data.Size(); + for (unsigned i(0); i < length; ++i) { + for (unsigned j(i+1); j < length; ++j) { + if (data[i].Comparable(data[j]) && data[i] == data[j]) { + std::ostringstream oss; + oss << "Array items are not unique (indices " << i << " and " << j << ")"; + ctx.AddError(oss.str()); + } + } + } + } + + void ValidateArrayLength(SchemaContext &ctx, Variant schema, Variant data) { + if (schema.Contains("minItems")) { + AutoSchemaPath spath(ctx, "minItems"); + if (schema["minItems"].IsNumber()) { + uintmax_t minItems = schema["minItems"].AsUnsigned(); + if (data.Size() < minItems) { + std::ostringstream oss; + oss << "Array is to short (" << data.Size() << "), minimum " << minItems; + ctx.AddError(oss.str()); + } + } else { + ctx.AddSchemaError("\"minItems\" must be a number"); + } + } + if (schema.Contains("maxItems")) { + AutoSchemaPath spath(ctx, "maxItems"); + if (schema["maxItems"].IsNumber()) { + uintmax_t maxItems = schema["maxItems"].AsUnsigned(); + if (data.Size() > maxItems) { + std::ostringstream oss; + oss << "Array is to long (" << data.Size() << "), maximum " << maxItems; + ctx.AddError(oss.str()); + } + } else { + ctx.AddSchemaError("\"maxItems\" must be a number"); + } + } + } + + void ValidateArray(SchemaContext &ctx, Variant schema, Variant data) { + if (!data.IsList()) { return; } + ValidateArrayLength(ctx, schema, data); + ValidateArrayUniqueItems(ctx, schema, data); + ValidateArrayItems(ctx, schema, data); + } + + void ValidateStringFormat(SchemaContext &ctx, Variant schema, Variant data) { + if (!schema.Contains("format")) { return; } + AutoSchemaPath spath(ctx, "format"); + if (!schema["format"].IsString()) { return; } + std::string format = schema["format"].AsString(); + regex_t pattern; + memset(&pattern, 0, sizeof(regex_t)); + std::string patternstr; + int err; + if (format == "regex") { + // From V3 spec + err = regcomp(&pattern, data.AsString().c_str(), REG_EXTENDED | REG_NOSUB); + if (err) { + std::ostringstream oss; + oss << "String \"" << data.AsString() << "\" not a valid regular expression."; + ctx.AddError(oss.str()); + } + regfree(&pattern); + } else { + if (format == "date-time") { + // From V4 spec + // RFC 3339, section 5.6 + patternstr = "^[0-9][0-9][0-9][0-9](-[0-1][0-9](-[0-3][0-9]" + "(T[0-9][0-9](:[0-9][0-9](:[0-9][0-9])?)?)?)?)?Z?$"; + } else if (format == "date") { + // From V3 spec: should be format of YYYY-MM-DD + patternstr = "^[0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]$"; + } else if (format == "time") { + // From V3 spec: should be format of hh:mm:ss + patternstr = "^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]$"; + } else if (format == "email") { + // RFC 5322, section 3.4.1 + // TODO + } else if (format == "hostname") { + // RFC 1034, section 3.1 + // TODO + } else if (format == "ipv4") { + // RFC 2676, section 3.2 + // TODO + } else if (format == "ipv6") { + // RFC 2373, section 2.2 + // TODO + } else if (format == "uri") { + // RFC 3986 + // TODO + } + + if (!patternstr.empty()) { + if ((err = regcomp(&pattern, patternstr.c_str(), REG_EXTENDED | REG_NOSUB))) { + std::vector buffer(8192); + regerror(err, &pattern, &buffer[0], buffer.size()); + std::ostringstream oss; + oss << "Failed to compile format regex \"" << patternstr << "\" with error: " + << &buffer[0]; + ctx.AddSchemaError(oss.str()); + return; + } + try { + if (regexec(&pattern, data.AsString().c_str(), 0, 0, 0)) { + ctx.AddError("String does not match format " + format); + } + } catch (...) { + regfree(&pattern); + throw; + } + regfree(&pattern); + } + } + } + + void ValidateStringPattern(SchemaContext &ctx, Variant schema, Variant data) { + if (!schema.Contains("pattern")) { return; } + AutoSchemaPath spath(ctx, "pattern"); + if (!schema["pattern"].IsString()) { + ctx.AddSchemaError("\"pattern\" must be a string"); + return; + } + regex_t pattern; + memset(&pattern, 0, sizeof(regex_t)); + std::string patternstr = schema["pattern"].AsString(); + int err; + if ((err = regcomp(&pattern, patternstr.c_str(), REG_EXTENDED | REG_NOSUB))) { + std::vector buffer(8192); + regerror(err, &pattern, &buffer[0], buffer.size()); + std::ostringstream oss; + oss << "Failed to compile pattern regex \"" << patternstr << "\" with error: " + << &buffer[0]; + ctx.AddSchemaError(oss.str()); + return; + } + try { + if (regexec(&pattern, data.AsString().c_str(), 0, 0, 0)) { + std::ostringstream oss; + oss << "String does not match pattern \"" + << patternstr << "\""; + ctx.AddError(oss.str()); + } + } catch (...) { + regfree(&pattern); + throw; + } + regfree(&pattern); + } + + void ValidateStringLength(SchemaContext &ctx, Variant schema, Variant data) { + if (schema.Contains("minLength")) { + AutoSchemaPath spath(ctx, "minLength"); + if (schema["minLength"].IsNumber()) { + // TODO: Get encoded length rather than byte length? + if (data.Size() < schema["minLength"].AsUnsigned()) { + std::ostringstream oss; + oss << "String is too short (" << data.Size() << " chars), minimum " + << schema["minLength"].AsUnsigned(); + ctx.AddError(oss.str()); + } + } else { + ctx.AddSchemaError("\"minLength\" must be a number"); + } + } + if (schema.Contains("maxLength")) { + AutoSchemaPath spath(ctx, "maxLength"); + if (schema["maxLength"].IsNumber()) { + // TODO: Get encoded length rather than byte length? + if (data.Size() > schema["maxLength"].AsUnsigned()) { + std::ostringstream oss; + oss << "String is too long (" << data.Size() << " chars), maximum " + << schema["maxLength"].AsUnsigned(); + ctx.AddError(oss.str()); + } + } else { + ctx.AddSchemaError("\"maxLength\" must be a number"); + } + } + } + + void ValidateString(SchemaContext &ctx, Variant schema, Variant data) { + if (!data.IsString()) { return; } + ValidateStringLength(ctx, schema, data); + ValidateStringPattern(ctx, schema, data); + ValidateStringFormat(ctx, schema, data); + } + + void ValidateMinMax(SchemaContext &ctx, Variant schema, Variant data) { + if (schema.Contains("minimum")) { + if (schema["minimum"].IsNumber()) { + if (data < schema["minimum"]) { + AutoSchemaPath spath(ctx, "minimum"); + std::ostringstream oss; + oss << "Value " << data.AsString() + << " is less than minimum " << schema["minimum"].AsString(); + ctx.AddError(oss.str()); + } + if (schema.Contains("exclusiveMinimum") && schema["exclusiveMinimum"].AsBool() + && data == schema["minimum"]) { + AutoSchemaPath spath(ctx, "exclusiveMinimum"); + std::ostringstream oss; + oss << "Value " << data.AsString() << " is equal to exclusive minimum " + << schema["minimum"].AsString(); + ctx.AddError(oss.str()); + } + } else { + AutoSchemaPath spath(ctx, "minimum"); + ctx.AddSchemaError("\"minimum\" must be a number"); + } + } + if (schema.Contains("maximum")) { + if (schema["maximum"].IsNumber()) { + if (data > schema["maximum"]) { + AutoSchemaPath spath(ctx, "maximum"); + std::ostringstream oss; + oss << "Value " << data.AsString() + << " is greater than maximum " << schema["maximum"].AsString(); + ctx.AddError(oss.str()); + } + if (schema.Contains("exclusiveMaximum") && schema["exclusiveMaximum"].AsBool() + && data == schema["maximum"]) { + AutoSchemaPath spath(ctx, "exclusiveMaximum"); + std::ostringstream oss; + oss << "Value " << data.AsString() + << " is equal to exclusive maximum " << schema["maximum"].AsString(); + ctx.AddError(oss.str()); + } + } else { + AutoSchemaPath spath(ctx, "maximum"); + ctx.AddSchemaError("\"maximum\" must be a number"); + } + } + } + + void ValidateMultipleOf(SchemaContext &ctx, Variant schema, Variant data) { + std::string multkey; + if (schema.Contains("multipleOf")) { + multkey = "multipleOf"; + } else if (schema.Contains("divisibleBy")) { + multkey = "divisibleBy"; + } else { + return; + } + AutoSchemaPath spath(ctx, multkey); + Variant multipleof = schema[multkey]; + if (!multipleof.IsNumber() || multipleof < 0) { + std::ostringstream oss; + oss << "\"" << multkey << "\" must be a positive number"; + ctx.AddSchemaError(oss.str()); + return; + } + Variant mod = data % multipleof; + if (data.IsFloat() || multipleof.IsFloat()) { + // We have an issue here of the fact that many numeric values in base 10 are + // not exactly represented in binary floating point. + // So, we need to check if it is within epsilon of 0 + long double m = mod.AsLongDouble(); + long double divisor = multipleof.AsLongDouble(); + long double tolerance = FLOAT_TOLERANCE; + + if (m > tolerance && std::abs(m - divisor) > tolerance) { + std::ostringstream oss; + oss << "Value " << data.AsString() << " is not a multiple of " << multipleof.AsString(); + //oss << "\nmodulus: " << m << "\n|modulus-divisor|: " << std::abs(m - divisor) + // << "\ntolerance " << tolerance; + ctx.AddError(oss.str()); + } + } else if (mod != 0) { + std::ostringstream oss; + oss << "Value " << data.AsString() << " is not a multiple of " << multipleof.AsString(); + ctx.AddError(oss.str()); + } + } + + void ValidateNumeric(SchemaContext &ctx, Variant schema, Variant data) { + if (!data.IsNumber()) { return; } + ValidateMultipleOf(ctx, schema, data); + ValidateMinMax(ctx, schema, data); + } + + void ValidateEnum(SchemaContext &ctx, Variant schema, Variant data) { + if (!schema.Contains("enum")) { return; } + Variant enm = schema["enum"]; + AutoSchemaPath spath(ctx, "enum"); + if (!enm.IsList()) { + ctx.AddSchemaError("\"enum\" must be an array"); + return; + } + for (Variant::ListIterator i(enm.ListBegin()), e(enm.ListEnd()); i!=e; ++i) { + if (i->Comparable(data) && *i == data) { return; } + } + std::ostringstream oss; + oss << "No enum match for: "; + SerializeJSON(oss.rdbuf(), data); + ctx.AddError(oss.str()); + } + + void ValidateType(SchemaContext &ctx, Variant schema, Variant data) { + if (!schema.Contains("type")) { return; } + AutoSchemaPath spath(ctx, "type"); + std::vector allowed_types; + if (schema["type"].IsList()) { + allowed_types = schema["type"].AsList(); + } else { + // TODO: v3 compatibility + // if (schema["type"] == "any") { return; } + allowed_types.push_back(schema["type"]); + } + std::ostringstream oss; + unsigned index = 0; + for (Variant::ListIterator i(allowed_types.begin()), e(allowed_types.end()); + i != e; ++i, ++index) { + if (*i == "array") { + if (data.IsList()) { return; } + } else if (*i == "boolean") { + if (data.IsBool()) { return; } + } else if (*i == "integer") { + if (data.IsInt() || data.IsUnsigned()) { return; } + if (data.IsFloat() && data % 1 == 0) { return; } + } else if (*i == "null") { + if (data.IsNull()) { return; } + } else if (*i == "number") { + if (data.IsNumber()) { return; } + } else if (*i == "object") { + if (data.IsMap()) { return; } + } else if (*i == "string") { + if (data.IsString()) { return; } + } else { + AutoSchemaPath spath(ctx, index); + std::ostringstream oss; + oss << "Invalid schema type: \"" << i->AsString() << "\""; + ctx.AddSchemaError(oss.str()); + } + } + oss << "invalid data type: \"" << data.GetType() << "\" expected"; + if (allowed_types.size() == 1) { + oss << ": \"" << allowed_types.front().AsString() << "\""; + } else { + oss << " one of: ["; + for (Variant::ListIterator i(allowed_types.begin()), e(allowed_types.end()); + i != e; ++i) { + oss << "\"" << i->AsString() << "\""; + if (i+1 != e) { oss << ", "; } + } + oss << "]"; + } + ctx.AddError(oss.str()); + } + + void ValidateBasic(SchemaContext &ctx, Variant schema, Variant data) { + ValidateType(ctx, schema, data); + ValidateEnum(ctx, schema, data); + } + + void SchemaValidate(SchemaContext &ctx, Variant schema, Variant data) { + AutoDepth depth(ctx); + // Empty schema always validates + if (!schema.IsMap()) { return; } + if (schema.Contains("$ref") && schema["$ref"].IsString()) { + SchemaValidate(ctx, ctx.loader->GetSchema(schema["$ref"].AsString()), data); + } + ValidateBasic(ctx, schema, data); + ValidateNumeric(ctx, schema, data); + ValidateString(ctx, schema, data); + ValidateArray(ctx, schema, data); + ValidateObject(ctx, schema, data); + ValidateCombinations(ctx, schema, data); + } + + SchemaResult SchemaValidate(Variant schema, Variant data, SchemaLoader *loader) + { + SchemaLoader lloader(loader); + if (schema.IsNull() && data.IsMap() && data.Contains("$schema")) { + schema["$ref"] = data["$schema"]; + } + if (schema.IsString()) { + schema = lloader.GetSchema(schema.AsString()); + } + lloader.AddSchema("", schema); + SchemaContext ctx(&lloader); + try { + SchemaValidate(ctx, schema, data); + } catch (const StopValidation &) {} + return ctx.result; + } + + void AddSchemaDefaultsImpl(Variant schema, VariantRef data, SchemaLoader *loader); + + void AddSchemaListDefaultsImpl(VariantRef slist, VariantRef data, SchemaLoader *loader) { + if (slist.Exists() && slist.IsList()) { + for (Variant::ListIterator i(slist.ListBegin()), e(slist.ListEnd()); i != e; ++i) { + AddSchemaDefaultsImpl(*i, data, loader); + } + } + } + + void AddSchemaDefaultsImpl(Variant schema, VariantRef data, SchemaLoader *loader) { + if (!schema.IsMap()) { return; } + if (schema.Contains("$ref") && schema["$ref"].IsString()) { + AddSchemaDefaultsImpl(loader->GetSchema(schema["$ref"].AsString()), data, loader); + } + if (schema.Contains("default") && (!data.Exists() || data.IsNull())) { + data = schema["default"].Copy(); + return; + } + if (schema.Contains("properties") && (!data.Exists() || data.IsMap())) { + for (Variant::MapIterator i(schema["properties"].MapBegin()), e(schema["properties"].MapEnd()); + i != e; ++i) + { + AddSchemaDefaultsImpl(i->second, data.At(i->first), loader); + } + } + if (schema.Contains("items") && (!data.Exists() || data.IsList())) { + if (schema["items"].IsList()) { + for (unsigned i = 0; i < schema["items"].Size(); ++i) + { + AddSchemaDefaultsImpl(schema["items"][i], data[i], loader); + } + } else { + AddSchemaDefaultsImpl(schema["items"], data[0], loader); + } + } + AddSchemaListDefaultsImpl(schema["allOf"], data, loader); + AddSchemaListDefaultsImpl(schema["oneOf"], data, loader); + AddSchemaListDefaultsImpl(schema["anyOf"], data, loader); + } + + void AddSchemaDefaults(Variant schema, VariantRef data, SchemaLoader *loader) { + SchemaLoader lloader(loader); + if (schema.IsNull() && data.IsMap() && data.Contains("$schema")) { + schema["$ref"] = data["$schema"]; + } + if (schema.IsString()) { + schema = lloader.GetSchema(schema.AsString()); + } + lloader.AddSchema("", schema); + AddSchemaDefaultsImpl(schema, data, &lloader); + } + + void InsertIndent(std::ostream &os, unsigned indent) { + for (unsigned i = 0; i < indent; ++i) { os << "\t"; } + } + + ValidationError::ValidationError(const std::string &m, const Path &dpath, + const Path &spath) + : message(m), + data_path(dpath), + schema_path(spath) + {} + + void ValidationError::AddSubError(const SchemaResult &err) { + sub_errors.push_back(err); + } + + std::string ValidationError::GetDataPathStr() const { + return PathString(data_path); + } + + std::string ValidationError::GetSchemaPathStr() const { + return PathString(schema_path); + } + + std::string ValidationError::PrettyPrintMessage() const { + std::ostringstream oss; + PrettyPrintMessage(oss); + return oss.str(); + } + + void ValidationError::PrettyPrintMessage(std::ostream &os, unsigned indent) const { + InsertIndent(os, indent); + os << "validation error: " << message << "\n"; + InsertIndent(os, indent); + os << "data path: " << GetDataPathStr() << "\n"; + InsertIndent(os, indent); + os << "schema path: " << GetSchemaPathStr() << "\n"; + if (!sub_errors.empty()) { + InsertIndent(os, indent); + os << "sub errors:\n"; + for (unsigned i = 0; i < sub_errors.size(); ++i) { + sub_errors[i].PrettyPrintMessage(os, indent+1); + } + } + } + + SchemaError::SchemaError(const std::string &m, const Path &spath) + : message(m), + schema_path(spath) + { + } + + std::string SchemaError::GetSchemaPathStr() const { + return PathString(schema_path); + } + + std::string SchemaError::PrettyPrintMessage() const { + std::ostringstream oss; + PrettyPrintMessage(oss); + return oss.str(); + } + + void SchemaError::PrettyPrintMessage(std::ostream &os, unsigned indent) const { + InsertIndent(os, indent); + os << "schema error: " << message << "\n"; + InsertIndent(os, indent); + os << "schema path: " << GetSchemaPathStr() << "\n"; + } + + SchemaResult::SchemaResult() + { + } + + void SchemaResult::AddError(const ValidationError &err) { + errors.push_back(err); + } + + void SchemaResult::AddSchemaError(const SchemaError &err) { + schema_errors.push_back(err); + } + + std::string SchemaResult::PrettyPrintMessage() const { + std::ostringstream oss; + PrettyPrintMessage(oss); + return oss.str(); + } + + void SchemaResult::PrettyPrintMessage(std::ostream &os, unsigned indent) const { + if (!errors.empty()) { + for (unsigned i = 0; i < errors.size(); ++i) { + errors[i].PrettyPrintMessage(os, indent); + } + } + if (!schema_errors.empty()) { + for (unsigned i = 0; i < schema_errors.size(); ++i) { + schema_errors[i].PrettyPrintMessage(os, indent); + } + } + } + +} diff --git a/src/hos_libvariant/src/src/SchemaLoader.cc b/src/hos_libvariant/src/src/SchemaLoader.cc new file mode 100644 index 00000000..f6884271 --- /dev/null +++ b/src/hos_libvariant/src/src/SchemaLoader.cc @@ -0,0 +1,570 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ENABLE_CURL +#include +#endif + +#if 0 +#include +#define DBPRINT(a) std::cerr << a +#else +#define DBPRINT(a) +#endif + +namespace libvariant { + + extern const char JSON_SCHEMA_V4_SCHEMA[]; + class SchemaStaticData { + public: + SchemaStaticData() { + JSON_SCHEMA_SCHEMA = DeserializeJSON(JSON_SCHEMA_V4_SCHEMA); + SCHEMA_URI = SchemaLoader::ResolveURI(JSON_SCHEMA_SCHEMA["id"].AsString(), ""); + SchemaLoader::NormSchema(JSON_SCHEMA_SCHEMA, SCHEMA_URI); + } + Variant JSON_SCHEMA_SCHEMA; + std::string SCHEMA_URI; + }; + shared_ptr schema_static_data; + + SchemaStaticData *GetSchemaStaticData() { + // This is actually a race condition when multithreading is used, but + // every thread will write the same data, so this is "OK" as long as + // the CPU cache coherency is reasonable. + if (!schema_static_data.get()) { + shared_ptr new_schema_static_data; + new_schema_static_data.reset(new SchemaStaticData); + schema_static_data = new_schema_static_data; + } + return schema_static_data.get(); + } + + SchemaLoader::SchemaLoader() + : missingHandler(0), + missingctx(0), + base(0) + { + SchemaStaticData *d = GetSchemaStaticData(); + schemas[d->SCHEMA_URI] = d->JSON_SCHEMA_SCHEMA; + } + + SchemaLoader::SchemaLoader(SchemaLoader *b) + : missingHandler(0), + missingctx(0), + base(b) + { + DBPRINT("schema loader\n"); + SchemaStaticData *d = GetSchemaStaticData(); + schemas[d->SCHEMA_URI] = d->JSON_SCHEMA_SCHEMA; + } + + SchemaLoader::~SchemaLoader() {} + + std::string UnescapeURI(const std::string &uri) { + std::string ret; + const char *c = uri.c_str(); + const char *e = c + uri.size(); + while (c != e) { + switch (*c) { + case '%': + if (c + 1 == e || c + 2 == e) { + ret.append(c); + c = e; + } else { + char hex[3] = { *(c+1), *(c+2), 0 }; + char *endp = 0; + long hexv = strtol(hex, &endp, 16); + if (*endp != 0) { + ret.append(c, 3); + } else { + ret.append(1, (char)hexv); + } + c += 3; + } + break; + default: + ret.append(c, 1); + ++c; + break; + } + } + return ret; + } + + Variant SchemaLoader::GetSchema(const std::string &uri) { + Variant::MapIterator iter = schemas.find(uri); + if (iter != schemas.end()) { + return iter->second; + } + std::string baseuri = ResolveURI(uri, ""); + std::string fragment; + std::string::size_type hashIndex = uri.find("#"); + if (hashIndex != std::string::npos) { + fragment = uri.substr(hashIndex + 1); + baseuri = uri.substr(0, hashIndex); + } + iter = schemas.find(baseuri); + if (iter == schemas.end()) { + if (base) { + return base->GetSchema(uri); + } + LoaderError err; + if (!HandleMissing(baseuri, err)) { + throw std::runtime_error(err.GetErrorMessage()); + } + iter = schemas.find(baseuri); + } + if (iter == schemas.end()) { + return Variant::NullType; + } + + Variant schema = iter->second; + return JSONPointerLookup(UnescapeURI(fragment), schema); + } + + std::map SchemaLoader::AddSchema(const std::string &uri, Variant schema) { + std::string luri = ResolveURI(uri, ""); + std::map m; + m[luri] = schema; + NormSchema(schema, luri); + SearchForTrustedSchemas(m, schema, luri); + schemas.insert(m.begin(), m.end()); + return m; + } + + void SchemaLoader::ForgetSchema(const std::string &uri) { + schemas.erase(uri); + } + + bool SchemaLoader::HandleMissing(const std::string &uri, LoaderError &error) { + if (missingHandler) { + return missingHandler(this, uri, error, missingctx); + } else if (base) { + return base->HandleMissing(uri, error); + } else { + error.AddError(uri, "SchemaLoader missing schema"); + return false; + } + } + + void SchemaLoader::SetMissingHandler(MissingHandlerType f, void *ctx) { + missingHandler = f; + missingctx = ctx; + } + + // The following two functions are adapted from two functions in tv4 with the following comment: + // parseURI() and resolveUrl() are from https://gist.github.com/1088850 + // - released as public domain by author ("Yaffle") - see comments on gist + + bool SchemaLoader::ParseURI(URIInfo &info, const std::string &uri) { + enum { + HREF=0, PROTOCOL, AUTHORITY, USERHOST, HOST, + HOSTNAME, PORT, PATHNAME, SEARCH, HASH, MATCHLEN + }; + static const struct RegexHelper { + RegexHelper() { + memset(®ex, 0, sizeof(regex_t)); + int ret = regcomp(®ex, +"^[[:space:]]*([^:\\/?#]+:)?" // PROTOCOL +"(//([^:@]*(:[^:@]*)?@)?([^:/?#]*)(:[0-9]*)?)?" // (//((user(:host)@)(hostname)(:port))) +"([^?#]*)" // PATHNAME +"(\\?[^#]*)?" // SEARCH +"(#[^[:space:]]*)?[[:space:]]*$" // HASH + , REG_EXTENDED); + if (ret) { + std::vector buffer(8192); + regerror(ret, ®ex, &buffer[0], buffer.size()); + std::ostringstream oss; + oss << "libvariant library initialization failure: Failed to initialize schema uri handling regex with error: " + << &buffer[0]; + fputs(oss.str().c_str(), stderr); + throw std::runtime_error(oss.str()); + } + } + ~RegexHelper() { regfree(®ex); } + regex_t regex; + } regex; + regmatch_t match[MATCHLEN]; + DBPRINT(std::endl << "Matching against \"" << uri << "\"\n"); + int err = regexec(®ex.regex, uri.c_str(), MATCHLEN, &match[0], 0); + if (err != 0) { + DBPRINT("Match failed\n"); + return false; + } + for (int i = 0; i < MATCHLEN; ++i) { + int so, eo, len; + if (match[i].rm_so >= 0) { + so = match[i].rm_so; + eo = match[i].rm_eo; + len = eo - so; + DBPRINT("Match "); + switch (i) { + case HREF: + info.href = uri.substr(so, len); + DBPRINT("href\t"); + break; + case PROTOCOL: + info.protocol = uri.substr(so, len); + DBPRINT("protocol\t"); + break; + case AUTHORITY: + info.authority = uri.substr(so, len); + DBPRINT("authority\t"); + break; + case PATHNAME: + info.pathname = uri.substr(so, len); + DBPRINT("pathname\t"); + break; + case SEARCH: + info.search = uri.substr(so, len); + DBPRINT("search\t"); + break; + case HASH: + info.hash = uri.substr(so, len); + DBPRINT("hash\t"); + break; + default: + break; + } + DBPRINT(i << " matched \"" << uri.substr(so, len) << "\"" << std::endl); + } else { + DBPRINT(i << " did not match" << std::endl); + } + } + return true; + } + + std::string RemoveDotSegments(const std::string &input) { + //^(\.\.?(\/|$))+/, '' -- ignore leading ../ removed + //\/(\.(\/|$))+/g, '/' -- remove /./ + //\/\.\.$/, '/../' -- normalize last /.. to /../ + //\/?[^\/]*/g, function (p) { + std::vector output; + std::string::size_type i = 0; + std::string::size_type next = input.find("/"); + bool firstslash = false; + DBPRINT("Processing \"" << input << "\"\n"); + unsigned lastdot = 0; + if (next == 0) { + // First was a slash, make sure to add it back + firstslash = true; + DBPRINT("firstslash\n"); + } else if (next >= input.size()) { + // No slashes + DBPRINT("no slashes\n"); + if (input == ".") { return ""; } + else { return input; } + //} else if (next + 1 == input.size()) { + // only slash at end + //if (input == "../" || input == "./") { return ""; } + //else { return input; } + } else { + std::string sub = input.substr(i, next - i); + if (sub != ".") { + output.push_back(sub); + if (sub == "..") { lastdot = output.size(); } + DBPRINT("leading: \"" << output.back() << "\"\n"); + } + } + while (next < input.size()) { + i = next; + next = input.find("/", i + 1); + // Get the string between the slashes + std::string sub = input.substr(i + 1, next - 1 - i); + if (sub == ".") { + lastdot = output.size(); + } else if (sub == "..") { + DBPRINT("pop\n"); + if (!output.empty()) { output.pop_back(); } + else { output.push_back(sub); } + lastdot = output.size(); + } else { + output.push_back(sub); + DBPRINT("push back: \"" << output.back() << "\"\n"); + } + } + std::ostringstream oss; + for (std::vector::iterator iv(output.begin()), ie(output.end()); iv != ie; ++iv) { + if (firstslash) { + oss << "/"; + } else { + firstslash = true; + } + oss << *iv; + } + if (output.empty() && firstslash) { oss << "/"; } + if (lastdot > 0 && lastdot == output.size()) { oss << "/"; } + DBPRINT("ret: \"" << oss.str() << "\""); + return oss.str(); + } + + std::string SchemaLoader::ResolveURI(const std::string &base, const std::string &href) { + URIInfo b, h; + bool base_parsed = ParseURI(b, base); + bool href_parsed = ParseURI(h, href); + std::string ret = ""; + if (!base_parsed || !href_parsed) { + return ret; + } + + ret += (h.protocol != "" ? h.protocol : b.protocol); + ret += (h.protocol != "" || h.authority != "" ? h.authority : b.authority); + if (h.protocol != "" || h.authority != "" || h.pathname[0] == '/') { + ret += RemoveDotSegments(h.pathname); + } else { + if (h.pathname == "") { + ret += RemoveDotSegments(b.pathname); + } else { + ret += RemoveDotSegments( + (b.authority != "" && b.pathname == "" ? "/" : "") + + b.pathname.substr(0, b.pathname.rfind("/") + 1) + + h.pathname + ); + } + } + if (h.protocol != "" || h.authority != "" || h.pathname != "" || h.search != "") { + ret += h.search; + } else { + ret += b.search; + } + ret += h.hash; + return ret; + } + + void SchemaLoader::NormSchema(Variant &schema, const std::string &uri) { + std::string baseuri = uri; + if (schema.IsMap()) { + if (schema.Contains("id") && schema["id"].IsString()) { + baseuri = ResolveURI(baseuri, schema["id"].AsString()); + schema["id"] = baseuri; + } + if (schema.Contains("$ref") && schema["$ref"].IsString()) { + schema["$ref"] = ResolveURI(baseuri, schema["$ref"].AsString()); + } else { + for (Variant::MapIterator i(schema.MapBegin()), e(schema.MapEnd()); i != e; ++i) { + if (i->first != "enum") { + NormSchema(i->second, baseuri); + } + } + } + } else if (schema.IsList()) { + for (Variant::ListIterator i(schema.ListBegin()), e(schema.ListEnd()); i != e; ++i) { + NormSchema(*i, baseuri); + } + } + } + + void SchemaLoader::SearchForTrustedSchemas(std::map &m, + Variant schema, const std::string &uri) + { + if (schema.IsMap()) { + if (schema.Contains("id") && schema["id"].IsString()) { + std::string id = schema["id"].AsString(); + if (id.substr(0, uri.length()) == uri) { + std::string remainder = id.substr(uri.length()); + if ((uri.length() > 0 && uri[uri.length()-1] == '/') + || remainder[0] == '#' + || remainder[0] == '?') + { + if (m.find(id) == m.end()) { + m[id] = schema; + } + } + } + } + + for (Variant::MapIterator i(schema.MapBegin()), e(schema.MapEnd()); i != e; ++i) { + if (i->first != "enum" && i->second.IsMap()) { + SearchForTrustedSchemas(m, i->second, uri); + } + } + } + } + + SchemaLoader::LoaderError::LoaderError() { + erross << "SchemaLoader error:\n"; + } + + SchemaLoader::LoaderError::~LoaderError() {} + + void SchemaLoader::LoaderError::AddError(const std::string &uri, const std::string &msg) { + erross << "\t" << uri << ": " << msg << "\n"; + } + + void AdvSchemaLoader::AddPath(const std::string &path) { + paths.push_back(path); + } + + bool AdvSchemaLoader::HandleMissing(const std::string &uri, LoaderError &error) { + URIInfo info; + if (uri.empty()) { + return SchemaLoader::HandleMissing(uri, error); + } else if (ParseURI(info, uri)) { + if (info.href[0] == '/' || info.href[0] == '.') { + // Assume file system path. + if (!LoadFromFile(info, error)) { + return SchemaLoader::HandleMissing(uri, error); + } + return true; + } else if (info.protocol.empty()) { + if (!LoadFromFile(info, error) && !LoadFromCurl(info, error)) { + return SchemaLoader::HandleMissing(uri, error); + } + return true; + } else if (info.protocol == "file:") { + if (!LoadFromFile(info, error)) { + return SchemaLoader::HandleMissing(uri, error); + } + return true; + } else { + if (!LoadFromCurl(info, error)) { + return SchemaLoader::HandleMissing(uri, error); + } + return true; + } + } + return SchemaLoader::HandleMissing(uri, error); + } + + bool AdvSchemaLoader::LoadFromFile(URIInfo &info, LoaderError &error) { + // Normalize the path.. + std::string path; + if (!info.authority.empty()) { + if ( + !info.protocol.empty() + && info.authority.size() >= 2 + && info.authority[0] == '/' + && info.authority[1] == '/' + ) + { + path = info.authority.substr(2); + } else { + path = info.authority; + } + } + path += info.pathname; + if (path[0] == '/') { + // Absolute path + try { + AddSchema(info.href, DeserializeGuessFile(path.c_str())); + return true; + } catch (const std::exception &e) { + error.AddError(path.c_str(), e.what()); + return false; + } + } + // Not absolute + for (std::vector::iterator i(paths.begin()), e(paths.end()); i != e; ++i) { + std::string uri = *i + "/" + path; + try { + AddSchema(info.href, DeserializeGuessFile(uri.c_str())); + return true; + } catch (const std::exception &e) { + error.AddError(uri, e.what()); + } + } + return false; + } + +#ifdef ENABLE_CURL + + size_t CurlContextWrite(char *ptr, size_t size, size_t nmemb, void *userdata); + + class CurlContext { + public: + + CurlContext(SchemaLoader::URIInfo &info) + : self(curl_easy_init()) + { + if (!self) { + std::ostringstream oss; + oss << "Unable to initialize curl to fetch uri: " << info.href; + throw std::runtime_error(oss.str()); + } + CURLcode err = curl_easy_setopt(self, CURLOPT_NOSIGNAL, 1); + if (err != CURLE_OK) { Error(err); } + err = curl_easy_setopt(self, CURLOPT_WRITEFUNCTION, &CurlContextWrite); + if (err != CURLE_OK) { Error(err); } + err = curl_easy_setopt(self, CURLOPT_WRITEDATA, (void*)this); + if (err != CURLE_OK) { Error(err); } + uri = info.protocol + info.authority + info.pathname + info.search; + err = curl_easy_setopt(self, CURLOPT_URL, uri.c_str()); + if (err != CURLE_OK) { Error(err); } + } + + ~CurlContext() { + curl_easy_cleanup(self); + } + + size_t Write(char *ptr, size_t len) { + data_buff.insert(data_buff.end(), ptr, ptr + len); + return len; + } + + void Perform() { + CURLcode err = curl_easy_perform(self); + if (err != CURLE_OK) { Error(err); } + } + + void Error(CURLcode err) { + std::ostringstream oss; + oss << "Error attempting to fetch uri: " << uri << "\n"; + oss << curl_easy_strerror(err); + throw std::runtime_error(oss.str()); + } + + CURL *self; + std::string uri; + std::vector data_buff; + std::vector err_buff; + }; + + size_t CurlContextWrite(char *ptr, size_t size, size_t nmemb, void *userdata) { + return ((CurlContext*)userdata)->Write(ptr, size*nmemb); + } + + bool AdvSchemaLoader::LoadFromCurl(URIInfo &info, LoaderError &error) { + try { + CurlContext ctx(info); + ctx.Perform(); + AddSchema(ctx.uri, DeserializeGuess(&ctx.data_buff[0], ctx.data_buff.size())); + return true; + } catch (const std::exception &e) { + error.AddError(info.href, e.what()); + return false; + } + } + +#else + bool AdvSchemaLoader::LoadFromCurl(URIInfo &info, LoaderError &error) { + error.AddError(info.href, "Curl support not compiled in to load urls."); + return false; + } +#endif +} diff --git a/src/hos_libvariant/src/src/StackTrace.cc b/src/hos_libvariant/src/src/StackTrace.cc new file mode 100644 index 00000000..641587af --- /dev/null +++ b/src/hos_libvariant/src/src/StackTrace.cc @@ -0,0 +1,51 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \brief functino for printing out a stack trace + * lookup the backtrace etc. in the man pages. + * \author John Bridgman + */ +#include "StackTrace.h" +#include +#include +#include +#include +#include + +void PrintStack() { + void* stack[STACKTRACE_MAXTRACE]; + size_t size = backtrace(stack, STACKTRACE_MAXTRACE); + backtrace_symbols_fd(stack, size, 2); +} + +std::string GetStack(unsigned ignore) { + void* stack[STACKTRACE_MAXTRACE]; + size_t size = backtrace(stack, STACKTRACE_MAXTRACE); + char **bt = backtrace_symbols(stack, size); + if (!bt) { + perror("backtrace_symbols"); + return ""; + } + std::ostringstream oss; + for (unsigned i = ignore; i < size; ++i) { + oss << bt[i] << '\n'; + } + free(bt); + return oss.str(); +} + + diff --git a/src/hos_libvariant/src/src/StackTrace.h b/src/hos_libvariant/src/src/StackTrace.h new file mode 100644 index 00000000..50047a0b --- /dev/null +++ b/src/hos_libvariant/src/src/StackTrace.h @@ -0,0 +1,48 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \brief function for printing out a stack trace + * Note that we need to pass -rdynamic to the linker to + * be able to see the function names with these functions. + * \author John Bridgman + */ + +#ifndef STACKTRACE_H +#define STACKTRACE_H +#pragma once +#include +#ifndef STACKTRACE_MAXTRACE +#define STACKTRACE_MAXTRACE 100 +#endif +/** + * Prints the stack trace to stderr + * Should work even if we are out of memory + */ +void PrintStack(); + +/** + * Returns a std::string to the stack trace. + * May fail if out of memory. + * \param ignore the number of top stacks to ignore. This is + * useful because this function is often used in error messages + * and it is useless garbage to report the stack from the error + * handler. + */ +std::string GetStack(unsigned ignore = 0); + +#endif + diff --git a/src/hos_libvariant/src/src/Variant.cc b/src/hos_libvariant/src/src/Variant.cc new file mode 100644 index 00000000..9afe8525 --- /dev/null +++ b/src/hos_libvariant/src/src/Variant.cc @@ -0,0 +1,2257 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= + +/** \file + * \author John Bridgman + * Variant implementation + */ +#include +#include "ParseBool.h" +#include +#include +#include +#include +#include +#include + +template +class my_modulus { +public: + T operator()(const T &lhs, const T &rhs) { return lhs % rhs; } +}; + +template<> +class my_modulus { +public: + long double operator()(const long double &lhs, const long double &rhs) { return fmod(lhs, rhs); } +}; + +namespace libvariant { + + static inline Variant::Type_t NumericUpcast(Variant::Type_t t1, Variant::Type_t t2) { + switch (t1) { + case Variant::IntegerType: + switch (t2) { + case Variant::IntegerType: + return Variant::IntegerType; + case Variant::UnsignedType: + return Variant::UnsignedType; + case Variant::FloatType: + return Variant::FloatType; + case Variant::NullType: + case Variant::BoolType: + case Variant::StringType: + case Variant::ListType: + case Variant::MapType: + throw UnableToConvertError(t2, "a numeric type."); + default: + throw UnknownTypeError(t2); + } + case Variant::UnsignedType: + switch (t2) { + case Variant::IntegerType: + return Variant::UnsignedType; + case Variant::UnsignedType: + return Variant::UnsignedType; + case Variant::FloatType: + return Variant::FloatType; + case Variant::NullType: + case Variant::BoolType: + case Variant::StringType: + case Variant::ListType: + case Variant::MapType: + throw UnableToConvertError(t2, "a numeric type."); + default: + throw UnknownTypeError(t2); + } + case Variant::FloatType: + switch (t2) { + case Variant::IntegerType: + return Variant::FloatType; + case Variant::UnsignedType: + return Variant::FloatType; + case Variant::FloatType: + return Variant::FloatType; + case Variant::NullType: + case Variant::BoolType: + case Variant::StringType: + case Variant::ListType: + case Variant::MapType: + throw UnableToConvertError(t2, "a numeric type."); + default: + throw UnknownTypeError(t2); + } + case Variant::NullType: + case Variant::BoolType: + case Variant::StringType: + case Variant::ListType: + case Variant::MapType: + throw UnableToConvertError(t1, "a numeric type."); + default: + throw UnknownTypeError(t1); + } + } + + + namespace Internal { + + struct RefData { + RefData() : valid(true) {} + bool valid; + }; + + struct Storage { + Storage() {} + + virtual ~Storage() {} + + }; + + struct MapStorage : public Storage { + MapStorage(const Variant::Map &m) : map(m) {} + Variant::Map map; + }; + + struct ListStorage : public Storage { + ListStorage(const Variant::List &l) : list(l) {} + Variant::List list; + }; + + struct StringStorage : public Storage { + StringStorage(const std::string &s) : str(s) {} + std::string str; + }; + + struct BlobStorage : public Storage { + BlobStorage(BlobPtr b) : blob(b) {} + BlobPtr blob; + }; + + struct RefStorage : public Storage { + shared_ptr storage; + }; + + struct ProxyStorage : public Storage { + ProxyStorage(Data *ref_, Path::const_iterator b, Path::const_iterator e) + : ref(ref_), storage(ref_->storage), path(b, e) + {} + Data *ref; + shared_ptr storage; + Path path; + }; + + + // Three ways to look up a value in a map or list: + // Get a reference/proxy -> GetRef + // Get pointer/throw -> Get checked=true + // Get pointer/null -> Get checked=false + + class VTable { + public: + static inline Data *GetData(Variant *v) { return v; } + static inline const Data *GetData(const Variant *v) { return v; } + static inline Variant *GetVar(Data *d) { return static_cast(d); } + static inline const Variant *GetVar(const Data *d) { return static_cast(d); } + + virtual ~VTable() {} + virtual void Copy(const Data *that, Data *other) const = 0; + virtual void Assign(const Data *that, Data *other) const; + virtual void MakeRef(const Data *that, Data *ref) const; + virtual void MakeProxy(Data *that, Data *ref, Path::const_iterator b, Path::const_iterator e) const; + virtual Variant::Type_t GetType(const Data *that) const = 0; + virtual bool AsBool(const Data *that) const; + virtual long double AsLongDouble(const Data *that) const; + virtual uintmax_t AsUnsigned(const Data *that) const; + virtual intmax_t AsInt(const Data *that) const; + virtual std::string AsString(const Data *that) const; + virtual BlobPtr AsBlob(Data *that) const; + virtual ConstBlobPtr AsBlobConst(const Data *that) const; + virtual unsigned Size(const Data *that) const; + virtual bool Empty(const Data *that) const; + virtual void Clear(Data *that) const; + virtual Variant::List &AsList(Data *that) const; + virtual const Variant::List &AsListConst(const Data *that) const; + virtual bool ContainsIndex(const Data *that, unsigned i) const; + virtual unsigned Index(const Data *that, Variant v) const; + virtual void EraseIndex(Data *that, unsigned i) const; + virtual VariantRef GetRefIndex(Data *that, unsigned i, Variant *def) const; + virtual const Variant *GetConstIndex(const Data *that, unsigned i, bool checked) const; + virtual Variant *GetIndex(Data *that, unsigned i, bool checked) const; + virtual void SetIndex(Data *that, unsigned i, const Data *other) const; + virtual Variant::Map &AsMap(Data *that) const; + virtual const Variant::Map &AsMapConst(const Data *that) const; + virtual bool ContainsKey(const Data *that, const std::string &s) const; + virtual void EraseKey(Data *that, const std::string &key) const; + virtual VariantRef GetRefKey(Data *that, const std::string &s, Variant *def) const; + virtual const Variant *GetConstKey(const Data *that, const std::string &s, bool checked) const; + virtual Variant *GetKey(Data *that, const std::string &s, bool checked) const; + virtual void SetKey(Data *that, const std::string &s, const Data *other) const; + VariantRef GetPathRef(Data *that, Path::const_iterator b, Path::const_iterator e, Variant *def) const; + const Variant *GetPathConst(const Data *that, Path::const_iterator b, Path::const_iterator e, bool checked) const; + void SetPath(Data *that, Path::const_iterator b, Path::const_iterator e, const Variant *other) const; + void ErasePath(Data *that, Path::const_iterator b, Path::const_iterator e, bool recursive) const; + bool Comparable(const Data *that, const Data *other) const; + virtual int Compare(const Data *that, const Data *other) const = 0; + virtual void Incr(Data *that) const; + virtual void Decr(Data *that) const; + virtual Variant Neg(const Data *that) const; + virtual void Add(Data *that, const Data *other) const; + virtual void Sub(Data *that, const Data *other) const; + virtual void Mul(Data *that, const Data *other) const; + virtual void Div(Data *that, const Data *other) const; + virtual void Rem(Data *that, const Data *other) const; + shared_ptr EnsureRef(Data *that) const; + virtual void Destroy(Data *that) const; + virtual void Destruct(Data *that) const; + virtual Variant *Resolve(Data *that) const; + virtual const Variant *ResolveConst(const Data *that) const; + virtual Variant *ResolveDefault(Data *that, const Data *def) const; + virtual bool Exists(const Data *that) const; + }; + + void DefaultInit(Data *that, VariantDefines::Type_t type); + + void NullInit(Data *that); + + void BoolInit(Data *that, bool b); + + void IntegerInit(Data *that, intmax_t i); + + void UnsignedInit(Data *that, uintmax_t u); + + void FloatInit(Data *that, long double f); + + void StringInit(Data *that, const std::string &s); + + void ListInit(Data *that, const Variant::List &l); + + void MapInit(Data *that, const Variant::Map &m); + + void BlobInit(Data *that, BlobPtr blob); + + void RefInit(Data *that, const Data *other); + + void ProxyInit(Data *that, Data *ref, Path::const_iterator b, Path::const_iterator e); + + //-------------------- + // VTable + //-------------------- + + void VTable::Assign(const Data *that, Data *other) const + { that->vtable->Copy(that, VTable::GetData(other->vtable->Resolve(other))); } + + void VTable::MakeRef(const Data *that, Data *ref) const { + RefInit(ref, that); + } + void VTable::MakeProxy(Data *that, Data *ref, Path::const_iterator b, Path::const_iterator e) const + { ProxyInit(ref, that, b, e); } + + bool VTable::AsBool(const Data *that) const + { throw UnableToConvertError(that->vtable->GetType(that), "a bool"); } + + long double VTable::AsLongDouble(const Data *that) const + { throw UnableToConvertError(that->vtable->GetType(that), "a float"); } + + uintmax_t VTable::AsUnsigned(const Data *that) const + { throw UnableToConvertError(that->vtable->GetType(that), "a unsigned"); } + + intmax_t VTable::AsInt(const Data *that) const + { throw UnableToConvertError(that->vtable->GetType(that), "a int"); } + + std::string VTable::AsString(const Data *that) const + { throw UnableToConvertError(that->vtable->GetType(that), "a string"); } + + BlobPtr VTable::AsBlob(Data *that) const + { throw UnexpectedTypeError(VariantDefines::BlobType, that->vtable->GetType(that)); } + + ConstBlobPtr VTable::AsBlobConst(const Data *that) const + { throw UnexpectedTypeError(VariantDefines::BlobType, that->vtable->GetType(that)); } + + unsigned VTable::Size(const Data *that) const + { throw InvalidOperationError(that->vtable->GetType(that), "Size"); } + + bool VTable::Empty(const Data *that) const + { throw InvalidOperationError(that->vtable->GetType(that), "Empty"); } + + void VTable::Clear(Data *that) const { NullInit(that); } + + Variant::List &VTable::AsList(Data *that) const + { throw UnableToConvertError(that->vtable->GetType(that), "a list"); } + + const Variant::List &VTable::AsListConst(const Data *that) const + { throw UnexpectedTypeError(VariantDefines::ListType, that->vtable->GetType(that)); } + + bool VTable::ContainsIndex(const Data *that, unsigned i) const + { return false; } + + unsigned VTable::Index(const Data *that, Variant o) const + { throw UnexpectedTypeError(VariantDefines::ListType, that->vtable->GetType(that)); } + + void VTable::EraseIndex(Data *that, unsigned i) const + { throw UnexpectedTypeError(VariantDefines::ListType, that->vtable->GetType(that)); } + + VariantRef VTable::GetRefIndex(Data *that, unsigned i, Variant *def) const + { throw UnexpectedTypeError(VariantDefines::ListType, that->vtable->GetType(that)); } + + const Variant *VTable::GetConstIndex(const Data *that, unsigned i, bool checked) const { + if (!checked) { return 0; } + throw UnexpectedTypeError(VariantDefines::ListType, that->vtable->GetType(that)); + } + + Variant *VTable::GetIndex(Data *that, unsigned i, bool checked) const { + if (!checked) { return 0; } + throw UnexpectedTypeError(VariantDefines::ListType, that->vtable->GetType(that)); + } + + void VTable::SetIndex(Data *that, unsigned i, const Data *other) const + { throw UnexpectedTypeError(VariantDefines::ListType, that->vtable->GetType(that)); } + + Variant::Map &VTable::AsMap(Data *that) const + { throw UnableToConvertError(that->vtable->GetType(that), "a map"); } + + const Variant::Map &VTable::AsMapConst(const Data *that) const + { throw UnexpectedTypeError(VariantDefines::MapType, that->vtable->GetType(that)); } + + bool VTable::ContainsKey(const Data *that, const std::string &s) const + { return false; } + + void VTable::EraseKey(Data *that, const std::string &key) const + { throw UnexpectedTypeError(VariantDefines::MapType, that->vtable->GetType(that)); } + + VariantRef VTable::GetRefKey(Data *that, const std::string &s, Variant *def) const + { throw UnexpectedTypeError(VariantDefines::MapType, that->vtable->GetType(that)); } + + const Variant *VTable::GetConstKey(const Data *that, const std::string &s, bool checked) const { + if (!checked) { return 0; } + throw UnexpectedTypeError(VariantDefines::MapType, that->vtable->GetType(that)); + } + + Variant *VTable::GetKey(Data *that, const std::string &s, bool checked) const { + if (!checked) { return 0; } + throw UnexpectedTypeError(VariantDefines::MapType, that->vtable->GetType(that)); + } + + void VTable::SetKey(Data *that, const std::string &s, const Data *other) const + { throw UnexpectedTypeError(VariantDefines::MapType, that->vtable->GetType(that)); } + + const Variant *GetPathElem(const Data *that, const PathElement &elem, bool checked) { + if (elem.IsString()) { + return that->vtable->GetConstKey(that, elem.AsString(), checked); + } else /* if (elem.IsNumber()) */ { + return that->vtable->GetConstIndex(that, elem.AsUnsigned(), checked); + } + } + + Variant *GetPathElem(Data *that, const PathElement &elem, bool checked) { + if (elem.IsString()) { + return that->vtable->GetKey(that, elem.AsString(), checked); + } else /* if (elem.IsNumber()) */ { + return that->vtable->GetIndex(that, elem.AsUnsigned(), checked); + } + } + + VariantRef GetRefPathElem(Data *that, const PathElement &elem, Variant *def) { + if (elem.IsString()) { + return that->vtable->GetRefKey(that, elem.AsString(), def); + } else /* if (elem.IsNumber()) */ { + return that->vtable->GetRefIndex(that, elem.AsUnsigned(), def); + } + } + + void SetPathElem(Data *that, const PathElement &elem, const Variant *other) { + if (elem.IsString()) { + that->vtable->SetKey(that, elem.AsString(), VTable::GetData(other)); + } else /* if (elem.IsNumber()) */ { + that->vtable->SetIndex(that, elem.AsUnsigned(), VTable::GetData(other)); + } + } + + VariantRef VTable::GetPathRef(Data *that, Path::const_iterator b, + Path::const_iterator e, Variant *def) const + { + if (b == e) { return VariantRef(*GetVar(that)); } + Variant *ref = 0; + ref = GetPathElem(that, *b, false); + if (!ref) { + if (!def) { + return VariantRef(*GetVar(that), b, e); + } + if (b + 1 == e) { + return GetRefPathElem(that, *b, def); + } else { + Variant null_value; + SetPathElem(that, *b, &null_value); + return that->vtable->GetPathRef(that, b, e, def); + } + } + if (b + 1 == e) { + return VariantRef(*ref); + } else { + Data *ref_data = VTable::GetData(ref); + return ref_data->vtable->GetPathRef(ref_data, b + 1, e, def); + } + } + + const Variant *VTable::GetPathConst(const Data *that, Path::const_iterator b, Path::const_iterator e, bool checked) const + { + if (b == e) { return that->vtable->ResolveConst(that); } + const Variant *ref = 0; + ref = GetPathElem(that, *b, checked); + if (!ref) { + if (checked) { + if (b->IsString()) { + throw KeyError(b->AsString()); + } else { + throw std::out_of_range("Variant::List index out of range."); + } + } + return 0; + } + if (b + 1 == e) { + return ref; + } else { + const Data *ref_data = VTable::GetData(ref); + return ref_data->vtable->GetPathConst(ref_data, b + 1, e, checked); + } + } + + void VTable::SetPath(Data *that, Path::const_iterator b, Path::const_iterator e, const Variant *other) const + { + if (b == e) { + const Data *other_data = VTable::GetData(other); + other_data->vtable->Assign(other_data, that); + return; + } + Variant *ref = 0; + ref = GetPathElem(that, *b, false); + if (!ref) { + if (b + 1 == e) { + SetPathElem(that, *b, other); + return; + } else { + Variant null_value; + SetPathElem(that, *b, &null_value); + that->vtable->SetPath(that, b, e, other); + return; + } + } + Data *ref_data = VTable::GetData(ref); + ref_data->vtable->SetPath(ref_data, b + 1, e, other); + } + + void ErasePathElem(Data *that, const PathElement &elem) { + if (elem.IsString()) { + return that->vtable->EraseKey(that, elem.AsString()); + } else /* if (elem.IsNumber()) */ { + return that->vtable->EraseIndex(that, elem.AsUnsigned()); + } + } + + void VTable::ErasePath(Data *that, Path::const_iterator b, Path::const_iterator e, bool remove_empty) const + { + if (b == e) { return; } + if (b + 1 == e) { + ErasePathElem(that, *b); + return; + } + Variant *ref = 0; + ref = GetPathElem(that, *b, false); + if (!ref) { return; } + Data *ref_data = VTable::GetData(ref); + ref_data->vtable->ErasePath(ref_data, b + 1, e, remove_empty); + if (remove_empty && ref_data->vtable->Empty(ref_data)) { + ErasePathElem(that, *b); + } + } + + bool VTable::Comparable(const Data *that, const Data *other) const { + VariantDefines::Type_t ltype = that->vtable->GetType(that), otype = other->vtable->GetType(other); + return ( ltype == otype ) + || ( + ( ltype == VariantDefines::IntegerType + || ltype == VariantDefines::UnsignedType + || ltype == VariantDefines::FloatType ) + && ( otype == VariantDefines::IntegerType + || otype == VariantDefines::UnsignedType + || otype == VariantDefines::FloatType ) + ); + } + + void VTable::Incr(Data *that) const + { throw NotNumericTypeError(that->vtable->GetType(that)); } + + void VTable::Decr(Data *that) const + { throw NotNumericTypeError(that->vtable->GetType(that)); } + + Variant VTable::Neg(const Data *that) const + { throw NotNumericTypeError(that->vtable->GetType(that)); } + + void VTable::Add(Data *that, const Data *other) const + { throw NotNumericTypeError(that->vtable->GetType(that)); } + + void VTable::Sub(Data *that, const Data *other) const + { throw NotNumericTypeError(that->vtable->GetType(that)); } + + void VTable::Mul(Data *that, const Data *other) const + { throw NotNumericTypeError(that->vtable->GetType(that)); } + + void VTable::Div(Data *that, const Data *other) const + { throw NotNumericTypeError(that->vtable->GetType(that)); } + + void VTable::Rem(Data *that, const Data *other) const + { throw NotNumericTypeError(that->vtable->GetType(that)); } + + shared_ptr VTable::EnsureRef(Data *that) const { + if (!that->ref_data) { + that->ref_data.reset(new RefData()); + } + return that->ref_data; + } + + void VTable::Destroy(Data *that) const { + assert(that->vtable); + that->storage.reset(); + that->vtable = 0; + } + + void VTable::Destruct(Data *that) const { + that->vtable->Destroy(that); + if (that->ref_data) { + that->ref_data->valid = false; + that->ref_data.reset(); + } + } + + Variant *VTable::Resolve(Data *that) const + { return VTable::GetVar(that); } + + const Variant *VTable::ResolveConst(const Data *that) const + { return VTable::GetVar(that); } + + Variant *VTable::ResolveDefault(Data *that, const Data *) const + { return VTable::GetVar(that); } + + bool VTable::Exists(const Data *that) const { return true; } + + //-------------------- + // NullVTable + //-------------------- + + class Null : public VTable { + public: + Null() {} + virtual void Copy(const Data *that, Data *other) const; + virtual Variant::Type_t GetType(const Data *that) const; + virtual bool AsBool(const Data *that) const; + virtual long double AsLongDouble(const Data *that) const; + virtual uintmax_t AsUnsigned(const Data *that) const; + virtual intmax_t AsInt(const Data *that) const; + virtual std::string AsString(const Data *that) const; + virtual unsigned Size(const Data *that) const; + virtual bool Empty(const Data *that) const; + virtual void Clear(Data *that) const; + virtual Variant::List &AsList(Data *that) const; + virtual void EraseIndex(Data *that, unsigned i) const; + virtual VariantRef GetRefIndex(Data *that, unsigned i, Variant *def) const; + virtual const Variant *GetConstIndex(const Data *that, unsigned i, bool checked) const; + virtual Variant *GetIndex(Data *that, unsigned i, bool checked) const; + virtual void SetIndex(Data *that, unsigned i, const Data *other) const; + virtual Variant::Map &AsMap(Data *that) const; + virtual void EraseKey(Data *that, const std::string &key) const; + virtual VariantRef GetRefKey(Data *that, const std::string &s, Variant *def) const; + virtual const Variant *GetConstKey(const Data *that, const std::string &s, bool checked) const; + virtual Variant *GetKey(Data *that, const std::string &s, bool checked) const; + virtual void SetKey(Data *that, const std::string &s, const Data *other) const; + virtual int Compare(const Data *that, const Data *other) const; + virtual Variant *ResolveDefault(Data *that, const Data *def) const; + }; + + const VTable *NullVTable() { + static const Null null_vtable; + return &null_vtable; + } + + void Null::Copy(const Data *that, Data *other) const { NullInit(other); } + + VariantDefines::Type_t Null::GetType(const Data *that) const + { return VariantDefines::NullType; } + + bool Null::AsBool(const Data *that) const { return false; } + + long double Null::AsLongDouble(const Data *that) const { return 0.0; } + + uintmax_t Null::AsUnsigned(const Data *that) const { return 0; } + + intmax_t Null::AsInt(const Data *that) const { return 0; } + + std::string Null::AsString(const Data *that) const { return ""; } + + unsigned Null::Size(const Data *that) const { return 0; } + + bool Null::Empty(const Data *that) const { return true; } + + void Null::Clear(Data *that) const {} + + Variant::List &Null::AsList(Data *that) const { + ListInit(that, Variant::List()); + return that->vtable->AsList(that); + } + void Null::EraseIndex(Data *that, unsigned i) const {} + + VariantRef Null::GetRefIndex(Data *that, unsigned i, Variant *def) const { + if (def) { + ListInit(that, Variant::List()); + return that->vtable->GetRefIndex(that, i, def); + } + return VariantRef(*that->vtable->Resolve(that), Path(1, i)); + } + + const Variant *Null::GetConstIndex(const Data *that, unsigned i, bool checked) const { + if (!checked) { return 0; } + throw std::out_of_range("Variant::List index out of range."); + } + + Variant *Null::GetIndex(Data *that, unsigned i, bool checked) const { + if (!checked) { return 0; } + throw std::out_of_range("Variant::List index out of range."); + } + + void Null::SetIndex(Data *that, unsigned i, const Data *other) const { + ListInit(that, Variant::List()); + that->vtable->SetIndex(that, i, other); + } + + Variant::Map &Null::AsMap(Data *that) const { + MapInit(that, Variant::Map()); + return that->vtable->AsMap(that); + } + + + void Null::EraseKey(Data *that, const std::string &) const {} + + VariantRef Null::GetRefKey(Data *that, const std::string &s, Variant *def) const { + if (def) { + MapInit(that, Variant::Map()); + return that->vtable->GetRefKey(that, s, def); + } + return VariantRef(*that->vtable->Resolve(that), Path(1, s)); + } + + const Variant *Null::GetConstKey(const Data *that, const std::string &s, bool checked) const { + if (!checked) { return 0; } + throw KeyError(s); + } + + Variant *Null::GetKey(Data *that, const std::string &s, bool checked) const { + if (!checked) { return 0; } + throw KeyError(s); + } + + void Null::SetKey(Data *that, const std::string &s, const Data *other) const { + MapInit(that, Variant::Map()); + that->vtable->SetKey(that, s, other); + } + + int Null::Compare(const Data *that, const Data *other) const { + return (Comparable(that, other) ? 0 : 1); + } + + Variant *Null::ResolveDefault(Data *that, const Data *def) const { + def->vtable->Assign(def, that); + return that->vtable->Resolve(that); + } + + void NullInit(Data *that) { + if (that->vtable) that->vtable->Destroy(that); + that->vtable = NullVTable(); + } + + //-------------------- + // BoolVTable + //-------------------- + + class Bool : public VTable { + public: + Bool() {} + virtual void Copy(const Data *that, Data *other) const; + virtual Variant::Type_t GetType(const Data *that) const; + virtual bool AsBool(const Data *that) const; + virtual long double AsLongDouble(const Data *that) const; + virtual uintmax_t AsUnsigned(const Data *that) const; + virtual intmax_t AsInt(const Data *that) const; + virtual std::string AsString(const Data *that) const; + virtual int Compare(const Data *that, const Data *other) const; + }; + + void Bool::Copy(const Data *that, Data *other) const + { BoolInit(other, that->b); } + + VariantDefines::Type_t Bool::GetType(const Data *that) const + { return VariantDefines::BoolType; } + + bool Bool::AsBool(const Data *that) const + { return that->b; } + + long double Bool::AsLongDouble(const Data *that) const + { return that->b; } + + uintmax_t Bool::AsUnsigned(const Data *that) const + { return that->b; } + + intmax_t Bool::AsInt(const Data *that) const + { return that->b; } + + std::string Bool::AsString(const Data *that) const { + if (that->b) { return "true"; } + else { return "false"; } + } + + int Bool::Compare(const Data *that, const Data *other) const { + if (Comparable(that, other)) { + other = VTable::GetData(other->vtable->ResolveConst(other)); + return (that->b == other->b ? 0 : 1); + } + return 1; + } + + void BoolInit(Data *that, bool b) { + static const Bool bool_vtable; + if (that->vtable) that->vtable->Destroy(that); + that->vtable = &bool_vtable; + that->b = b; + } + + //-------------------- + // NumericVTable + //-------------------- + + class Numeric : public VTable { + public: + virtual int Compare(const Data *that, const Data *other) const; + virtual void Add(Data *that, const Data *other) const; + virtual void Sub(Data *that, const Data *other) const; + virtual void Mul(Data *that, const Data *other) const; + virtual void Div(Data *that, const Data *other) const; + virtual void Rem(Data *that, const Data *other) const; + }; + + int Numeric::Compare(const Data *that, const Data *other) const { + if (Comparable(that, other)) { + long double us = that->vtable->AsLongDouble(that); + long double o = other->vtable->AsLongDouble(other); + if (us < o) { return -1; } + else if (us > o) { return 1; } + else { return 0; } + } + return 1; + } + + template< template class Op > + void NumericOperation(Data *that, const Data *other) { + VariantDefines::Type_t ntype = NumericUpcast(that->vtable->GetType(that), + other->vtable->GetType(other)); + switch (ntype) { + case VariantDefines::IntegerType: + { + Op op; + IntegerInit(that, + op(that->vtable->AsInt(that), other->vtable->AsInt(other))); + } + break; + case VariantDefines::UnsignedType: + { + Op op; + UnsignedInit(that, + op(that->vtable->AsUnsigned(that), other->vtable->AsUnsigned(other))); + } + break; + case VariantDefines::FloatType: + { + Op op; + FloatInit(that, + op(that->vtable->AsLongDouble(that), other->vtable->AsLongDouble(other))); + } + break; + default: + throw NotNumericTypeError(ntype); + } + } + + void Numeric::Add(Data *that, const Data *other) const + { NumericOperation(that, other); } + + void Numeric::Sub(Data *that, const Data *other) const + { NumericOperation(that, other); } + + void Numeric::Mul(Data *that, const Data *other) const + { NumericOperation(that, other); } + + void Numeric::Div(Data *that, const Data *other) const + { NumericOperation(that, other); } + + void Numeric::Rem(Data *that, const Data *other) const + { NumericOperation(that, other); } + + //-------------------- + // IntegerVTable + //-------------------- + + class Integer : public Numeric { + public: + Integer() {} + virtual void Copy(const Data *that, Data *other) const; + virtual Variant::Type_t GetType(const Data *that) const; + virtual bool AsBool(const Data *that) const; + virtual long double AsLongDouble(const Data *that) const; + virtual uintmax_t AsUnsigned(const Data *that) const; + virtual intmax_t AsInt(const Data *that) const; + virtual std::string AsString(const Data *that) const; + virtual void Incr(Data *that) const; + virtual void Decr(Data *that) const; + virtual Variant Neg(const Data *that) const; + }; + + void Integer::Copy(const Data *that, Data *other) const + { IntegerInit(other, that->i); } + + VariantDefines::Type_t Integer::GetType(const Data *that) const + { return VariantDefines::IntegerType; } + + bool Integer::AsBool(const Data *that) const + { return that->i != 0; } + + long double Integer::AsLongDouble(const Data *that) const + { return (long double)that->i; } + + uintmax_t Integer::AsUnsigned(const Data *that) const + { return (uintmax_t)that->i; } + + intmax_t Integer::AsInt(const Data *that) const + { return that->i; } + + std::string Integer::AsString(const Data *that) const { + std::ostringstream oss; + oss << that->i; + return oss.str(); + } + + void Integer::Incr(Data *that) const + { ++that->i; } + + void Integer::Decr(Data *that) const + { --that->i; } + + Variant Integer::Neg(const Data *that) const + { return Variant(-that->i); } + + void IntegerInit(Data *that, intmax_t i) { + static const Integer integer_vtable; + if (that->vtable) that->vtable->Destroy(that); + that->vtable = &integer_vtable; + that->i = i; + } + + //-------------------- + // UnsignedVTable + //-------------------- + + class Unsigned : public Numeric { + public: + Unsigned() {} + virtual void Copy(const Data *that, Data *other) const; + virtual Variant::Type_t GetType(const Data *that) const; + virtual bool AsBool(const Data *that) const; + virtual long double AsLongDouble(const Data *that) const; + virtual uintmax_t AsUnsigned(const Data *that) const; + virtual intmax_t AsInt(const Data *that) const; + virtual std::string AsString(const Data *that) const; + virtual void Incr(Data *that) const; + virtual void Decr(Data *that) const; + virtual Variant Neg(const Data *that) const; + }; + + void Unsigned::Copy(const Data *that, Data *other) const + { UnsignedInit(other, that->u); } + + VariantDefines::Type_t Unsigned::GetType(const Data *that) const + { return VariantDefines::UnsignedType; } + + bool Unsigned::AsBool(const Data *that) const + { return that->u != 0; } + + long double Unsigned::AsLongDouble(const Data *that) const + { return (long double)that->u; } + + uintmax_t Unsigned::AsUnsigned(const Data *that) const + { return that->u; } + + intmax_t Unsigned::AsInt(const Data *that) const + { return (intmax_t)that->u; } + + std::string Unsigned::AsString(const Data *that) const { + std::ostringstream oss; + oss << that->u; + return oss.str(); + } + + void Unsigned::Incr(Data *that) const + { ++that->u; } + + void Unsigned::Decr(Data *that) const + { --that->u; } + + Variant Unsigned::Neg(const Data *that) const { + return Variant(-that->u); + } + + void UnsignedInit(Data *that, uintmax_t u) { + static const Unsigned unsigned_vtable; + if (that->vtable) that->vtable->Destroy(that); + that->vtable = &unsigned_vtable; + that->u = u; + } + + //-------------------- + // FloatVTable + //-------------------- + + class Float : public Numeric { + public: + Float() {} + virtual void Copy(const Data *that, Data *other) const; + virtual Variant::Type_t GetType(const Data *that) const; + virtual bool AsBool(const Data *that) const; + virtual long double AsLongDouble(const Data *that) const; + virtual uintmax_t AsUnsigned(const Data *that) const; + virtual intmax_t AsInt(const Data *that) const; + virtual std::string AsString(const Data *that) const; + virtual void Incr(Data *that) const; + virtual void Decr(Data *that) const; + virtual Variant Neg(const Data *that) const; + }; + + void Float::Copy(const Data *that, Data *other) const { + FloatInit(other, that->f); + } + + VariantDefines::Type_t Float::GetType(const Data *that) const + { return VariantDefines::FloatType; } + + bool Float::AsBool(const Data *that) const + { return that->f != 0; } + + long double Float::AsLongDouble(const Data *that) const + { return that->f; } + + uintmax_t Float::AsUnsigned(const Data *that) const + { return (uintmax_t)that->f; } + + intmax_t Float::AsInt(const Data *that) const + { return (intmax_t)that->f; } + + std::string Float::AsString(const Data *that) const { + std::ostringstream oss; + oss << that->f; + return oss.str(); + } + + void Float::Incr(Data *that) const + { ++that->f; } + + void Float::Decr(Data *that) const + { --that->f; } + + Variant Float::Neg(const Data *that) const { + return Variant(-that->f); + } + + void FloatInit(Data *that, long double f) { + static const Float float_vtable; + if (that->vtable) that->vtable->Destroy(that); + that->vtable = &float_vtable; + that->f = f; + } + + //-------------------- + // StringVTable + //-------------------- + + class String : public VTable { + public: + String() {} + virtual void Copy(const Data *that, Data *other) const; + virtual void Assign(const Data *that, Data *other) const; + virtual Variant::Type_t GetType(const Data *that) const; + virtual bool AsBool(const Data *that) const; + virtual long double AsLongDouble(const Data *that) const; + virtual uintmax_t AsUnsigned(const Data *that) const; + virtual intmax_t AsInt(const Data *that) const; + virtual std::string AsString(const Data *that) const; + virtual unsigned Size(const Data *that) const; + virtual bool Empty(const Data *that) const; + virtual void Clear(Data *that) const; + virtual int Compare(const Data *that, const Data *other) const; + virtual void Destroy(Data *that) const; + }; + + const VTable *StringVTable() { + static const String string_vtable; + return &string_vtable; + } + + void String::Copy(const Data *that, Data *other) const + { StringInit(other, *that->s); } + + void String::Assign(const Data *that, Data *other) const { + assert(that->vtable); + shared_ptr storage = that->storage; + std::string *s = that->s; + if (other->vtable) { other = VTable::GetData(other->vtable->Resolve(other)); } + if (other->vtable) { other->vtable->Destroy(other); } + other->vtable = StringVTable(); + other->s = s; + other->storage = storage; + } + + VariantDefines::Type_t String::GetType(const Data *that) const + { return VariantDefines::StringType; } + + bool String::AsBool(const Data *that) const + { return ParseBool(*that->s); } + + long double String::AsLongDouble(const Data *that) const { + std::istringstream iss(*that->s); + long double val = 0; + iss >> val; + if (iss.fail()) { throw UnableToConvertError(that->vtable->GetType(that), "a float"); } + return val; + } + + uintmax_t String::AsUnsigned(const Data *that) const { + std::istringstream iss(*that->s); + uintmax_t val = 0; + iss >> val; + if (iss.fail()) { throw UnableToConvertError(that->vtable->GetType(that), "an unsigned"); } + return val; + } + + intmax_t String::AsInt(const Data *that) const { + std::istringstream iss(*that->s); + intmax_t val = 0; + iss >> val; + if (iss.fail()) { throw UnableToConvertError(that->vtable->GetType(that), "an int"); } + return val; + } + + std::string String::AsString(const Data *that) const + { return *that->s; } + + unsigned String::Size(const Data *that) const { return that->s->size(); } + + bool String::Empty(const Data *that) const { return that->s->empty(); } + + void String::Clear(Data *that) const { return that->s->clear(); } + + int String::Compare(const Data *that, const Data *other) const { + if (Comparable(that, other)) { + other = VTable::GetData(other->vtable->ResolveConst(other)); + return that->s->compare(*other->s); + } + return 1; + } + + void String::Destroy(Data *that) const { + VTable::Destroy(that); + that->s = 0; + } + + void StringInit(Data *that, const std::string &s) { + if (that->vtable) that->vtable->Destroy(that); + that->vtable = StringVTable(); + shared_ptr storage(new StringStorage(s)); + that->s = &storage->str; + that->storage = storage; + } + + //-------------------- + // ListVTable + //-------------------- + + class List : public VTable { + public: + List() {} + virtual void Copy(const Data *that, Data *other) const; + virtual void Assign(const Data *that, Data *other) const; + virtual Variant::Type_t GetType(const Data *that) const; + virtual unsigned Size(const Data *that) const; + virtual bool Empty(const Data *that) const; + virtual void Clear(Data *that) const; + virtual Variant::List &AsList(Data *that) const; + virtual const Variant::List &AsListConst(const Data *that) const; + virtual bool ContainsIndex(const Data *that, unsigned i) const; + virtual unsigned Index(const Data *that, Variant v) const; + virtual void EraseIndex(Data *that, unsigned i) const; + virtual VariantRef GetRefIndex(Data *that, unsigned i, Variant *def) const; + virtual const Variant *GetConstIndex(const Data *that, unsigned i, bool checked) const; + virtual Variant *GetIndex(Data *that, unsigned i, bool checked) const; + virtual void SetIndex(Data *that, unsigned i, const Data *other) const; + virtual int Compare(const Data *that, const Data *other) const; + virtual void Destroy(Data *that) const; + }; + + const VTable *ListVTable() { + static const List list_vtable; + return &list_vtable; + } + + void List::Copy(const Data *that, Data *other) const { + ListInit(other, Variant::List()); + for (Variant::ConstListIterator i(that->l->list.begin()), e(that->l->list.end()); + i != e; ++i) { + other->l->list.push_back(i->Copy()); + } + } + + void List::Assign(const Data *that, Data *other) const { + assert(that->vtable); + shared_ptr storage = that->storage; + ListStorage *l = that->l; + if (other->vtable) { other = VTable::GetData(other->vtable->Resolve(other)); } + if (other->vtable) { other->vtable->Destroy(other); } + other->vtable = ListVTable(); + other->l = l; + other->storage = storage; + } + + VariantDefines::Type_t List::GetType(const Data *that) const { return VariantDefines::ListType; } + + unsigned List::Size(const Data *that) const { return that->l->list.size(); } + + bool List::Empty(const Data *that) const { return that->l->list.empty(); } + + void List::Clear(Data *that) const { return that->l->list.clear(); } + + Variant::List &List::AsList(Data *that) const { return that->l->list; } + + const Variant::List &List::AsListConst(const Data *that) const { return that->l->list; } + + bool List::ContainsIndex(const Data *that, unsigned i) const { return i < that->l->list.size(); } + + unsigned List::Index(const Data *that, Variant v) const { + Variant::ListIterator begin = that->l->list.begin(), + end = that->l->list.end(); + return std::distance(begin, std::find(begin, end, v)); + } + + void List::EraseIndex(Data *that, unsigned i) const + { + unsigned size = that->l->list.size(); + if (i + 1 < size) { + that->l->list.at(i).Assign(Variant::NullType); + } else if (i < size) { + that->l->list.pop_back(); + } + } + + VariantRef List::GetRefIndex(Data *that, unsigned i, Variant *def) const { + if (i < that->l->list.size()) { + return VariantRef(that->l->list.at(i)); + } else if (def) { + that->l->list.resize(i + 1); + that->l->list.at(i) = *def; + return VariantRef(that->l->list.at(i)); + } else { + return VariantRef(*that->vtable->Resolve(that), Path(1, i)); + } + } + + const Variant *List::GetConstIndex(const Data *that, unsigned i, bool checked) const { + if (i < that->l->list.size()) { + return &that->l->list.at(i); + } else if (!checked) { + return 0; + } else { + throw std::out_of_range("Variant::List index out of range."); + } + } + + Variant *List::GetIndex(Data *that, unsigned i, bool checked) const { + if (i < that->l->list.size()) { + return &that->l->list.at(i); + } else if (!checked) { + return 0; + } else { + throw std::out_of_range("Variant::List index out of range."); + } + } + + void List::SetIndex(Data *that, unsigned i, const Data *other) const { + if ( ! (i < that->l->list.size()) ) { + that->l->list.resize(i + 1); + } + other->vtable->Assign(other, VTable::GetData(&that->l->list.at(i))); + } + + int List::Compare(const Data *that, const Data *other) const { + if (Comparable(that, other)) { + other = VTable::GetData(other->vtable->ResolveConst(other)); + return (that->l->list != other->l->list ? 1 : 0); + } + return 1; + } + + void List::Destroy(Data *that) const { + VTable::Destroy(that); + that->l = 0; + } + + void ListInit(Data *that, const Variant::List &l) { + if (that->vtable) that->vtable->Destroy(that); + that->vtable = ListVTable(); + shared_ptr storage(new ListStorage(l)); + that->l = storage.get(); + that->storage = storage; + } + + //-------------------- + // MapVTable + //-------------------- + + class Map : public VTable { + public: + Map() {} + virtual void Copy(const Data *that, Data *other) const; + virtual void Assign(const Data *that, Data *other) const; + virtual Variant::Type_t GetType(const Data *that) const; + virtual unsigned Size(const Data *that) const; + virtual bool Empty(const Data *that) const; + virtual void Clear(Data *that) const; + virtual Variant::Map &AsMap(Data *that) const; + virtual const Variant::Map &AsMapConst(const Data *that) const; + virtual bool ContainsKey(const Data *that, const std::string &s) const; + virtual void EraseKey(Data *that, const std::string &key) const; + virtual VariantRef GetRefKey(Data *that, const std::string &s, Variant *def) const; + virtual const Variant *GetConstKey(const Data *that, const std::string &s, bool checked) const; + virtual Variant *GetKey(Data *that, const std::string &s, bool checked) const; + virtual void SetKey(Data *that, const std::string &s, const Data *other) const; + virtual int Compare(const Data *that, const Data *other) const; + virtual void Destroy(Data *that) const; + }; + + const VTable *MapVTable() { + static const Map map_vtable; + return &map_vtable; + } + + void Map::Copy(const Data *that, Data *other) const { + MapInit(other, Variant::Map()); + for (Variant::ConstMapIterator i(that->m->map.begin()), e(that->m->map.end()); + i != e; ++i) { + other->m->map.insert(std::make_pair(i->first, i->second.Copy())); + } + } + + void Map::Assign(const Data *that, Data *other) const { + assert(that->vtable); + shared_ptr storage = that->storage; + MapStorage *m = that->m; + if (other->vtable) { other = VTable::GetData(other->vtable->Resolve(other)); } + if (other->vtable) { other->vtable->Destroy(other); } + other->vtable = MapVTable(); + other->m = m; + other->storage = storage; + } + + VariantDefines::Type_t Map::GetType(const Data *that) const { return VariantDefines::MapType; } + + unsigned Map::Size(const Data *that) const { return that->m->map.size(); } + + bool Map::Empty(const Data *that) const { return that->m->map.empty(); } + + void Map::Clear(Data *that) const { return that->m->map.clear(); } + + Variant::Map &Map::AsMap(Data *that) const { return that->m->map; } + + const Variant::Map &Map::AsMapConst(const Data *that) const { return that->m->map; } + + bool Map::ContainsKey(const Data *that, const std::string &s) const + { return that->m->map.find(s) != that->m->map.end(); } + + void Map::EraseKey(Data *that, const std::string &key) const { that->m->map.erase(key); } + + VariantRef Map::GetRefKey(Data *that, const std::string &s, Variant *def) const { + Variant::MapIterator entry = that->m->map.find(s); + if (entry != that->m->map.end()) { + return VariantRef(entry->second); + } else if (def) { + return VariantRef(that->m->map.insert(std::make_pair(s, *def)).first->second); + } else { + return VariantRef(*that->vtable->Resolve(that), Path(1, s)); + } + } + + const Variant *Map::GetConstKey(const Data *that, const std::string &s, bool checked) const { + Variant::MapIterator entry = that->m->map.find(s); + if (entry != that->m->map.end()) { + return &entry->second; + } else if (!checked) { + return 0; + } else { + throw KeyError(s); + } + } + + Variant *Map::GetKey(Data *that, const std::string &s, bool checked) const { + Variant::MapIterator entry = that->m->map.find(s); + if (entry != that->m->map.end()) { + return &entry->second; + } else if (!checked) { + return 0; + } else { + throw KeyError(s); + } + } + + void Map::SetKey(Data *that, const std::string &s, const Data *other) const { + Variant::MapIterator entry = that->m->map.insert(std::make_pair(s, Variant())).first; + other->vtable->Assign(other, VTable::GetData(&entry->second)); + } + + + int Map::Compare(const Data *that, const Data *other) const { + if (Comparable(that, other)) { + other = VTable::GetData(other->vtable->ResolveConst(other)); + return (that->m->map != other->m->map ? 1 : 0); + } + return 1; + } + + void Map::Destroy(Data *that) const { + VTable::Destroy(that); + that->m = 0; + } + + void MapInit(Data *that, const Variant::Map &m) { + if (that->vtable) that->vtable->Destroy(that); + that->vtable = MapVTable(); + shared_ptr storage(new MapStorage(m)); + that->m = storage.get(); + that->storage = storage; + } + + //-------------------- + // BlobVTable + //-------------------- + + class Blob : public VTable { + public: + Blob() {} + virtual void Copy(const Data *that, Data *other) const; + virtual void Assign(const Data *that, Data *other) const; + virtual Variant::Type_t GetType(const Data *that) const; + virtual BlobPtr AsBlob(Data *that) const; + virtual ConstBlobPtr AsBlobConst(const Data *that) const; + virtual unsigned Size(const Data *that) const; + virtual int Compare(const Data *that, const Data *other) const; + }; + + const VTable *BlobVTable() { + static const Blob blob_vtable; + return &blob_vtable; + } + + void Blob::Copy(const Data *that, Data *other) const + { BlobInit(other, ( (*that->blob) ? (*that->blob)->Copy() : BlobPtr() )); } + + void Blob::Assign(const Data *that, Data *other) const { + assert(that->vtable); + shared_ptr storage = that->storage; + BlobPtr *b = that->blob; + if (other->vtable) { other = VTable::GetData(other->vtable->Resolve(other)); } + if (other->vtable) { other->vtable->Destroy(other); } + other->vtable = BlobVTable(); + other->blob = b; + other->storage = storage; + } + + VariantDefines::Type_t Blob::GetType(const Data *that) const + { return VariantDefines::BlobType; } + + BlobPtr Blob::AsBlob(Data *that) const + { return *(that->blob); } + + ConstBlobPtr Blob::AsBlobConst(const Data *that) const + { return *(that->blob); } + + unsigned Blob::Size(const Data *that) const + { return (*that->blob)->GetTotalLength(); } + + int Blob::Compare(const Data *that, const Data *other) const { + if (Comparable(that, other)) { + ConstBlobPtr us = (*that->blob); + ConstBlobPtr o = other->vtable->AsBlobConst(other); + if (us == o) { return 0; } + if (us && o) { return us->Compare(o); } + } + return 1; + } + + void BlobInit(Data *that, BlobPtr blob) { + if (that->vtable) that->vtable->Destroy(that); + that->vtable = BlobVTable(); + shared_ptr storage(new BlobStorage(blob)); + that->blob = &storage->blob; + that->storage = storage; + } + + //-------------------- + // RefVTable + //-------------------- + + class Ref : public VTable { + public: + Ref() {} + virtual void Copy(const Data *that, Data *other) const; + virtual void Assign(const Data *that, Data *other) const; + virtual void MakeRef(const Data *that, Data *ref) const; + virtual void MakeProxy(Data *that, Data *ref, Path::const_iterator b, Path::const_iterator e) const; + virtual Variant::Type_t GetType(const Data *that) const; + virtual bool AsBool(const Data *that) const; + virtual long double AsLongDouble(const Data *that) const; + virtual uintmax_t AsUnsigned(const Data *that) const; + virtual intmax_t AsInt(const Data *that) const; + virtual std::string AsString(const Data *that) const; + virtual BlobPtr AsBlob(Data *that) const; + virtual ConstBlobPtr AsBlobConst(const Data *that) const; + virtual unsigned Size(const Data *that) const; + virtual bool Empty(const Data *that) const; + virtual void Clear(Data *that) const; + virtual Variant::List &AsList(Data *that) const; + virtual const Variant::List &AsListConst(const Data *that) const; + virtual bool ContainsIndex(const Data *that, unsigned i) const; + virtual unsigned Index(const Data *that, Variant v) const; + virtual void EraseIndex(Data *that, unsigned i) const; + virtual VariantRef GetRefIndex(Data *that, unsigned i, Variant *def) const; + virtual const Variant *GetConstIndex(const Data *that, unsigned i, bool checked) const; + virtual Variant *GetIndex(Data *that, unsigned i, bool checked) const; + virtual void SetIndex(Data *that, unsigned i, const Data *other) const; + virtual Variant::Map &AsMap(Data *that) const; + virtual const Variant::Map &AsMapConst(const Data *that) const; + virtual bool ContainsKey(const Data *that, const std::string &s) const; + virtual void EraseKey(Data *that, const std::string &key) const; + virtual VariantRef GetRefKey(Data *that, const std::string &s, Variant *def) const; + virtual const Variant *GetConstKey(const Data *that, const std::string &s, bool checked) const; + virtual Variant *GetKey(Data *that, const std::string &s, bool checked) const; + virtual void SetKey(Data *that, const std::string &s, const Data *other) const; + virtual int Compare(const Data *that, const Data *other) const; + virtual void Incr(Data *that) const; + virtual void Decr(Data *that) const; + virtual Variant Neg(const Data *that) const; + virtual void Add(Data *that, const Data *other) const; + virtual void Sub(Data *that, const Data *other) const; + virtual void Mul(Data *that, const Data *other) const; + virtual void Div(Data *that, const Data *other) const; + virtual void Rem(Data *that, const Data *other) const; + virtual void Destroy(Data *that) const; + virtual void Destruct(Data *that) const; + virtual Variant *Resolve(Data *that) const; + virtual const Variant *ResolveConst(const Data *that) const; + virtual Variant *ResolveDefault(Data *that, const Data *def) const; + virtual bool Exists(const Data *that) const; + }; + + static inline void CheckRef(const Data *that) { + if (!that->ref_data || !that->ref_data->valid) { + throw InvalidReferenceError("Error attempting to access an invalid VariantRef"); + } + } + + void Ref::Copy(const Data *that, Data *other) const + { CheckRef(that); that->ref->vtable->Copy(that->ref, other); } + + void Ref::Assign(const Data *that, Data *other) const + { CheckRef(that); that->ref->vtable->Assign(that->ref, other); } + + void Ref::MakeRef(const Data *that, Data *ref) const + { CheckRef(that); that->ref->vtable->MakeRef(that->ref, ref); } + + void Ref::MakeProxy(Data *that, Data *ref, Path::const_iterator b, Path::const_iterator e) const + { CheckRef(that); that->ref->vtable->MakeProxy(that->ref, ref, b, e); } + + VariantDefines::Type_t Ref::GetType(const Data *that) const + { CheckRef(that); return that->ref->vtable->GetType(that->ref); } + + bool Ref::AsBool(const Data *that) const + { CheckRef(that); return that->ref->vtable->AsBool(that->ref); } + + long double Ref::AsLongDouble(const Data *that) const + { CheckRef(that); return that->ref->vtable->AsLongDouble(that->ref); } + + uintmax_t Ref::AsUnsigned(const Data *that) const + { CheckRef(that); return that->ref->vtable->AsUnsigned(that->ref); } + + intmax_t Ref::AsInt(const Data *that) const + { CheckRef(that); return that->ref->vtable->AsInt(that->ref); } + + std::string Ref::AsString(const Data *that) const + { CheckRef(that); return that->ref->vtable->AsString(that->ref); } + + BlobPtr Ref::AsBlob(Data *that) const + { CheckRef(that); return that->ref->vtable->AsBlob(that->ref); } + + ConstBlobPtr Ref::AsBlobConst(const Data *that) const + { CheckRef(that); return that->ref->vtable->AsBlobConst(that->ref); } + + unsigned Ref::Size(const Data *that) const + { CheckRef(that); return that->ref->vtable->Size(that->ref); } + + bool Ref::Empty(const Data *that) const + { CheckRef(that); return that->ref->vtable->Empty(that->ref); } + + void Ref::Clear(Data *that) const + { CheckRef(that); return that->ref->vtable->Clear(that->ref); } + + Variant::List &Ref::AsList(Data *that) const + { CheckRef(that); return that->ref->vtable->AsList(that->ref); } + + const Variant::List &Ref::AsListConst(const Data *that) const + { CheckRef(that); return that->ref->vtable->AsListConst(that->ref); } + + bool Ref::ContainsIndex(const Data *that, unsigned i) const + { CheckRef(that); return that->ref->vtable->ContainsIndex(that->ref, i); } + + unsigned Ref::Index(const Data *that, Variant v) const + { CheckRef(that); return that->ref->vtable->Index(that->ref, v); } + + void Ref::EraseIndex(Data *that, unsigned i) const + { CheckRef(that); return that->ref->vtable->EraseIndex(that->ref, i); } + + VariantRef Ref::GetRefIndex(Data *that, unsigned i, Variant *def) const + { CheckRef(that); return that->ref->vtable->GetRefIndex(that->ref, i , def); } + + const Variant *Ref::GetConstIndex(const Data *that, unsigned i, bool checked) const + { CheckRef(that); return that->ref->vtable->GetConstIndex(that->ref, i, checked); } + + Variant *Ref::GetIndex(Data *that, unsigned i, bool checked) const + { CheckRef(that); return that->ref->vtable->GetIndex(that->ref, i, checked); } + + void Ref::SetIndex(Data *that, unsigned i, const Data *other) const + { CheckRef(that); that->ref->vtable->SetIndex(that->ref, i, other); } + + Variant::Map &Ref::AsMap(Data *that) const + { CheckRef(that); return that->ref->vtable->AsMap(that->ref); } + + const Variant::Map &Ref::AsMapConst(const Data *that) const + { CheckRef(that); return that->ref->vtable->AsMapConst(that->ref); } + + bool Ref::ContainsKey(const Data *that, const std::string &s) const + { CheckRef(that); return that->ref->vtable->ContainsKey(that->ref, s); } + + void Ref::EraseKey(Data *that, const std::string &key) const + { CheckRef(that); return that->ref->vtable->EraseKey(that->ref, key); } + + VariantRef Ref::GetRefKey(Data *that, const std::string &s, Variant *def) const + { CheckRef(that); return that->ref->vtable->GetRefKey(that->ref, s, def); } + + const Variant *Ref::GetConstKey(const Data *that, const std::string &s, bool checked) const + { CheckRef(that); return that->ref->vtable->GetConstKey(that->ref, s, checked); } + + Variant *Ref::GetKey(Data *that, const std::string &s, bool checked) const + { CheckRef(that); return that->ref->vtable->GetKey(that->ref, s, checked); } + + void Ref::SetKey(Data *that, const std::string &s, const Data *other) const + { CheckRef(that); that->ref->vtable->SetKey(that->ref, s, other); } + + int Ref::Compare(const Data *that, const Data *other) const + { CheckRef(that); return that->ref->vtable->Compare(that->ref, other); } + + void Ref::Incr(Data *that) const + { CheckRef(that); that->ref->vtable->Incr(that->ref); } + + void Ref::Decr(Data *that) const + { CheckRef(that); that->ref->vtable->Decr(that->ref); } + + Variant Ref::Neg(const Data *that) const + { CheckRef(that); return that->ref->vtable->Neg(that->ref); } + + void Ref::Add(Data *that, const Data *other) const + { CheckRef(that); that->ref->vtable->Add(that->ref, other); } + + void Ref::Sub(Data *that, const Data *other) const + { CheckRef(that); that->ref->vtable->Sub(that->ref, other); } + + void Ref::Mul(Data *that, const Data *other) const + { CheckRef(that); that->ref->vtable->Mul(that->ref, other); } + + void Ref::Div(Data *that, const Data *other) const + { CheckRef(that); that->ref->vtable->Div(that->ref, other); } + + void Ref::Rem(Data *that, const Data *other) const + { CheckRef(that); that->ref->vtable->Rem(that->ref, other); } + + void Ref::Destroy(Data *that) const { + VTable::Destroy(that); + that->ref = 0; + } + + void Ref::Destruct(Data *that) const { + Destroy(that); + that->ref_data.reset(); + } + + Variant *Ref::Resolve(Data *that) const + { CheckRef(that); return that->ref->vtable->Resolve(that->ref); } + + const Variant *Ref::ResolveConst(const Data *that) const + { CheckRef(that); return that->ref->vtable->ResolveConst(that->ref); } + + Variant *Ref::ResolveDefault(Data *that, const Data *def) const + { CheckRef(that); return that->ref->vtable->ResolveDefault(that->ref, def); } + + bool Ref::Exists(const Data *that) const { + return (that->ref != 0) && (that->ref_data->valid == true); + } + + void RefInit(Data *that, const Data *other) { + static const Ref ref_vtable; + if (that->vtable) that->vtable->Destroy(that); + that->vtable = &ref_vtable; + // XXX: const cast.. double ICKY! + that->ref = const_cast(other); + that->ref_data = that->ref->vtable->EnsureRef(that->ref); + } + + //-------------------- + // ProxyVTable + //-------------------- + + class Proxy : public VTable { + public: + Proxy() {} + virtual void Copy(const Data *that, Data *other) const; + virtual void Assign(const Data *that, Data *other) const; + virtual void MakeRef(const Data *that, Data *ref) const; + virtual void MakeProxy(Data *that, Data *ref, Path::const_iterator b, Path::const_iterator e) const; + virtual Variant::Type_t GetType(const Data *that) const; + virtual bool AsBool(const Data *that) const; + virtual long double AsLongDouble(const Data *that) const; + virtual uintmax_t AsUnsigned(const Data *that) const; + virtual intmax_t AsInt(const Data *that) const; + virtual std::string AsString(const Data *that) const; + virtual BlobPtr AsBlob(Data *that) const; + virtual ConstBlobPtr AsBlobConst(const Data *that) const; + virtual unsigned Size(const Data *that) const; + virtual bool Empty(const Data *that) const; + virtual void Clear(Data *that) const; + virtual Variant::List &AsList(Data *that) const; + virtual const Variant::List &AsListConst(const Data *that) const; + virtual bool ContainsIndex(const Data *that, unsigned i) const; + virtual unsigned Index(const Data *that, Variant v) const; + virtual void EraseIndex(Data *that, unsigned i) const; + virtual VariantRef GetRefIndex(Data *that, unsigned i, Variant *def) const; + virtual const Variant *GetConstIndex(const Data *that, unsigned i, bool checked) const; + virtual Variant *GetIndex(Data *that, unsigned i, bool checked) const; + virtual void SetIndex(Data *that, unsigned i, const Data *other) const; + virtual Variant::Map &AsMap(Data *that) const; + virtual const Variant::Map &AsMapConst(const Data *that) const; + virtual bool ContainsKey(const Data *that, const std::string &s) const; + virtual void EraseKey(Data *that, const std::string &key) const; + virtual VariantRef GetRefKey(Data *that, const std::string &s, Variant *def) const; + virtual const Variant *GetConstKey(const Data *that, const std::string &s, bool checked) const; + virtual Variant *GetKey(Data *that, const std::string &s, bool checked) const; + virtual void SetKey(Data *that, const std::string &s, const Data *other) const; + virtual int Compare(const Data *that, const Data *other) const; + virtual void Incr(Data *that) const; + virtual void Decr(Data *that) const; + virtual Variant Neg(const Data *that) const; + virtual void Add(Data *that, const Data *other) const; + virtual void Sub(Data *that, const Data *other) const; + virtual void Mul(Data *that, const Data *other) const; + virtual void Div(Data *that, const Data *other) const; + virtual void Rem(Data *that, const Data *other) const; + virtual void Destroy(Data *that) const; + virtual void Destruct(Data *that) const; + virtual Variant *Resolve(Data *that) const; + virtual const Variant *ResolveConst(const Data *that) const; + virtual Variant *ResolveDefault(Data *that, const Data *def) const; + virtual bool Exists(const Data *that) const; + }; + + bool ProxyResolveCheck(const Data *that) { + CheckRef(that); + Data *ref = that->proxy->ref; + const Variant *result = ref->vtable->GetPathConst(ref, that->proxy->path.begin(), + that->proxy->path.end(), false); + if (result) { + const Data *res = VTable::GetData(result); + // XXX: Const cast, ICKY! I don't know how to do this without making all of Data mutable... + res->vtable->MakeRef(res, const_cast(that)); + return true; + } + return false; + } + + void ProxyResolveThrow(const Data *that) { + CheckRef(that); + Data *ref = that->proxy->ref; + const Variant *result = ref->vtable->GetPathConst(ref, that->proxy->path.begin(), + that->proxy->path.end(), true); + const Data *res = VTable::GetData(result); + // XXX: Const cast, ICKY! I don't know how to do this without making all of Data mutable... + res->vtable->MakeRef(res, const_cast(that)); + } + + void ProxyResolveCreate(Data *that) { + CheckRef(that); + Variant tmp_null; + Data *ref = that->proxy->ref; + VariantRef result = ref->vtable->GetPathRef(ref, that->proxy->path.begin(), + that->proxy->path.end(), &tmp_null); + Data *res = VTable::GetData(&result); + res->vtable->MakeRef(res, that); + } + + + void Proxy::Copy(const Data *that, Data *other) const + { ProxyResolveThrow(that); that->vtable->Copy(that, other); } + + void Proxy::Assign(const Data *that, Data *other) const + { ProxyResolveThrow(that); that->vtable->Assign(that, other); } + + void Proxy::MakeRef(const Data *that, Data *ref) const { + CheckRef(that); + ProxyInit(ref, that->proxy->ref, that->proxy->path.begin(), that->proxy->path.end()); + } + + void Proxy::MakeProxy(Data *that, Data *ref, Path::const_iterator b, Path::const_iterator e) const + { + CheckRef(that); + Path newpath = that->proxy->path; + newpath.insert(newpath.end(), b, e); + ProxyInit(ref, that->proxy->ref, newpath.begin(), newpath.end()); + } + + VariantDefines::Type_t Proxy::GetType(const Data *that) const + { ProxyResolveThrow(that); return that->vtable->GetType(that); } + + bool Proxy::AsBool(const Data *that) const + { ProxyResolveThrow(that); return that->vtable->AsBool(that); } + + long double Proxy::AsLongDouble(const Data *that) const + { ProxyResolveThrow(that); return that->vtable->AsLongDouble(that); } + + uintmax_t Proxy::AsUnsigned(const Data *that) const + { ProxyResolveThrow(that); return that->vtable->AsUnsigned(that); } + + intmax_t Proxy::AsInt(const Data *that) const + { ProxyResolveThrow(that); return that->vtable->AsInt(that); } + + std::string Proxy::AsString(const Data *that) const + { ProxyResolveThrow(that); return that->vtable->AsString(that); } + + BlobPtr Proxy::AsBlob(Data *that) const + { ProxyResolveThrow(that); return that->vtable->AsBlob(that); } + + ConstBlobPtr Proxy::AsBlobConst(const Data *that) const + { ProxyResolveThrow(that); return that->vtable->AsBlobConst(that); } + + unsigned Proxy::Size(const Data *that) const + { ProxyResolveThrow(that); return that->vtable->Size(that); } + + bool Proxy::Empty(const Data *that) const + { ProxyResolveThrow(that); return that->vtable->Empty(that); } + + void Proxy::Clear(Data *that) const + { ProxyResolveThrow(that); return that->vtable->Clear(that); } + + Variant::List &Proxy::AsList(Data *that) const + { ProxyResolveCreate(that); return that->vtable->AsList(that); } + + const Variant::List &Proxy::AsListConst(const Data *that) const + { ProxyResolveThrow(that); return that->vtable->AsListConst(that); } + + bool Proxy::ContainsIndex(const Data *that, unsigned i) const + { ProxyResolveThrow(that); return that->vtable->ContainsIndex(that, i); } + + unsigned Proxy::Index(const Data *that, Variant v) const + { ProxyResolveThrow(that); return that->vtable->Index(that, v); } + + void Proxy::EraseIndex(Data *that, unsigned i) const + { ProxyResolveThrow(that); return that->vtable->EraseIndex(that, i); } + + VariantRef Proxy::GetRefIndex(Data *that, unsigned i, Variant *def) const + { + if (def) { + ProxyResolveCreate(that); + return that->vtable->GetRefIndex(that, i, def); + } + if (ProxyResolveCheck(that)) { + return that->vtable->GetRefIndex(that, i, def); + } else { + Path path = that->proxy->path; + path.push_back(i); + return VariantRef(*VTable::GetVar(that->proxy->ref), path); + } + } + + const Variant *Proxy::GetConstIndex(const Data *that, unsigned i, bool checked) const + { ProxyResolveThrow(that); return that->vtable->GetConstIndex(that, i, checked); } + + Variant *Proxy::GetIndex(Data *that, unsigned i, bool checked) const + { + if (ProxyResolveCheck(that)) { + return that->vtable->GetIndex(that, i, checked); + } else if (checked) { + throw std::out_of_range("Variant::List index out of range."); + } else { + return 0; + } + } + + void Proxy::SetIndex(Data *that, unsigned i, const Data *other) const + { ProxyResolveCreate(that); return that->vtable->SetIndex(that, i, other); } + + Variant::Map &Proxy::AsMap(Data *that) const + { ProxyResolveCreate(that); return that->vtable->AsMap(that); } + + const Variant::Map &Proxy::AsMapConst(const Data *that) const + { ProxyResolveThrow(that); return that->vtable->AsMapConst(that); } + + bool Proxy::ContainsKey(const Data *that, const std::string &s) const + { ProxyResolveThrow(that); return that->vtable->ContainsKey(that, s); } + + void Proxy::EraseKey(Data *that, const std::string &key) const + { ProxyResolveThrow(that); return that->vtable->EraseKey(that, key); } + + VariantRef Proxy::GetRefKey(Data *that, const std::string &s, Variant *def) const + { + if (def) { + ProxyResolveCreate(that); + return that->vtable->GetRefKey(that, s, def); + } + if (ProxyResolveCheck(that)) { + return that->vtable->GetRefKey(that, s, def); + } else { + Path path = that->proxy->path; + path.push_back(s); + return VariantRef(*VTable::GetVar(that->proxy->ref), path); + } + } + + const Variant *Proxy::GetConstKey(const Data *that, const std::string &s, bool checked) const + { ProxyResolveThrow(that); return that->vtable->GetConstKey(that, s, checked); } + + Variant *Proxy::GetKey(Data *that, const std::string &s, bool checked) const + { + if (ProxyResolveCheck(that)) { + return that->vtable->GetKey(that, s, checked); + } else if (checked) { + throw KeyError(s); + } else { + return 0; + } + } + + void Proxy::SetKey(Data *that, const std::string &s, const Data *other) const + { ProxyResolveCreate(that); return that->vtable->SetKey(that, s, other); } + + int Proxy::Compare(const Data *that, const Data *other) const + { ProxyResolveThrow(that); return that->vtable->Compare(that, other); } + + void Proxy::Incr(Data *that) const + { ProxyResolveThrow(that); return that->vtable->Incr(that); } + + void Proxy::Decr(Data *that) const + { ProxyResolveThrow(that); return that->vtable->Decr(that); } + + Variant Proxy::Neg(const Data *that) const + { ProxyResolveThrow(that); return that->vtable->Neg(that); } + + void Proxy::Add(Data *that, const Data *other) const + { ProxyResolveThrow(that); return that->vtable->Add(that, other); } + + void Proxy::Sub(Data *that, const Data *other) const + { ProxyResolveThrow(that); return that->vtable->Sub(that, other); } + + void Proxy::Mul(Data *that, const Data *other) const + { ProxyResolveThrow(that); return that->vtable->Mul(that, other); } + + void Proxy::Div(Data *that, const Data *other) const + { ProxyResolveThrow(that); return that->vtable->Div(that, other); } + + void Proxy::Rem(Data *that, const Data *other) const + { ProxyResolveThrow(that); return that->vtable->Rem(that, other); } + + void Proxy::Destroy(Data *that) const { + VTable::Destroy(that); + that->proxy = 0; + } + + void Proxy::Destruct(Data *that) const { + Destroy(that); + that->ref_data.reset(); + } + + Variant *Proxy::Resolve(Data *that) const { + ProxyResolveCreate(that); + return that->vtable->Resolve(that); + } + + const Variant *Proxy::ResolveConst(const Data *that) const { + ProxyResolveThrow(that); + return that->vtable->ResolveConst(that); + } + + Variant *Proxy::ResolveDefault(Data *that, const Data *def) const { + ProxyResolveCreate(that); + return that->vtable->ResolveDefault(that, def); + } + + bool Proxy::Exists(const Data *that) const { + if (!that->ref_data || !that->ref_data->valid) { + return false; + } + Data *ref = that->proxy->ref; + const Variant *result = ref->vtable->GetPathConst(ref, that->proxy->path.begin(), + that->proxy->path.end(), false); + return result != 0; + } + + void ProxyInit(Data *that, Data *ref, Path::const_iterator b, Path::const_iterator e) { + static const Proxy proxy_vtable; + if (that->vtable) that->vtable->Destroy(that); + that->vtable = &proxy_vtable; + that->ref_data = ref->vtable->EnsureRef(ref); + shared_ptr storage(new ProxyStorage(ref, b, e)); + that->proxy = storage.get(); + that->storage = storage; + } + + + //------------------- + + void DefaultInit(Data *that, VariantDefines::Type_t type) { + switch (type) { + case VariantDefines::NullType: + NullInit(that); + break; + case VariantDefines::BoolType: + BoolInit(that, false); + break; + case VariantDefines::IntegerType: + IntegerInit(that, 0); + break; + case VariantDefines::UnsignedType: + UnsignedInit(that, 0u); + break; + case VariantDefines::FloatType: + FloatInit(that, 0.0); + break; + case VariantDefines::StringType: + StringInit(that, ""); + break; + case VariantDefines::ListType: + ListInit(that, Variant::List()); + break; + case VariantDefines::MapType: + MapInit(that, Variant::Map()); + break; + case VariantDefines::BlobType: + BlobInit(that, BlobPtr()); + break; + } + } + + Data::Data() : vtable(NullVTable()) {} + } + + //-------------------- + // Variant + //-------------------- + + Variant::Variant(const RefTag &, const Variant &o) + { + o.vtable->MakeRef(&o, this); + } + + Variant::Variant(const RefTag &, Variant &o, Path::const_iterator b, Path::const_iterator e) + { + o.vtable->MakeProxy(&o, this, b, e); + } + + Variant::~Variant() { + vtable->Destruct(this); + } + + VariantDefines::Type_t Variant::GetType() const + { return vtable->GetType(this); } + + bool Variant::AsBool() const + { return vtable->AsBool(this); } + + long double Variant::AsLongDouble() const + { return vtable->AsLongDouble(this); } + + uintmax_t Variant::AsUnsigned() const + { return vtable->AsUnsigned(this); } + + intmax_t Variant::AsInt() const + { return vtable->AsInt(this); } + + std::string Variant::AsString() const + { return vtable->AsString(this); } + + BlobPtr Variant::AsBlob() + { return vtable->AsBlob(this); } + + ConstBlobPtr Variant::AsBlob() const + { return vtable->AsBlobConst(this); } + + unsigned Variant::Size() const + { return vtable->Size(this); } + + bool Variant::Empty() const + { return vtable->Empty(this); } + + void Variant::Clear() + { vtable->Clear(this); } + + Variant::List &Variant::AsList() + { return vtable->AsList(this); } + + const Variant::List &Variant::AsList() const + { return vtable->AsListConst(this); } + + VariantRef Variant::At(unsigned i) + { return vtable->GetRefIndex(this, i, 0); } + + VariantRef Variant::At(unsigned i, Variant def) + { return vtable->GetRefIndex(this, i, &def); } + + const Variant &Variant::At(unsigned i) const + { return *vtable->GetConstIndex(this, i, true); } + + Variant Variant::Get(unsigned i) const + { return *vtable->GetConstIndex(this, i, true); } + + Variant Variant::Get(unsigned i, Variant def) const { + const Variant *ret = vtable->GetConstIndex(this, i, false); + if (ret) { return *ret; } + else { return def; } + } + + Variant &Variant::Set(unsigned i, Variant v) { + vtable->SetIndex(this, i, &v); + return *this; + } + + Variant &Variant::Append(Variant value) { + vtable->AsList(this).push_back(value); + return *this; + } + + bool Variant::Contains(unsigned i) const + { return vtable->ContainsIndex(this, i); } + + unsigned Variant::Index(Variant v) const + { return vtable->Index(this, v); } + + void Variant::Erase(unsigned i) + { vtable->EraseIndex(this, i); } + + Variant::Map &Variant::AsMap() + { return vtable->AsMap(this); } + + const Variant::Map &Variant::AsMap() const + { return vtable->AsMapConst(this); } + + VariantRef Variant::At(const std::string &s) + { return vtable->GetRefKey(this, s, 0); } + + VariantRef Variant::At(const std::string &s, Variant def) + { return vtable->GetRefKey(this, s, &def); } + + const Variant &Variant::At(const std::string &s) const + { return *vtable->GetConstKey(this, s, true); } + + Variant Variant::Get(const std::string &s) const + { return *vtable->GetConstKey(this, s, true); } + + Variant Variant::Get(const std::string &s, Variant def) const { + const Variant *ret = vtable->GetConstKey(this, s, false); + if (ret) { return *ret; } + else { return def; } + } + + Variant &Variant::Set(const std::string &s, Variant v) { + vtable->SetKey(this, s, &v); + return *this; + } + + bool Variant::Contains(const std::string &s) const + { return vtable->ContainsKey(this, s); } + + void Variant::Erase(const std::string &key) + { vtable->EraseKey(this, key); } + + VariantRef Variant::AtPath(const Path &path) + { return vtable->GetPathRef(this, path.begin(), path.end(), 0); } + + VariantRef Variant::AtPath(const Path &path, Variant def) + { return vtable->GetPathRef(this, path.begin(), path.end(), &def); } + + const Variant &Variant::AtPath(const Path &path) const + { return *vtable->GetPathConst(this, path.begin(), path.end(), true); } + + Variant Variant::GetPath(const Path &path) const + { return *vtable->GetPathConst(this, path.begin(), path.end(), true); } + + Variant Variant::GetPath(const Path &path, Variant def) const { + const Variant *ret = vtable->GetPathConst(this, path.begin(), path.end(), false); + if (ret) { return *ret; } + else { return def; } + } + + Variant &Variant::SetPath(const Path &path, Variant val) { + vtable->SetPath(this, path.begin(), path.end(), &val); + return *this; + } + + Variant &Variant::ErasePath(const Path &path, bool remove_empty) { + vtable->ErasePath(this, path.begin(), path.end(), remove_empty); + return *this; + } + + bool Variant::HasPath(const Path &path) const { + return vtable->GetPathConst(this, path.begin(), path.end(), false) != 0; + } + + void Variant::Merge(Variant other) { + for (ConstMapIterator i(other.MapBegin()), e(other.MapEnd()); i != e; ++i) { + this->Set(i->first, i->second); + } + } + + int Variant::Compare(const Variant &other) const + { return vtable->Compare(this, &other); } + + bool Variant::Comparable(const Variant &other) const + { return vtable->Comparable(this, &other); } + + void Variant::Incr() { + vtable->Incr(this); + } + + void Variant::Decr() { + vtable->Decr(this); + } + + void Variant::Add(const Variant &o){ + vtable->Add(this, &o); + } + + void Variant::Sub(const Variant &o){ + vtable->Sub(this, &o); + } + + void Variant::Mul(const Variant &o){ + vtable->Mul(this, &o); + } + + void Variant::Div(const Variant &o){ + vtable->Div(this, &o); + } + + void Variant::Rem(const Variant &o){ + vtable->Rem(this, &o); + } + + Variant Variant::Neg() const + { return vtable->Neg(this); } + + VariantRef Variant::Ref() { + return VariantRef(*this); + } + + Variant Variant::Copy() const { + Variant result; + vtable->Copy(this, &result); + return result; + } + + Variant &Variant::Resolve() { + return *vtable->Resolve(this); + } + + const Variant &Variant::Resolve() const { + return *vtable->ResolveConst(this); + } + + Variant &Variant::Resolve(const Variant &def) { + return *vtable->ResolveDefault(this, &def); + } + + bool Variant::Exists() const { + return vtable->Exists(this); + } + + void Variant::Assign(const Variant &other) + { other.vtable->Assign(&other, this); } + + void Variant::Assign(VariantDefines::Type_t type) + { DefaultInit(vtable->Resolve(this), type); } + + void Variant::Assign(bool v) + { Internal::BoolInit(vtable->Resolve(this), v); } + + void Variant::Assign(int v) + { Internal::IntegerInit(vtable->Resolve(this), v); } + + void Variant::Assign(unsigned v) + { Internal::UnsignedInit(vtable->Resolve(this), v); } + + void Variant::Assign(long v) + { Internal::IntegerInit(vtable->Resolve(this), v); } + + void Variant::Assign(unsigned long v) + { Internal::UnsignedInit(vtable->Resolve(this), v); } + + void Variant::Assign(long long v) + { Internal::IntegerInit(vtable->Resolve(this), v); } + + void Variant::Assign(unsigned long long v) + { Internal::UnsignedInit(vtable->Resolve(this), v); } + + void Variant::Assign(double v) + { Internal::FloatInit(vtable->Resolve(this), v); } + + void Variant::Assign(long double v) + { Internal::FloatInit(vtable->Resolve(this), v); } + + void Variant::Assign(BlobPtr b) + { Internal::BlobInit(vtable->Resolve(this), b); } + + void Variant::Assign(const std::string &v) + { Internal::StringInit(vtable->Resolve(this), v); } + + void Variant::Assign(const char *v) + { Internal::StringInit(vtable->Resolve(this), v); } + + void Variant::ReassignRef(const Variant &o) { + o.vtable->MakeRef(&o, this); + } +} diff --git a/src/hos_libvariant/src/src/VariantEmitting.cc b/src/hos_libvariant/src/src/VariantEmitting.cc new file mode 100644 index 00000000..5429e0ca --- /dev/null +++ b/src/hos_libvariant/src/src/VariantEmitting.cc @@ -0,0 +1,110 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#include +#include +#include +#include +#include + +namespace libvariant { + + Emitter &operator<<(Emitter &e, const Variant &v) { + switch (v.GetType()) { + case Variant::NullType: + e.EmitNull(); + break; + case Variant::BoolType: + if (v.AsBool()) { + e.EmitTrue(); + } else { + e.EmitFalse(); + } + break; + case Variant::IntegerType: + e.Emit(v.AsInt()); + break; + case Variant::UnsignedType: + e.Emit(v.AsUnsigned()); + break; + case Variant::FloatType: + e.Emit(v.AsDouble()); + break; + case Variant::StringType: + e.Emit(v.AsString()); + break; + case Variant::ListType: + e << v.AsList(); + break; + case Variant::MapType: + e << v.AsMap(); + break; + case Variant::BlobType: + e << v.AsBlob(); + break; + default: + throw UnknownTypeError(v.GetType()); + } + return e; + } + + std::string Serialize(Variant v, SerializeType type, Variant params) { + std::ostringstream oss; + Serialize(oss.rdbuf(), v, type, params); + return oss.str(); + + } + + void Serialize(const std::string &filename, Variant v, SerializeType type, + Variant params) { + Emitter emitter = CreateEmitter(CreateEmitterOutput(filename.c_str()), type, params); + emitter << v; + emitter.Close(); + } + + void Serialize(FILE *f, Variant v, SerializeType type, + Variant params) { + Emitter emitter = CreateEmitter(CreateEmitterOutput(f), type, params); + emitter << v; + emitter.Close(); + } + + void Serialize(std::streambuf *sb, Variant v, SerializeType type, + Variant params) { + Emitter emitter = CreateEmitter(CreateEmitterOutput(sb), type, params); + emitter << v; + emitter.Close(); + + } + + unsigned Serialize(void *ptr, unsigned len, Variant v, SerializeType type, + Variant params) { + unsigned out_len = 0; + Emitter emitter = CreateEmitter(CreateEmitterOutput(ptr, len, &out_len), type, params); + emitter << v; + emitter.Close(); + return out_len; + } +} + +void VariantPrint(const libvariant::Variant v) { + libvariant::SerializeJSON(stderr, v, true); + fprintf(stderr, "\n"); +} diff --git a/src/hos_libvariant/src/src/VariantParsing.cc b/src/hos_libvariant/src/src/VariantParsing.cc new file mode 100644 index 00000000..4bb32f07 --- /dev/null +++ b/src/hos_libvariant/src/src/VariantParsing.cc @@ -0,0 +1,345 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#include +#include +#include +#include +#include +#include + +#if 0 +#include +#include +#define ANCHOR (anchor ? anchor : "") +#define TAG (tag ? tag : "") +#define DBTRACE(args) do {\ + for (int i = Level(); i > 0; --i) { std::cerr << ". "; }\ + std::cerr << args << std::endl;\ +} while (false) +#else +#define DBTRACE(args) +#endif + +namespace libvariant { + + typedef std::map AnchorMap; + + class ParserState { + public: + + ParserState() + {} + + void Anchor(const char *anchor, Variant v) { + if (anchor) { anchors.insert(std::make_pair(std::string(anchor), v)); } + } + + Variant Anchor(const char *anchor) { + return anchors.at(anchor); + } + + AnchorMap anchors; + Variant result; + }; + + class VariantBaseParserActions : public ParserActions { + public: + VariantBaseParserActions(ParserState *s, VariantBaseParserActions *b) + : done(false), seen_begin_document(false), state(s), base(b) + {} + + virtual void BeginDocument(ParserImpl *p) { + DBTRACE("BeginDocument"); + seen_begin_document = true; + } + virtual void EndDocument(ParserImpl *p) { + DBTRACE("EndDocument"); + Finish(p); + } + + virtual void BeginMap(ParserImpl *p, int length, const char *anchor, const char *tag); + virtual void BeginList(ParserImpl *p, int length, const char *anchor, const char *tag); + + virtual void Alias(ParserImpl *p, const char *anchor) { + DBTRACE("Alias (" << ANCHOR << ")"); + SetValue(p, state->Anchor(anchor), 0); + } + virtual void Scalar(ParserImpl *p, double v, const char *anchor, const char *tag) { + DBTRACE("Scalar(" << v << ", " << ANCHOR << ", " << TAG << ")"); + SetValue(p, v, anchor); + } + virtual void Scalar(ParserImpl *p, const char *str, unsigned length, const char *anchor, const char *tag) { + DBTRACE("Scalar(" << std::string(str, length) << ", " << ANCHOR << ", " << TAG << ")"); + SetValue(p, std::string(str, length), anchor); + } + virtual void Scalar(ParserImpl *p, bool v, const char *anchor, const char *tag) { + DBTRACE("Scalar(" << v << ", " << ANCHOR << ", " << TAG << ")"); + SetValue(p, v, anchor); + } + virtual void Null(ParserImpl *p, const char *anchor, const char *tag) { + DBTRACE("Scalar( null, " << ANCHOR << ", " << TAG << ")"); + SetValue(p, Variant::NullType, anchor); + } + virtual void Scalar(ParserImpl *p, intmax_t v, const char *anchor, const char *tag) { + DBTRACE("Scalar(" << v << ", " << ANCHOR << ", " << TAG << ")"); + SetValue(p, v, anchor); + } + virtual void Scalar(ParserImpl *p, uintmax_t v, const char *anchor, const char *tag) { + DBTRACE("Scalar(" << v << ", " << ANCHOR << ", " << TAG << ")"); + SetValue(p, v, anchor); + } + virtual void Scalar(ParserImpl *p, BlobPtr b, const char *anchor, const char *tag) { + DBTRACE("Scalar(blob, " << ANCHOR << ", " << TAG << ")"); + SetValue(p, b, anchor); + } + + virtual void SetValue(ParserImpl *p, Variant v, const char *anchor) { + state->Anchor(anchor, v); + result = v; + if (anchor) { this->anchor = anchor; } + if (!seen_begin_document) { + Finish(p); + } + } + + void Finish(ParserImpl *p) { + if (base) { + base->SetValue(p, result, (anchor.empty() ? 0 : anchor.c_str())); + } else { + state->result = result; + } + done = true; + p->PopAction(); + } + + int Level() { + if (base) { return base->Level() + 1; } + else { return 1; } + } + + Variant result; + bool done; + bool seen_begin_document; + ParserState *state; + VariantBaseParserActions *base; + std::string anchor; + }; + + class VariantMapParserActions : public VariantBaseParserActions { + public: + VariantMapParserActions(ParserState *s, VariantBaseParserActions *b) + : VariantBaseParserActions(s, b), expect_key(true) + { + result = Variant::MapType; + } + + virtual void EndMap(ParserImpl *p) { + DBTRACE("EndMap"); + Finish(p); + } + + virtual void SetValue(ParserImpl *p, Variant v, const char *anchor) { + if (expect_key) { + key = v.AsString(); + expect_key = false; + } else { + state->Anchor(anchor, v); + result[key] = v; + expect_key = true; + } + } + + bool expect_key; + std::string key; + }; + + void VariantBaseParserActions::BeginMap(ParserImpl *p, int length, const char *anchor, const char *tag) { + DBTRACE("BeginMap(" << ANCHOR << ", " << TAG << ")"); + shared_ptr actions(new VariantMapParserActions(state, this)); + if (anchor) { actions->anchor = anchor; } + p->PushAction(actions); + } + + class VariantListParserActions : public VariantBaseParserActions { + public: + VariantListParserActions(ParserState *s, VariantBaseParserActions *b) + : VariantBaseParserActions(s, b) + { + result = Variant::ListType; + } + + virtual void EndList(ParserImpl *p) { + DBTRACE("EndList"); + Finish(p); + } + + virtual void SetValue(ParserImpl *p, Variant v, const char *anchor) { + state->Anchor(anchor, v); + result.Append(v); + } + + }; + + void VariantBaseParserActions::BeginList(ParserImpl *p, int length, const char *anchor, const char *tag) { + DBTRACE("BeginList(" << ANCHOR << ", " << TAG << ")"); + shared_ptr actions(new VariantListParserActions(state, this)); + if (anchor) { actions->anchor = anchor; } + p->PushAction(actions); + } + + Variant ParseVariant(Parser &p) { + ParserState state; + shared_ptr actions(new VariantBaseParserActions(&state, 0)); + p.PushAction(actions); + while (p.Run() == 0 && !actions->done); + return state.result; + } + + Variant Deserialize(const std::string &str, SerializeType type) { + return Deserialize(str.c_str(), str.length(), type); + } + + Variant Deserialize(const char *str, SerializeType type) { + return Deserialize(str, strlen(str), type); + } + + Variant Deserialize(const void *ptr, unsigned len, SerializeType type) { + Parser parser = CreateParser(CreateParserInput(ptr, len), type); + return ParseVariant(parser); + } + + Variant DeserializeFile(const char *filename, SerializeType type) { + Parser parser = CreateParser(CreateParserInputFile(filename), type); + return ParseVariant(parser); + } + + Variant DeserializeFile(FILE *f, SerializeType type) { + Parser parser = CreateParser(CreateParserInputFile(f), type); + return ParseVariant(parser); + } + + Variant DeserializeFile(std::streambuf *sb, SerializeType type) { + Parser parser = CreateParser(CreateParserInputFile(sb), type); + return ParseVariant(parser); + } + + Variant DeserializeGuess(const std::string &str) { + return DeserializeGuess(str.c_str(), str.length()); + } + Variant DeserializeGuess(const char *str) { + return DeserializeGuess(str, strlen(str)); + } + Variant DeserializeGuess(const void *ptr, unsigned len) { + Parser parser = CreateParserGuess(CreateParserInput(ptr, len) ); + return ParseVariant(parser); + } + Variant DeserializeGuessFile(const char *filename) { + Parser parser = CreateParserGuess(CreateParserInputFile(filename)); + return ParseVariant(parser); + } + Variant DeserializeGuessFile(FILE *f) { + Parser parser = CreateParserGuess(CreateParserInputFile(f)); + return ParseVariant(parser); + } + Variant DeserializeGuessFile(std::streambuf *sb) { + Parser parser = CreateParserGuess(CreateParserInputFile(sb)); + return ParseVariant(parser); + } + + LoadAllIterator DeserializeAll(const std::string &str, SerializeType type) { + return DeserializeAll(str.c_str(), str.length(), type); + } + + LoadAllIterator DeserializeAll(const char *str, SerializeType type) { + return DeserializeAll(str, strlen(str), type); + } + + LoadAllIterator DeserializeAll(const void *ptr, unsigned len, SerializeType type) { + Parser parser = CreateParser(CreateParserInput(ptr, len), type); + return LoadAllIterator(parser); + } + + LoadAllIterator DeserializeAllFile(const char *filename, SerializeType type) { + Parser parser = CreateParser(CreateParserInputFile(filename), type); + return LoadAllIterator(parser); + } + + LoadAllIterator DeserializeAllFile(FILE *f, SerializeType type) { + Parser parser = CreateParser(CreateParserInputFile(f), type); + return LoadAllIterator(parser); + } + + LoadAllIterator DeserializeAllFile(std::streambuf *sb, SerializeType type) { + Parser parser = CreateParser(CreateParserInputFile(sb), type); + return LoadAllIterator(parser); + } + + + class LoadAllIterator::Impl { + public: + Impl(Parser p) : parser(p) {} + Parser parser; + }; + + struct LoadAllIterator::Value { + Value(Variant v_) :v(v_) {} + Variant v; + shared_ptr next; + }; + + LoadAllIterator::LoadAllIterator() + {} + + LoadAllIterator::LoadAllIterator(Parser &parser) + : impl(new Impl(parser)) + { + Next(); + } + + Variant &LoadAllIterator::Get() { + if (!value) { throw std::out_of_range("LoadAllIterator: Trying to reach past the end."); } + return value->v; + } + + void LoadAllIterator::Next() { + if (!value) { + if (!impl->parser.Done()) { + value = shared_ptr(new Value(ParseVariant(impl->parser))); + } + } else if (value->next) { + value = value->next; + } else { + if (!impl->parser.Done()) { + value->next = shared_ptr(new Value(ParseVariant(impl->parser))); + if (impl->parser.Done() && value->next->v.IsNull()) { + value->next.reset(); + } + } + value = value->next; + } + } + bool LoadAllIterator::operator==(const LoadAllIterator &that) const { + if (value && that.value) { + return value == that.value; + } + return (!value && !that.value); + } +} diff --git a/src/hos_libvariant/src/src/XMLPLISTDefs.h b/src/hos_libvariant/src/src/XMLPLISTDefs.h new file mode 100644 index 00000000..ef7ebe45 --- /dev/null +++ b/src/hos_libvariant/src/src/XMLPLISTDefs.h @@ -0,0 +1,37 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_XMLPLISTDEFS_H +#define VARIANT_XMLPLISTDEFS_H +#pragma once + +#define MAP_NAME "dict" +#define STRING_NAME "string" +#define TRUE_NAME "true" +#define FALSE_NAME "false" +#define INTEGER_NAME "integer" +#define FLOAT_NAME "real" +#define ROOT_NAME "plist" +#define LIST_NAME "array" +#define NULL_NAME "null" +#define KEY_NAME "key" +#define BLOB_NAME "data" + +#endif diff --git a/src/hos_libvariant/src/src/XMLPLISTEmitter.cc b/src/hos_libvariant/src/src/XMLPLISTEmitter.cc new file mode 100644 index 00000000..015b6ed6 --- /dev/null +++ b/src/hos_libvariant/src/src/XMLPLISTEmitter.cc @@ -0,0 +1,217 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ + +#include "XMLPLISTEmitter.h" +#include +#include +#include +#include +#include "XMLPLISTDefs.h" +#include "Base64.h" + +namespace libvariant { + + int XMLPLISTEmitterImpl::DoWrite(void *ctx, const char *buffer, int len) { + XMLPLISTEmitterImpl *impl = (XMLPLISTEmitterImpl*)ctx; + return impl->output->Write(buffer, len); + } + + int XMLPLISTEmitterImpl::DoClose(void *ctx) { + XMLPLISTEmitterImpl *impl = (XMLPLISTEmitterImpl*)ctx; + impl->output->Flush(); + return 0; + } + + XMLPLISTEmitterImpl::XMLPLISTEmitterImpl(shared_ptr out, Variant params) + : output(out), pretty(false), indent(4), + precision(std::numeric_limits::digits10+2), closed(false) + { + if (params.IsMap()) { + params.GetInto(pretty, "pretty", pretty); + params.GetInto(indent, "indent", indent); + params.GetInto(precision, "precision", precision); + } + xmlOutputBufferPtr xmloutput = xmlOutputBufferCreateIO(&XMLPLISTEmitterImpl::DoWrite, + &XMLPLISTEmitterImpl::DoClose, + (void*)this, 0); + if (xmloutput == 0) { + HandleError("xmlOutputBufferCreateIO"); + } + writer = xmlNewTextWriter(xmloutput); + if (writer == 0) { + xmlOutputBufferClose(xmloutput); + HandleError("xmlNewTextWriter"); + } + UpdateParams(); + if (xmlTextWriterStartDocument(writer, 0, 0, "yes") < 0) { + xmlFreeTextWriter(writer); + writer = 0; + HandleError("xmlTextWriterStartDocument"); + } + state.push_back(NONE); + } + + XMLPLISTEmitterImpl::~XMLPLISTEmitterImpl() { + if (!closed) { + xmlTextWriterEndDocument(writer); + xmlTextWriterFlush(writer); + closed = true; + } + xmlFreeTextWriter(writer); + writer = 0; + } + + void XMLPLISTEmitterImpl::BeginDocument() { + StartElement(ROOT_NAME); + } + + void XMLPLISTEmitterImpl::EndDocument() { + CloseElement(); + } + + void XMLPLISTEmitterImpl::BeginMap(int) { + StartElement(MAP_NAME); + state.push_back(EXPECT_MAP_KEY); + } + + void XMLPLISTEmitterImpl::EndMap() { + CloseElement(); + state.pop_back(); + } + + void XMLPLISTEmitterImpl::BeginList(int) { + StartElement(LIST_NAME); + state.push_back(IN_LIST); + } + + void XMLPLISTEmitterImpl::EndList() { + CloseElement(); + state.pop_back(); + } + + void XMLPLISTEmitterImpl::EmitNull() { + StartElement(NULL_NAME); + CloseElement(); + } + + void XMLPLISTEmitterImpl::EmitTrue() { + StartElement(TRUE_NAME); + CloseElement(); + } + + void XMLPLISTEmitterImpl::EmitFalse() { + StartElement(FALSE_NAME); + CloseElement(); + } + + void XMLPLISTEmitterImpl::Emit(const char *v) { + if (state.back() == EXPECT_MAP_KEY) { + StartElement(KEY_NAME, false); + WriteText(v); + CloseElement(); + } else { + StartElement(STRING_NAME); + WriteText(v); + CloseElement(); + } + } + + void XMLPLISTEmitterImpl::Emit(intmax_t v) { + StartElement(INTEGER_NAME); + std::ostringstream oss; + oss << v; + WriteText(oss.str().c_str()); + CloseElement(); + } + + void XMLPLISTEmitterImpl::Emit(uintmax_t v) { + StartElement(INTEGER_NAME); + std::ostringstream oss; + oss << v; + WriteText(oss.str().c_str()); + CloseElement(); + } + + void XMLPLISTEmitterImpl::Emit(double v) { + StartElement(FLOAT_NAME); + std::ostringstream oss; + oss << std::setprecision(precision) << std::showpoint << v; + WriteText(oss.str().c_str()); + CloseElement(); + } + + void XMLPLISTEmitterImpl::Emit(ConstBlobPtr b) { + StartElement(BLOB_NAME); + std::vector buf(Base64EncodeSize(b->GetTotalLength())); + Base64Encode(&buf[0], b->GetIOVec(), b->GetNumBuffers()); + WriteText(&buf[0]); + CloseElement(); + } + + void XMLPLISTEmitterImpl::Flush() { + CheckClosed(); + if (xmlTextWriterFlush(writer) < 0) { + HandleError("xmlTextWriterFlush"); + } + output->Flush(); + } + + void XMLPLISTEmitterImpl::Close() { + if (!closed) { + if (xmlTextWriterEndDocument(writer) < 0) { + HandleError("xmlTextWriterEndDocument"); + } + Flush(); + closed = true; + } + } + + Variant XMLPLISTEmitterImpl::GetParam(const std::string &key) { + if (key == "pretty") { return pretty; } + if (key == "indent") { return indent; } + if (key == "precision") { return precision; } + return Variant::NullType; + } + + Variant XMLPLISTEmitterImpl::GetParams() { + Variant ret; + ret["pretty"] = pretty; + ret["indent"] = indent; + ret["precision"] = precision; + return ret; + } + + void XMLPLISTEmitterImpl::SetParam(const std::string &key, Variant value) { + if (key == "pretty") { pretty = value.AsBool(); } + else if (key == "indent") { indent = value.AsUnsigned(); } + else if (key == "precision") { precision = value.AsUnsigned(); } + UpdateParams(); + } + + void XMLPLISTEmitterImpl::UpdateParams() { + if (pretty) { + xmlTextWriterSetIndent(writer, indent); + } else { + xmlTextWriterSetIndent(writer, 0); + } + } + +} diff --git a/src/hos_libvariant/src/src/XMLPLISTEmitter.h b/src/hos_libvariant/src/src/XMLPLISTEmitter.h new file mode 100644 index 00000000..217d2711 --- /dev/null +++ b/src/hos_libvariant/src/src/XMLPLISTEmitter.h @@ -0,0 +1,133 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief An emitter for the XMLPLIST subset that Variant supports. + * Depends on libxml2. + */ +#ifndef VARIANT_XMLPLISTEMITTER_H +#define VARIANT_XMLPLISTEMITTER_H + +#pragma once +#include "../../src/include/Variant/Emitter.h" +#include +#include +#include + +namespace libvariant { + + /** + * Supported params are: + * + * "pretty": true|false + * "indent": integer (amount to indent for pretty) + * "precision": number of digits for a float + */ + class XMLPLISTEmitterImpl : public EmitterImpl { + enum State { + NONE, + EXPECT_MAP_KEY, + EXPECT_MAP_VALUE, + IN_LIST + }; + public: + + XMLPLISTEmitterImpl(shared_ptr out, Variant params); + ~XMLPLISTEmitterImpl(); + + virtual void BeginDocument(); + virtual void EndDocument(); + virtual void BeginMap(int length); + virtual void EndMap(); + virtual void BeginList(int length); + virtual void EndList(); + + virtual void EmitNull(); + virtual void EmitTrue(); + virtual void EmitFalse(); + virtual void Emit(const char *v); + virtual void Emit(intmax_t v); + virtual void Emit(uintmax_t v); + virtual void Emit(double v); + virtual void Emit(ConstBlobPtr b); + + virtual void Flush(); + virtual void Close(); + + virtual Variant GetParam(const std::string &key); + virtual Variant GetParams(); + virtual void SetParam(const std::string &key, Variant value); + private: + static int DoWrite(void *ctx, const char *buffer, int len); + static int DoClose(void *ctx); + + void HandleError(const char *fnname) { + xmlErrorPtr error = xmlGetLastError(); + if (error) { + throw std::runtime_error(error->message); + } else { + throw std::runtime_error(fnname); + } + } + + void CheckClosed() { + if (closed) { throw std::runtime_error("Cannot operate on a closed XMLPLISTEmitter."); } + } + + void CheckMapKey(bool complex_type) { + if (state.back() == EXPECT_MAP_VALUE) { + state.back() = EXPECT_MAP_KEY; + } else if (state.back() == EXPECT_MAP_KEY) { + if (complex_type) { + throw std::runtime_error("XMLPLISTEmitter does not support non trivial types as keys"); + } + state.back() = EXPECT_MAP_VALUE; + } + } + + void StartElement(const char *name, bool complex_type=true) { + CheckClosed(); + if (xmlTextWriterStartElement(writer, (const xmlChar*)name) < 0) { + HandleError("xmlTextWriterStartElement"); + } + CheckMapKey(complex_type); + } + + void CloseElement() { + CheckClosed(); + if (xmlTextWriterEndElement(writer) < 0) { + HandleError("xmlTextWriterEndElement"); + } + } + + void WriteText(const char *ptr) { + if (xmlTextWriterWriteString(writer, (const xmlChar*)ptr) < 0) { + HandleError("xmlTextWriterWriteString"); + } + } + + void UpdateParams(); + xmlTextWriterPtr writer; + shared_ptr output; + bool pretty; + unsigned indent; + unsigned precision; + bool closed; + std::deque state; + }; +} +#endif diff --git a/src/hos_libvariant/src/src/XMLPLISTParser.cc b/src/hos_libvariant/src/src/XMLPLISTParser.cc new file mode 100644 index 00000000..cfbaf335 --- /dev/null +++ b/src/hos_libvariant/src/src/XMLPLISTParser.cc @@ -0,0 +1,423 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#include "XMLPLISTParser.h" +#include +#include +#include +#include +#include +#include "XMLPLISTDefs.h" +#include "Base64.h" + +namespace libvariant { + + XMLPLISTParserImpl::State_t XMLPLISTParserImpl::StringToNode(const char *name) { + if (!name) { + return StringNode; + } else if (strcasecmp(name, STRING_NAME) == 0) { + return StringNode; + } else if (strcasecmp(name, TRUE_NAME) == 0) { + return TrueNode; + } else if (strcasecmp(name, ROOT_NAME) == 0) { + return RootNode; + } else if (strcasecmp(name, LIST_NAME) == 0) { + return ListNode; + } else if (strcasecmp(name, FALSE_NAME) == 0) { + return FalseNode; + } else if (strcasecmp(name, INTEGER_NAME) == 0) { + return IntegerNode; + } else if (strcasecmp(name, FLOAT_NAME) == 0) { + return FloatNode; + } else if (strcasecmp(name, NULL_NAME) == 0) { + return NullNode; + } else if (strcasecmp(name, MAP_NAME) == 0) { + return MapNode; + } else if (strcasecmp(name, KEY_NAME) == 0) { + return KeyNode; + } else if (strcasecmp(name, BLOB_NAME) == 0) { + return BlobNode; + } else { + return StringNode; + } + } + + int XMLPLISTParserImpl::Run() { + while (!action_stack.empty()) { + if (closed) { return 1; } + bool loop = true; + switch (statestack.back()) { + case StartState: + statestack.back() = EndState; + break; + case EndState: + return 1; + case EmptyMapNode: + statestack.pop_back(); + TopAction()->EndMap(this); + return 0; + case EmptyListNode: + statestack.pop_back(); + TopAction()->EndList(this); + return 0; + case RootNode: + case MapNode: + case ListNode: + break; + default: + err = true; + errorstr = "libvariant XML PLIST parser in an inconsistent state"; + throw std::runtime_error(errorstr); + } + while (loop) { + int ret = xmlTextReaderRead(reader); + if (ret == 1) { + int node_type = xmlTextReaderNodeType(reader); + const char *name = (const char*)xmlTextReaderConstName(reader); + switch (node_type) { + case XML_READER_TYPE_ELEMENT: + loop = BeginElement(TopAction(), StringToNode(name)); + break; + case XML_READER_TYPE_END_ELEMENT: + loop = EndElement(TopAction(), StringToNode(name)); + break; + case XML_READER_TYPE_TEXT: + loop = ProcessText(TopAction()); + break; + case XML_READER_TYPE_END_ENTITY: + case XML_READER_TYPE_ATTRIBUTE: + case XML_READER_TYPE_CDATA: + case XML_READER_TYPE_ENTITY_REFERENCE: + case XML_READER_TYPE_ENTITY: + case XML_READER_TYPE_PROCESSING_INSTRUCTION: + case XML_READER_TYPE_COMMENT: + case XML_READER_TYPE_DOCUMENT: + case XML_READER_TYPE_DOCUMENT_TYPE: + case XML_READER_TYPE_DOCUMENT_FRAGMENT: + case XML_READER_TYPE_NOTATION: + case XML_READER_TYPE_WHITESPACE: + case XML_READER_TYPE_SIGNIFICANT_WHITESPACE: + case XML_READER_TYPE_XML_DECLARATION: + case XML_READER_TYPE_NONE: + default: + break; + } + } else if (ret == 0) { + if (statestack.back() != EndState) { + err = true; + errorstr = "libvariant XML PLIST parser in inconsistent state"; + throw std::runtime_error(errorstr); + } + return 1; + } else { + HandleError("xmlTextReaderRead"); + } + } + } + return 0; + } + + bool XMLPLISTParserImpl::BeginElement(ParserActions *action, State_t nodetype) { + bool empty_node = xmlTextReaderIsEmptyElement(reader) != 0; + switch (nodetype) { + case NullNode: + if (!empty_node) { statestack.push_back(nodetype); } + action->Null(this, 0, 0); + return !empty_node; + case RootNode: + statestack.push_back(nodetype); + action->BeginDocument(this); + return !empty_node; + case TrueNode: + if (!empty_node) { statestack.push_back(nodetype); } + action->Scalar(this, true, 0, 0); + return !empty_node; + case FalseNode: + if (!empty_node) { statestack.push_back(nodetype); } + action->Scalar(this, false, 0, 0); + return !empty_node; + case IntegerNode: + if (!empty_node) { + statestack.push_back(nodetype); + empty = true; + } else { + err = true; + errorstr = "libvariant XML PLIST does not allow empty interger elements"; + throw std::runtime_error(errorstr); + } + return true; + case FloatNode: + if (!empty_node) { + statestack.push_back(nodetype); + empty = true; + } else { + err = true; + errorstr = "libvariant XML PLIST does not allow empty real elements"; + throw std::runtime_error(errorstr); + } + return true; + case StringNode: + if (!empty_node) { + statestack.push_back(nodetype); + empty = true; + } else { + err = true; + errorstr = "libvariant XML PLIST does not allow empty string elements"; + throw std::runtime_error(errorstr); + } + return true; + case BlobNode: + if (!empty_node) { + statestack.push_back(nodetype); + empty = true; + } else { + err = true; + errorstr = "libvariant XML PLIST does not allow empty data elements"; + throw std::runtime_error(errorstr); + } + return true; + case MapNode: + if (empty_node) { statestack.push_back(EmptyMapNode); } + else { statestack.push_back(nodetype); } + action->BeginMap(this, -1, 0, 0); + return false; + case KeyNode: + { + if (empty_node) { + err = true; + errorstr = "libvariant XML PLIST does not allow empty key elements"; + throw std::runtime_error(errorstr); + } + statestack.push_back(nodetype); + empty = true; + } + return true; + case ListNode: + if (empty_node) { statestack.push_back(EmptyListNode); } + else { statestack.push_back(nodetype); } + action->BeginList(this, -1, 0, 0); + return false; + default: + err = true; + errorstr = "Invalid libvariant XML PLIST parser state"; + throw std::runtime_error(errorstr); + } + } + + bool XMLPLISTParserImpl::ProcessText(ParserActions *action) { + switch (statestack.back()) { + case NullNode: + case RootNode: + case TrueNode: + case FalseNode: + case MapNode: + case ListNode: + return true; + case IntegerNode: + { + empty = false; + const char *value = (const char*)xmlTextReaderConstValue(reader); + intmax_t val; + val = strtoll(value, 0, 0); + if (val == LLONG_MAX && errno == ERANGE) { + uintmax_t v; + v = strtoull(value, 0, 0); + action->Scalar(this, v, 0, 0); + } else { + action->Scalar(this, val, 0, 0); + } + } + return true; + case FloatNode: + { + empty = false; + const char *value = (const char*)xmlTextReaderConstValue(reader); + double val = strtod(value, 0); + action->Scalar(this, val, 0, 0); + } + return true; + case StringNode: + { + empty = false; + const char *value = (const char*)xmlTextReaderConstValue(reader); + action->Scalar(this, value, strlen(value), 0, 0); + } + return true; + case BlobNode: + { + empty = false; + const char *value = (const char*)xmlTextReaderConstValue(reader); + unsigned length = strlen(value); + void *data = 0; + if (posix_memalign(&data, 64, Base64DecodeSize(length)) != 0) { + err = true; + errorstr = "memory allocation failure"; + throw std::bad_alloc(); + } + unsigned len = Base64Decode(data, value, length); + action->Scalar(this, Blob::CreateFree(data, len), 0, 0); + } + return true; + case KeyNode: + { + empty = false; + const char *value = (const char*)xmlTextReaderConstValue(reader); + action->Scalar(this, value, strlen(value), 0, 0); + } + return true; + default: + err = true; + errorstr = "Invalid libvariant XML PLIST parser state"; + throw std::runtime_error(errorstr); + } + + } + + bool XMLPLISTParserImpl::EndElement(ParserActions *action, State_t nodetype) { + if (statestack.back() != nodetype) { + err = true; + errorstr = "libvariant XML PLIST parser in inconsistent state"; + throw std::runtime_error(errorstr); + } + statestack.pop_back(); + switch (nodetype) { + case NullNode: + case TrueNode: + case FalseNode: + return false; + case IntegerNode: + case FloatNode: + if (empty) { + err = true; + errorstr = "libvariant XML PLIST parser cannot have empty numeric nodes"; + throw std::runtime_error(errorstr); + } + return false; + case BlobNode: + if (empty) { + err = true; + errorstr = "libvariant XML PLIST parser cannot have empty data nodes"; + throw std::runtime_error(errorstr); + } + return false; + case StringNode: + case KeyNode: + if (empty) { action->Scalar(this, "", 0, 0, 0); } + return false; + case RootNode: + action->EndDocument(this); + return false; + case MapNode: + action->EndMap(this); + return false; + case ListNode: + action->EndList(this); + return false; + default: + err = true; + errorstr = "Invalid libvariant XML PLIST parser state"; + throw std::runtime_error(errorstr); + } + } + + void XMLPLISTParserImpl::Close() { + if (!closed) { + closed = true; + xmlTextReaderClose(reader); + } + } + + void XMLPLISTParserImpl::HandleError(const char *fnname) { + xmlErrorPtr error = xmlGetLastError(); + err = true; + if (error) { + errorstr = error->message; + throw std::runtime_error(error->message); + } else { + errorstr = fnname; + throw std::runtime_error(fnname); + } + } + + int XMLPLISTParserImpl::do_read(void *ctx, char *buffer, int len) { + XMLPLISTParserImpl *impl = (XMLPLISTParserImpl*)ctx; + unsigned l = len; + const void *ptr = impl->input->GetPtr(l); + if (!ptr) { return 0; } + l = std::min(len, l); + memcpy(buffer, ptr, l); + impl->input->Release(l); + return l; + } + + int XMLPLISTParserImpl::do_close(void *ctx) { + XMLPLISTParserImpl *impl = (XMLPLISTParserImpl*)ctx; + impl->Close(); + return 0; + } + + XMLPLISTParserImpl::XMLPLISTParserImpl(shared_ptr in) + : input(in), closed(false), err(false) + { + reader = xmlReaderForIO(do_read, do_close, this, 0, 0, + XML_PARSE_NOENT|XML_PARSE_NOCDATA); + if (!reader) { + HandleError("xmlReaderForIO"); + } + statestack.push_back(StartState); + } + + XMLPLISTParserImpl::~XMLPLISTParserImpl() { + Close(); + xmlFreeTextReader(reader); + reader = 0; + } + + bool XMLPLISTParserImpl::Done() const { + return closed; + } + + bool XMLPLISTParserImpl::Error() const { + return err; + } + + bool XMLPLISTParserImpl::Ok() const { + return !closed && !err; + } + + std::string XMLPLISTParserImpl::ErrorStr() const { + return errorstr; + } + + void XMLPLISTParserImpl::Reset() { + Close(); + xmlFreeTextReader(reader); + reader = 0; + reader = xmlReaderForIO(do_read, do_close, this, 0, 0, + XML_PARSE_NOENT|XML_PARSE_NOCDATA); + if (!reader) { + HandleError("xmlReaderForIO"); + } + statestack.push_back(StartState); + closed = false; + err = false; + + } +} diff --git a/src/hos_libvariant/src/src/XMLPLISTParser.h b/src/hos_libvariant/src/src/XMLPLISTParser.h new file mode 100644 index 00000000..ade5e376 --- /dev/null +++ b/src/hos_libvariant/src/src/XMLPLISTParser.h @@ -0,0 +1,81 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#ifndef VARIANT_XMLPLISTPARSER_H +#define VARIANT_XMLPLISTPARSER_H + +#pragma once +#include +#include +#include "../../src/include/Variant/Parser.h" +#include "../../src/include/Variant/ParserInput.h" +#include "../../src/include/Variant/SharedPtr.h" + + +namespace libvariant { + + class XMLPLISTParserImpl : public ParserImpl { + enum State_t { + StartState, + NullNode, + RootNode, + TrueNode, + FalseNode, + IntegerNode, + FloatNode, + StringNode, + BlobNode, + MapNode, + EmptyMapNode, + KeyNode, + ListNode, + EmptyListNode, + EndState + }; + public: + XMLPLISTParserImpl(shared_ptr in); + virtual ~XMLPLISTParserImpl(); + virtual int Run(); + virtual bool Done() const; + virtual bool Error() const; + virtual bool Ok() const; + virtual std::string ErrorStr() const; + virtual void Reset(); + private: + bool BeginElement(ParserActions *action, State_t nodetype); + bool ProcessText(ParserActions *action); + bool EndElement(ParserActions *action, State_t nodetype); + void Close(); + void HandleError(const char *fnname); + + static int do_read(void *ctx, char *buffer, int len); + static int do_close(void *ctx); + static State_t StringToNode(const char *name); + + std::deque statestack; + xmlTextReaderPtr reader; + shared_ptr input; + bool closed; + bool empty; + bool err; + std::string errorstr; + }; +} +#endif diff --git a/src/hos_libvariant/src/src/YAMLEmitter.cc b/src/hos_libvariant/src/src/YAMLEmitter.cc new file mode 100644 index 00000000..ecbe8c4b --- /dev/null +++ b/src/hos_libvariant/src/src/YAMLEmitter.cc @@ -0,0 +1,410 @@ +//============================================================================= +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief A wrapper class around a libyaml emitter + */ +#include "YAMLEmitter.h" +#include +#include +#include +#include +#include +#include "Base64.h" + +namespace libvariant { + + static int WriteHandler(void *data, unsigned char *buffer, size_t size) { + EmitterOutput *out = (EmitterOutput*)data; + return out->Write((const void*)buffer, size); + } + + static const char *param_keys[] = { "scalar_style", "map_style", "list_style", + "implicit_document_begin", "implicit_document_end", "indent", "width", + "precision", 0 }; + static const char *scalar_style_str[] = { "any", "plain", "single quoted", + "double quoted", "literal", "folded", 0 }; + static const char *style_str[] = { "any", "block", "flow", 0 }; + + YAMLEmitterImpl::Config::Config(Variant params) + : default_scalar_style(ANY_SCALAR_STYLE), + default_map_style(ANY_STYLE), + default_list_style(ANY_STYLE), + implicit_begin_document(false), + implicit_end_document(false), + indent(-1), + width(-1), + precision(std::numeric_limits::digits10+2) + { + SetParams(params); + } + + void YAMLEmitterImpl::Config::SetParams(Variant params) { + if (params.IsMap()) { + for (int i = 0; param_keys[i]; ++i) { + const char *key = param_keys[i]; + if (params.Contains(key)) { + SetParam((ConfigKeys)i, params[key]); + } + } + } + } + + void YAMLEmitterImpl::Config::SetParam(const std::string &key, Variant value) { + for (int i = 0; param_keys[i]; ++i) { + if (param_keys[i] == key) { + SetParam((ConfigKeys)i, value); + break; + } + } + } + + void YAMLEmitterImpl::Config::SetParam(ConfigKeys index, Variant value) { + switch (index) { + case SCALAR_STYLE: + { + std::string v = value.AsString(); + for (int i = 0; scalar_style_str[i]; ++i) { + const char *style = scalar_style_str[i]; + if (v == style) { + default_scalar_style = (ScalarStyle)i; + break; + } + } + } + break; + case MAP_STYLE: + { + std::string v = value.AsString(); + for (int i = 0; style_str[i]; ++i) { + const char *style = style_str[i]; + if (v == style) { + default_map_style = (Style)i; + break; + } + } + } + break; + case LIST_STYLE: + { + std::string v = value.AsString(); + for (int i = 0; style_str[i]; ++i) { + const char *style = style_str[i]; + if (v == style) { + default_list_style = (Style)i; + break; + } + } + } + break; + case IMPLICIT_DOCUMENT_BEGIN: + implicit_begin_document = value.AsBool(); + break; + case IMPLICIT_DOCUMENT_END: + implicit_end_document = value.AsBool(); + break; + case INDENT: + indent = value.AsInt(); + break; + case WIDTH: + width = value.AsInt(); + break; + case PRECISION: + precision = value.AsUnsigned(); + break; + default: + break; + } + } + + Variant YAMLEmitterImpl::Config::GetParams() { + Variant ret = Variant::MapType; + for (int i = 0; param_keys[i]; ++i) { + const char *key = param_keys[i]; + ret[key] = GetParam((ConfigKeys)i); + } + return ret; + } + + Variant YAMLEmitterImpl::Config::GetParam(const std::string &key) { + for (int i = 0; param_keys[i]; ++i) { + if (param_keys[i] == key) { + return GetParam((ConfigKeys)i); + } + } + return Variant::NullType; + } + + Variant YAMLEmitterImpl::Config::GetParam(ConfigKeys index) { + switch (index) { + case SCALAR_STYLE: + return scalar_style_str[index]; + case MAP_STYLE: + return style_str[index]; + case LIST_STYLE: + return style_str[index]; + case IMPLICIT_DOCUMENT_BEGIN: + return implicit_begin_document; + case IMPLICIT_DOCUMENT_END: + return implicit_end_document; + case INDENT: + return indent; + case WIDTH: + return width; + case PRECISION: + return precision; + default: + return Variant::NullType; + } + } + + + YAMLEmitterImpl::YAMLEmitterImpl(shared_ptr o, Variant params) + :out(o), closed(false), in_document(false), conf(params) + { + if (yaml_emitter_initialize(&emitter) == 0) { + throw std::runtime_error("Unable to initialize YAMLEmitter."); + } + yaml_emitter_set_output(&emitter, WriteHandler, out.get()); + if (conf.indent > 0) { + yaml_emitter_set_indent(&emitter, conf.indent); + } + if (conf.width > 0) { + yaml_emitter_set_width(&emitter, conf.width); + } + try { EmitStreamStart(); } + catch (...) { + yaml_emitter_delete(&emitter); + throw; + } + } + + YAMLEmitterImpl::~YAMLEmitterImpl() { + try { Close(); } + catch (const std::runtime_error &) {} + } + + void YAMLEmitterImpl::BeginDocument() { + BeginDocument(conf.implicit_begin_document); + } + + void YAMLEmitterImpl::BeginDocument(bool implicit) { + CheckClosed(); + CheckOutDocument(); + yaml_event_t event; + if (yaml_document_start_event_initialize(&event, 0, 0, 0, implicit ? 1 : 0) == 0) { + throw std::runtime_error("Error initializing document start event."); + } + Emit(event); + in_document = true; + } + + void YAMLEmitterImpl::EndDocument() { + EndDocument(conf.implicit_end_document); + } + + void YAMLEmitterImpl::EndDocument(bool implicit) { + CheckClosed(); + CheckInDocument(); + yaml_event_t event; + if (yaml_document_end_event_initialize(&event, implicit ? 1 : 0) == 0) { + throw std::runtime_error("Error initializing document end event."); + } + Emit(event); + in_document = false; + } + + void YAMLEmitterImpl::BeginMap(int length) { + BeginMap(length, conf.default_map_style); + } + + void YAMLEmitterImpl::BeginMap(int, Style style) { + CheckClosed(); + CheckInDocument(); + yaml_event_t event; + if (yaml_mapping_start_event_initialize(&event, 0, 0, 1, + (yaml_mapping_style_t)style) == 0) { + throw std::runtime_error("Unable to initialize mapping start event"); + } + Emit(event); + } + + void YAMLEmitterImpl::EndMap() { + CheckClosed(); + CheckInDocument(); + yaml_event_t event; + if (yaml_mapping_end_event_initialize(&event) == 0) { + throw std::runtime_error("Unable to initialize mapping end event."); + } + Emit(event); + } + + void YAMLEmitterImpl::BeginList(int length) { + BeginList(length, conf.default_list_style); + } + + void YAMLEmitterImpl::BeginList(int, Style style) { + CheckClosed(); + CheckInDocument(); + yaml_event_t event; + if (yaml_sequence_start_event_initialize(&event, 0, 0, 1, + (yaml_sequence_style_t)style) == 0) { + throw std::runtime_error("Unable to initialize sequence start event"); + } + Emit(event); + } + + void YAMLEmitterImpl::EndList() { + CheckClosed(); + CheckInDocument(); + yaml_event_t event; + if (yaml_sequence_end_event_initialize(&event) == 0) { + throw std::runtime_error("Unable to initialize sequence end event."); + } + Emit(event); + } + + void YAMLEmitterImpl::EmitNull() { + Emit("null", PLAIN_SCALAR_STYLE); + } + + void YAMLEmitterImpl::EmitTrue() { + Emit("true", PLAIN_SCALAR_STYLE); + } + + void YAMLEmitterImpl::EmitFalse() { + Emit("false", PLAIN_SCALAR_STYLE); + } + + void YAMLEmitterImpl::Emit(const std::string &v, ScalarStyle style) { + CheckClosed(); + CheckInDocument(); + yaml_event_t event; + if (yaml_scalar_event_initialize(&event, 0, 0, (yaml_char_t*)v.c_str(), v.length(), 1, 1, + (yaml_scalar_style_t)style) == 0) { + throw std::runtime_error("Unable to initialize scalar event."); + } + Emit(event); + } + + void YAMLEmitterImpl::Emit(const char *v) { + Emit(v, ANY_SCALAR_STYLE); + } + + void YAMLEmitterImpl::Emit(const char *v, ScalarStyle style) { + CheckClosed(); + CheckInDocument(); + yaml_event_t event; + if (yaml_scalar_event_initialize(&event, 0, 0, (yaml_char_t*)v, strlen(v), 1, 1, + (yaml_scalar_style_t)style) == 0) { + throw std::runtime_error("Unable to initialize scalar event."); + } + Emit(event); + } + + void YAMLEmitterImpl::Emit(intmax_t v) { + std::ostringstream oss; + oss << v; + Emit(oss.str(), PLAIN_SCALAR_STYLE); + } + + void YAMLEmitterImpl::Emit(uintmax_t v) { + std::ostringstream oss; + oss << v; + Emit(oss.str(), PLAIN_SCALAR_STYLE); + } + + void YAMLEmitterImpl::Emit(double v) { + std::ostringstream oss; + if (v != v) { + oss << ".nan"; + } else if (std::abs(v) == std::numeric_limits::infinity()) { + oss << (v < 0 ? "-" : "") << ".inf"; + } else { + oss << std::setprecision(conf.precision) << std::showpoint << v; + } + Emit(oss.str(), PLAIN_SCALAR_STYLE); + } + + void YAMLEmitterImpl::Emit(ConstBlobPtr b) { + CheckClosed(); + CheckInDocument(); + yaml_event_t event; + std::vector buf(Base64EncodeSize(b->GetTotalLength())); + unsigned len = Base64Encode(&buf[0], b->GetIOVec(), b->GetNumBuffers(), 0); + if (yaml_scalar_event_initialize(&event, 0, (yaml_char_t*)"tag:yaml.org,2002:binary", (yaml_char_t*)&buf[0], len, 0, 0, + (yaml_scalar_style_t)ANY_SCALAR_STYLE) == 0) { + throw std::runtime_error("Unable to initialize scalar event."); + } + Emit(event); + } + + void YAMLEmitterImpl::Flush() { + CheckClosed(); + if (yaml_emitter_flush(&emitter) == 0) { + throw std::runtime_error(emitter.problem); + } + } + + void YAMLEmitterImpl::Close() { + if (!closed) { + CheckOutDocument(); + yaml_event_t event; + if (yaml_stream_end_event_initialize(&event) == 0) { + throw std::runtime_error("Unable to initialize stream end event."); + } + Emit(event); + Flush(); + yaml_emitter_delete(&emitter); + out.reset(); + closed = true; + } + } + + Variant YAMLEmitterImpl::GetParam(const std::string &key) { + return conf.GetParam(key); + } + + Variant YAMLEmitterImpl::GetParams() { + return conf.GetParams(); + } + + void YAMLEmitterImpl::SetParam(const std::string &key, Variant value) { + conf.SetParam(key, value); + } + + void YAMLEmitterImpl::SetParams(Variant params) { + conf.SetParams(params); + } + + void YAMLEmitterImpl::EmitStreamStart() { + yaml_event_t event; + if (yaml_stream_start_event_initialize(&event, YAML_UTF8_ENCODING) == 0) { + throw std::runtime_error("Unable to initialize stream start event"); + } + Emit(event); + } + + void YAMLEmitterImpl::Emit(yaml_event_t &event) { + if (yaml_emitter_emit(&emitter, &event) == 0) { + yaml_event_delete(&event); + throw std::runtime_error(emitter.problem); + } + } + +} diff --git a/src/hos_libvariant/src/src/YAMLEmitter.h b/src/hos_libvariant/src/src/YAMLEmitter.h new file mode 100644 index 00000000..a83fc5b8 --- /dev/null +++ b/src/hos_libvariant/src/src/YAMLEmitter.h @@ -0,0 +1,170 @@ +//============================================================================= +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief A wrapper class around a libyaml emitter + */ + +#ifndef YAMLEMITTER_INC +#define YAMLEMITTER_INC + +#pragma once +#include +#include +#include +#include +#include +#include "../../src/include/Variant/Emitter.h" +#include +#include + +namespace libvariant { + + /** + * Supported parameters are (first is default): + * "scalar_style": "any"|"plain"|"single quoted"|"double + * quoted"|"literal"|"folded" + * "map_style": "any"|"block"|"flow" + * "list_style": "any"|"block"|"flow" + * "implicit_document_begin": false|true + * "implicit_document_end": false|true + * These two parameters are only settable on creation. + * Resetting afterwards has no effect. + * "indent": integer (number of spaces to indent) + * "width": integer (set prefered line width) + * "precision": number of digits for a float + */ + class YAMLEmitterImpl : public EmitterImpl { + public: + enum ConfigKeys { + SCALAR_STYLE, + MAP_STYLE, + LIST_STYLE, + IMPLICIT_DOCUMENT_BEGIN, + IMPLICIT_DOCUMENT_END, + INDENT, + WIDTH, + PRECISION + }; + + enum ScalarStyle { + ANY_SCALAR_STYLE, + PLAIN_SCALAR_STYLE, + SINGLE_QUOTED_SCALAR_STYLE, + DOUBLE_QUOTED_SCALAR_STYLE, + LITERAL_SCALAR_STYLE, + FOLDED_SCALAR_STYLE + }; + + enum Style { + ANY_STYLE, + BLOCK_STYLE, + FLOW_STYLE + }; + + struct Config { + Config(Variant params); + void SetParams(Variant params); + void SetParam(const std::string &key, Variant value); + void SetParam(ConfigKeys index, Variant value); + Variant GetParams(); + Variant GetParam(const std::string &key); + Variant GetParam(ConfigKeys index); + + ScalarStyle default_scalar_style; + Style default_map_style; + Style default_list_style; + bool implicit_begin_document; + bool implicit_end_document; + int indent; + int width; + unsigned precision; + }; + + /** + * Create a YAMLEmitter that uses output to write. + * The output object will be deleted when YAMLEmitter + * is destroyed. + */ + YAMLEmitterImpl(shared_ptr output, Variant params); + virtual ~YAMLEmitterImpl(); + + virtual void BeginDocument(); + void BeginDocument(bool implicit); + virtual void EndDocument(); + void EndDocument(bool implicit); + virtual void BeginMap(int length); + void BeginMap(int length, Style style); + virtual void EndMap(); + virtual void BeginList(int length); + void BeginList(int length, Style style); + virtual void EndList(); + + virtual void EmitNull(); + virtual void EmitTrue(); + virtual void EmitFalse(); + void Emit(const std::string &v, ScalarStyle style); + virtual void Emit(const char *v); + void Emit(const char *v, ScalarStyle style); + virtual void Emit(intmax_t v); + virtual void Emit(uintmax_t v); + virtual void Emit(double v); + virtual void Emit(ConstBlobPtr b); + + virtual void Flush(); + /** Flush, release all resources and clean up. + * Doing anything other than deleting this object + * will result in a std::runtime_error */ + virtual void Close(); + + virtual Variant GetParam(const std::string &key); + virtual Variant GetParams(); + virtual void SetParam(const std::string &key, Variant value); + virtual void SetParams(Variant params); + + private: + void EmitStreamStart(); + void Emit(yaml_event_t &event); + + void CheckClosed() { + if (closed) { + throw std::runtime_error("YAMLEmitter is closed"); + } + } + + void CheckInDocument() { + if (!in_document) { + BeginDocument(); + } + } + + void CheckOutDocument() { + if (in_document) { + EndDocument(); + } + } + + shared_ptr out; + yaml_emitter_t emitter; + bool closed; + bool in_document; + Config conf; + }; + +} +#endif diff --git a/src/hos_libvariant/src/src/YAMLParser.cc b/src/hos_libvariant/src/src/YAMLParser.cc new file mode 100644 index 00000000..73a03d7d --- /dev/null +++ b/src/hos_libvariant/src/src/YAMLParser.cc @@ -0,0 +1,194 @@ +//============================================================================= +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ +#include "YAMLParser.h" +#include +#include "Base64.h" +#include "GuessScalar.h" +#include +#include +#include + +namespace libvariant { + + int YAMLParserImpl::ParserReadHandler(void *data, unsigned char *buffer, size_t size, size_t *sizein) { + YAMLParserImpl *impl = (YAMLParserImpl*)data; + unsigned len = size; + const void *ptr = impl->input->GetPtr(len); + if (!ptr) { + *sizein = 0; + return 1; + } + *sizein = std::min(size, len); + memcpy(buffer, ptr, *sizein); + impl->input->Release(*sizein); + return 1; + } + + YAMLParserImpl::YAMLParserImpl(shared_ptr in) + : input(in), eof(false), err(false) + { + yaml_parser_initialize(&parser); + yaml_parser_set_input(&parser, &ParserReadHandler, this); + } + + YAMLParserImpl::~YAMLParserImpl() { + yaml_parser_delete(&parser); + } + + void ParseScalar(yaml_event_t &event, ParserImpl *p, ParserActions *action) { + const char *value = (const char *)event.data.scalar.value; + const char *anchor = (const char *)event.data.scalar.anchor; + const char *tag = (const char *)event.data.scalar.tag; + unsigned length = event.data.scalar.length; + yaml_scalar_style_t style = event.data.scalar.style; + if (tag && strcmp(tag, "tag:yaml.org,2002:binary") == 0) { + void *data = 0; + if (posix_memalign(&data, 64, Base64DecodeSize(length)) != 0) { + throw std::bad_alloc(); + } + unsigned len = Base64Decode(data, value, length); + action->Scalar(p, Blob::CreateFree(data, len), anchor, tag); + return; + } + switch (style) { + case YAML_ANY_SCALAR_STYLE: + case YAML_PLAIN_SCALAR_STYLE: + break; + case YAML_SINGLE_QUOTED_SCALAR_STYLE: + case YAML_DOUBLE_QUOTED_SCALAR_STYLE: + case YAML_LITERAL_SCALAR_STYLE: + case YAML_FOLDED_SCALAR_STYLE: + action->Scalar(p, value, length, anchor, tag); + return; + } + if (tag) { + action->Scalar(p, value, length, anchor, tag); + } else { + GuessScalar(value, length, anchor, tag, p, action); + } + } + + int YAMLParserImpl::Run() { + bool loop = true; + while (loop && !eof && !action_stack.empty()) { + yaml_event_t event; + if (yaml_parser_parse(&parser, &event) == 0) { + err = true; + std::ostringstream oss; + oss << "Error parsing YAML: " << parser.problem << " " + << (parser.context ? parser.context : "") + << " at line " << parser.problem_mark.line << " column " + << parser.problem_mark.column << "\n"; + errorstr = oss.str(); + throw std::runtime_error(errorstr); + } + + try { + switch (event.type) { + /** An empty event. */ + case YAML_NO_EVENT: + break; + + /** A STREAM-START event. */ + case YAML_STREAM_START_EVENT: + break; + /** A STREAM-END event. */ + case YAML_STREAM_END_EVENT: + eof = true; + loop = false; + break; + + /** A DOCUMENT-START event. */ + case YAML_DOCUMENT_START_EVENT: + TopAction()->BeginDocument(this); + break; + /** A DOCUMENT-END event. */ + case YAML_DOCUMENT_END_EVENT: + TopAction()->EndDocument(this); + loop = false; + break; + + /** An ALIAS event. */ + case YAML_ALIAS_EVENT: + TopAction()->Alias(this, (const char*)event.data.alias.anchor); + break; + /** A SCALAR event. */ + case YAML_SCALAR_EVENT: + ParseScalar(event, this, TopAction()); + break; + + /** A SEQUENCE-START event. */ + case YAML_SEQUENCE_START_EVENT: + TopAction()->BeginList(this, -1, (const char*)event.data.sequence_start.anchor, + (const char*)event.data.sequence_start.tag); + break; + /** A SEQUENCE-END event. */ + case YAML_SEQUENCE_END_EVENT: + TopAction()->EndList(this); + break; + + /** A MAPPING-START event. */ + case YAML_MAPPING_START_EVENT: + TopAction()->BeginMap(this, -1, (const char*)event.data.mapping_start.anchor, + (const char*)event.data.mapping_start.tag); + break; + /** A MAPPING-END event. */ + case YAML_MAPPING_END_EVENT: + TopAction()->EndMap(this); + break; + + } + } catch (...) { + err = true; + errorstr = "Exception from action..."; + yaml_event_delete(&event); + throw; + } + yaml_event_delete(&event); + } + return eof ? 1 : 0; + } + + bool YAMLParserImpl::Done() const { + return eof; + } + + bool YAMLParserImpl::Error() const { + return err; + } + + bool YAMLParserImpl::Ok() const { + return !err && !eof; + } + + std::string YAMLParserImpl::ErrorStr() const { + return errorstr; + } + + void YAMLParserImpl::Reset() { + eof = false; + err = false; + yaml_parser_delete(&parser); + yaml_parser_initialize(&parser); + yaml_parser_set_input(&parser, &ParserReadHandler, this); + } +} diff --git a/src/hos_libvariant/src/src/YAMLParser.h b/src/hos_libvariant/src/src/YAMLParser.h new file mode 100644 index 00000000..351d0e87 --- /dev/null +++ b/src/hos_libvariant/src/src/YAMLParser.h @@ -0,0 +1,62 @@ +//============================================================================= +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief + */ + + +#ifndef YAMLPARSER_INC +#define YAMLPARSER_INC + +#pragma once +#include "../../src/include/Variant/Parser.h" +#include "../../src/include/Variant/ParserInput.h" +#include "../../src/include/Variant/SharedPtr.h" +#include + +namespace libvariant { + + + /** + * \brief + */ + class YAMLParserImpl : public ParserImpl { + public: + YAMLParserImpl(shared_ptr in); + virtual ~YAMLParserImpl(); + + virtual int Run(); + + virtual bool Done() const; + virtual bool Error() const; + virtual bool Ok() const; + virtual std::string ErrorStr() const; + virtual void Reset(); + private: + static int ParserReadHandler(void *data, unsigned char *buffer, size_t size, size_t *sizein); + yaml_parser_t parser; + shared_ptr input; + bool eof; + bool err; + std::string errorstr; + }; + +} + +#endif diff --git a/src/hos_libvariant/src/src/argparse-schema.cc b/src/hos_libvariant/src/src/argparse-schema.cc new file mode 100644 index 00000000..93d131f0 --- /dev/null +++ b/src/hos_libvariant/src/src/argparse-schema.cc @@ -0,0 +1,184 @@ +// This file was generated using gen-argparse-schema and argparse-schema.yaml +// To change edit those files and regenarate. +namespace libvariant { +extern const char ARG_PARSE_SCHEMA_STR[]; +const char ARG_PARSE_SCHEMA_STR[] = { + 0x7b, 0x22, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x65, 0x6e, 0x75, 0x6d, 0x22, 0x3a, + 0x20, 0x5b, 0x22, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x2c, 0x20, 0x22, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x22, + 0x2c, 0x20, 0x22, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x72, 0x75, + 0x65, 0x22, 0x2c, 0x20, 0x22, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x22, 0x2c, 0x20, 0x22, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x64, 0x22, 0x2c, 0x20, 0x22, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, + 0x2c, 0x20, 0x22, 0x68, 0x65, 0x6c, 0x70, 0x22, 0x2c, 0x20, 0x22, 0x61, + 0x64, 0x76, 0x5f, 0x68, 0x65, 0x6c, 0x70, 0x22, 0x2c, 0x20, 0x22, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x2c, 0x20, 0x22, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0x2c, 0x20, 0x22, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x79, 0x61, 0x6d, 0x6c, 0x22, + 0x2c, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x6c, + 0x69, 0x73, 0x74, 0x22, 0x2c, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x22, 0x5d, 0x7d, 0x2c, 0x20, + 0x22, 0x74, 0x79, 0x70, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x65, + 0x6e, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x5b, 0x22, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x22, 0x2c, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, + 0x6e, 0x22, 0x2c, 0x20, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, + 0x22, 0x2c, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x2c, + 0x20, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0x2c, 0x20, 0x6e, 0x75, 0x6c, + 0x6c, 0x5d, 0x7d, 0x2c, 0x20, 0x22, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x42, 0x61, 0x73, 0x65, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x72, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x64, 0x22, 0x3a, 0x20, 0x5b, 0x22, 0x74, 0x69, + 0x74, 0x6c, 0x65, 0x22, 0x2c, 0x20, 0x22, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x20, 0x22, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x5d, 0x2c, 0x20, 0x22, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x3a, 0x20, 0x7b, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x6d, + 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x7b, + 0x22, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x30, + 0x2c, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x69, + 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x6d, + 0x61, 0x78, 0x41, 0x72, 0x67, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x6d, + 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x30, 0x2c, 0x20, + 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x69, 0x6e, 0x74, + 0x65, 0x67, 0x65, 0x72, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x65, 0x6e, 0x75, + 0x6d, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x6d, 0x69, 0x6e, 0x49, 0x74, 0x65, + 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x31, 0x2c, 0x20, 0x22, 0x75, 0x6e, 0x69, + 0x71, 0x75, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x74, + 0x72, 0x75, 0x65, 0x2c, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, + 0x20, 0x22, 0x61, 0x72, 0x72, 0x61, 0x79, 0x22, 0x2c, 0x20, 0x22, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x5b, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, + 0x6e, 0x22, 0x2c, 0x20, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, + 0x22, 0x2c, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x2c, + 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x5d, 0x7d, 0x7d, + 0x2c, 0x20, 0x22, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x22, 0x3a, + 0x20, 0x7b, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x6d, 0x61, + 0x78, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x7b, 0x22, + 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x30, 0x2c, + 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x69, 0x6e, + 0x74, 0x65, 0x67, 0x65, 0x72, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x6d, 0x69, + 0x6e, 0x41, 0x72, 0x67, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x6d, 0x69, + 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x30, 0x2c, 0x20, 0x22, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x69, 0x6e, 0x74, 0x65, + 0x67, 0x65, 0x72, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x61, 0x64, 0x76, 0x61, + 0x6e, 0x63, 0x65, 0x64, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x2c, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x62, + 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x7b, 0x7d, 0x2c, 0x20, 0x22, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x22, 0x3a, 0x20, 0x7b, 0x7d, 0x2c, 0x20, 0x22, 0x70, 0x61, 0x74, 0x74, + 0x65, 0x72, 0x6e, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x2c, + 0x20, 0x22, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x3a, 0x20, 0x22, + 0x72, 0x65, 0x67, 0x65, 0x78, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x20, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x2c, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, + 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x22, 0x7d, 0x2c, 0x20, + 0x22, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x7b, + 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, + 0x3a, 0x20, 0x22, 0x23, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, + 0x7b, 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x2f, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x22, 0x7d, 0x7d, 0x7d, 0x7d, 0x2c, 0x20, + 0x22, 0x24, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x3a, 0x20, 0x22, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x2d, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, + 0x72, 0x61, 0x66, 0x74, 0x2d, 0x30, 0x34, 0x2f, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x23, 0x22, 0x2c, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, + 0x3a, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x2c, 0x20, + 0x22, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, + 0x3a, 0x20, 0x7b, 0x22, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x7d, + 0x2c, 0x20, 0x22, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x3a, 0x20, + 0x7b, 0x22, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x3a, + 0x20, 0x7b, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x2c, 0x20, 0x22, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x3a, 0x20, 0x7b, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, + 0x7d, 0x2c, 0x20, 0x22, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x22, 0x3a, + 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x61, 0x72, 0x72, 0x61, 0x79, 0x22, 0x7d, 0x2c, + 0x20, 0x22, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3a, 0x20, 0x7b, 0x22, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x64, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x22, + 0x7d, 0x2c, 0x20, 0x22, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x64, + 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x22, 0x3a, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x20, 0x22, 0x74, + 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x65, + 0x61, 0x6e, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x6d, 0x75, 0x74, 0x75, 0x61, + 0x6c, 0x6c, 0x79, 0x20, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, + 0x65, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, + 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x22, 0x7d, 0x7d, + 0x7d, 0x2c, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x74, + 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, + 0x7d, 0x2c, 0x20, 0x22, 0x65, 0x70, 0x69, 0x6c, 0x6f, 0x67, 0x22, 0x3a, + 0x20, 0x7b, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x61, 0x64, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x74, + 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x22, 0x2c, 0x20, 0x22, 0x61, 0x6e, 0x79, 0x4f, 0x66, 0x22, 0x3a, + 0x20, 0x5b, 0x7b, 0x22, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x22, 0x3a, 0x20, 0x5b, 0x22, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x5d, 0x7d, 0x2c, 0x20, 0x7b, 0x22, 0x72, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x22, 0x3a, 0x20, 0x5b, 0x22, + 0x6c, 0x6f, 0x6e, 0x67, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x5d, + 0x7d, 0x5d, 0x2c, 0x20, 0x22, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x6c, 0x6f, 0x6e, 0x67, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x74, + 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x22, 0x7d, 0x2c, 0x20, 0x22, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x6d, 0x69, + 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x31, 0x2c, + 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x22, 0x2c, 0x20, 0x22, 0x6d, 0x61, 0x78, 0x4c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x31, 0x7d, 0x2c, 0x20, + 0x22, 0x65, 0x6e, 0x76, 0x22, 0x3a, 0x20, 0x7b, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, + 0x7d, 0x7d, 0x2c, 0x20, 0x22, 0x61, 0x6c, 0x6c, 0x4f, 0x66, 0x22, 0x3a, + 0x20, 0x5b, 0x7b, 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, + 0x23, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x73, 0x65, + 0x22, 0x7d, 0x5d, 0x7d, 0x2c, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, + 0x3a, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x7d, 0x2c, + 0x20, 0x22, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, + 0x3a, 0x20, 0x7b, 0x22, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, + 0x7b, 0x22, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x22, 0x3a, + 0x20, 0x5b, 0x22, 0x6b, 0x65, 0x79, 0x70, 0x61, 0x74, 0x68, 0x22, 0x5d, + 0x2c, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x2c, 0x20, 0x22, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x22, + 0x6b, 0x65, 0x79, 0x70, 0x61, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x7b, 0x22, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x22, 0x7d, 0x7d, 0x2c, 0x20, 0x22, 0x61, 0x6c, 0x6c, 0x4f, + 0x66, 0x22, 0x3a, 0x20, 0x5b, 0x7b, 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, + 0x3a, 0x20, 0x22, 0x23, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, + 0x61, 0x73, 0x65, 0x22, 0x7d, 0x5d, 0x7d, 0x2c, 0x20, 0x22, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x61, 0x72, 0x72, 0x61, 0x79, 0x22, + 0x7d, 0x7d, 0x7d +, 0 }; } diff --git a/src/hos_libvariant/src/src/argparse-schema.yaml b/src/hos_libvariant/src/src/argparse-schema.yaml new file mode 100644 index 00000000..43417a4d --- /dev/null +++ b/src/hos_libvariant/src/src/argparse-schema.yaml @@ -0,0 +1,91 @@ + +"$schema": "http://json-schema.org/draft-04/schema#" +definitions: + actions: + enum: + - store + - store_const + - store_true + - store_false + - append + - count + - help + - adv_help + - config + - config_json + - config_yaml + - config_plist + - config_print + types: + enum: + - string + - boolean + - integer + - number + - 'null' + - null + + optionBase: + properties: + title: { type: string } + description: { type: string } + action: { "$ref": '#/definitions/actions' } + type: { "$ref": '#/definitions/types' } + default: {} + const: {} + required: { type: boolean, default: false } + advanced: { type: boolean, default: false } + enum: + type: array + minItems: 1 + uniqueItems: true + items: { type: [ boolean, integer, number, string ] } +# Specific to type "number" and "integer" + minimum: { type: number } + maximum: { type: number } +# Specific to type "string" + minLength: { type: integer, minimum: 0 } + maxLength: { type: integer, minimum: 0 } + pattern: { type: string, format: regex } +# Specific to action "append" + minArgs: { type: integer, minimum: 0 } + maxArgs: { type: integer, minimum: 0 } + required: [ title, description, action ] + +type: object +properties: + title: { type: string } + description: { type: string } + epilog: { type: string } + options: + type: object + additionalProperties: + type: object + properties: + longOption: { type: string } + shortOption: { type: string, maxLength: 1, minLength: 1 } + env: { type: string } + allOf: [ { "$ref": '#/definitions/optionBase' } ] + anyOf: + - { required: [ shortOption ] } + - { required: [ longOption ] } + groups: + type: object + additionalProperties: + type: object + properties: + title: { type: string } + description: { type: string } + mutually exclusive: { type: boolean } + required: { type: boolean } + advanced: { type: boolean, default: false } + members: { type: array, unique: true, items: { type: string } } + arguments: + type: array + items: + type: object + properties: + keypath: { type: string } + allOf: [ { "$ref": '#/definitions/optionBase' } ] + required: [ keypath ] + diff --git a/src/hos_libvariant/src/src/gen-argparse-schema b/src/hos_libvariant/src/src/gen-argparse-schema new file mode 100644 index 00000000..04b0b09f --- /dev/null +++ b/src/hos_libvariant/src/src/gen-argparse-schema @@ -0,0 +1,9 @@ +#!/bin/sh + +(echo "// This file was generated using gen-argparse-schema and argparse-schema.yaml"; +echo "// To change edit those files and regenarate."; +echo "namespace libvariant {"; +echo "extern const char ARG_PARSE_SCHEMA_STR[];"; +echo "const char ARG_PARSE_SCHEMA_STR[] = {"; +python -c 'import json,yaml,sys; json.dump(yaml.load(sys.stdin), sys.stdout);' < argparse-schema.yaml | xxd -i; +echo ", 0 }; }") > argparse-schema.cc diff --git a/src/hos_libvariant/src/src/gen-json-schema b/src/hos_libvariant/src/src/gen-json-schema new file mode 100644 index 00000000..0d5e17d8 --- /dev/null +++ b/src/hos_libvariant/src/src/gen-json-schema @@ -0,0 +1,9 @@ +#!/bin/sh + +(echo "// This file was generated using gen-json-schema and json-schema-v4.json"; +echo "// To change edit those files and regenarate."; +echo "namespace libvariant {"; +echo "extern const char JSON_SCHEMA_V4_SCHEMA[];"; +echo "const char JSON_SCHEMA_V4_SCHEMA[] = {"; +xxd -i < json-schema-v4.json; +echo ", 0 }; }") > json-schema-v4.cc diff --git a/src/hos_libvariant/src/src/json-schema-v4.cc b/src/hos_libvariant/src/src/json-schema-v4.cc new file mode 100644 index 00000000..87deb5fb --- /dev/null +++ b/src/hos_libvariant/src/src/json-schema-v4.cc @@ -0,0 +1,371 @@ +// This file was generated using gen-json-schema and json-schema-v4.json +// To change edit those files and regenarate. +namespace libvariant { +extern const char JSON_SCHEMA_V4_SCHEMA[]; +const char JSON_SCHEMA_V4_SCHEMA[] = { + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, + 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, + 0x2d, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x6f, 0x72, 0x67, 0x2f, + 0x64, 0x72, 0x61, 0x66, 0x74, 0x2d, 0x30, 0x34, 0x2f, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x23, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x24, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x3a, 0x20, 0x22, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x2d, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x72, + 0x61, 0x66, 0x74, 0x2d, 0x30, 0x34, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x23, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, + 0x22, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x20, 0x6d, 0x65, 0x74, 0x61, 0x2d, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x66, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x41, 0x72, 0x72, 0x61, 0x79, 0x22, 0x3a, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x61, 0x72, + 0x72, 0x61, 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x69, 0x6e, 0x49, 0x74, + 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x31, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x24, 0x72, 0x65, + 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x22, 0x20, 0x7d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x76, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x22, 0x3a, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x69, + 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x69, + 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x30, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x76, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x44, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x30, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, + 0x6c, 0x6c, 0x4f, 0x66, 0x22, 0x3a, 0x20, 0x5b, 0x20, 0x7b, 0x20, 0x22, + 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x2f, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, + 0x72, 0x22, 0x20, 0x7d, 0x2c, 0x20, 0x7b, 0x20, 0x22, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x20, 0x30, 0x20, 0x7d, 0x20, 0x5d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x69, 0x6d, + 0x70, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x5b, 0x20, 0x22, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x22, 0x2c, 0x20, 0x22, 0x62, 0x6f, 0x6f, + 0x6c, 0x65, 0x61, 0x6e, 0x22, 0x2c, 0x20, 0x22, 0x69, 0x6e, 0x74, 0x65, + 0x67, 0x65, 0x72, 0x22, 0x2c, 0x20, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, + 0x2c, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x2c, 0x20, + 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x2c, 0x20, 0x22, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, + 0x72, 0x72, 0x61, 0x79, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x61, 0x72, 0x72, 0x61, 0x79, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x7b, + 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x22, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x69, + 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x31, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, + 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, + 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, + 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x69, 0x64, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, 0x69, 0x22, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x24, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, + 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x75, 0x72, + 0x69, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, + 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0x3a, + 0x20, 0x7b, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x4f, 0x66, + 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, + 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x30, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, + 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x61, + 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, + 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x61, 0x78, 0x69, + 0x6d, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, + 0x3a, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x22, + 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, + 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, + 0x76, 0x65, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x22, 0x3a, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x62, + 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x20, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x61, + 0x78, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x3a, 0x20, 0x7b, 0x20, + 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x2f, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, + 0x65, 0x72, 0x22, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x6d, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, + 0x3a, 0x20, 0x22, 0x23, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, + 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x44, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x30, 0x22, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, + 0x6e, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, + 0x3a, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x72, + 0x65, 0x67, 0x65, 0x78, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, + 0x6e, 0x79, 0x4f, 0x66, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, + 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x22, 0x20, 0x7d, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, + 0x3a, 0x20, 0x22, 0x23, 0x22, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x20, 0x7b, 0x7d, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x6e, 0x79, 0x4f, + 0x66, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, + 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x22, 0x20, + 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x24, 0x72, + 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x2f, 0x64, 0x65, 0x66, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x41, 0x72, 0x72, 0x61, 0x79, 0x22, 0x20, 0x7d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0x3a, + 0x20, 0x7b, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x7b, + 0x20, 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x2f, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x74, 0x65, + 0x67, 0x65, 0x72, 0x22, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x69, 0x6e, 0x49, 0x74, 0x65, 0x6d, + 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, + 0x3a, 0x20, 0x22, 0x23, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, + 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x44, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x30, 0x22, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, + 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, + 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x65, + 0x61, 0x6e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x22, 0x3a, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x61, 0x78, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x20, + 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x2f, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, + 0x65, 0x72, 0x22, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x6d, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x24, + 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x2f, 0x64, 0x65, 0x66, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, + 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x30, 0x22, 0x20, 0x7d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, + 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x2f, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, 0x79, 0x22, 0x20, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, + 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x61, 0x6e, 0x79, 0x4f, 0x66, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, + 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x22, 0x20, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x24, 0x72, 0x65, + 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x22, 0x20, 0x7d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x20, + 0x7b, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3a, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x64, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, + 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x22, 0x20, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0x3a, + 0x20, 0x7b, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x3a, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x64, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, + 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x22, 0x20, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0x3a, + 0x20, 0x7b, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, + 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, + 0x3a, 0x20, 0x22, 0x23, 0x22, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x20, 0x7b, 0x7d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x70, 0x65, 0x6e, + 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x64, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x61, 0x6e, 0x79, 0x4f, 0x66, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x24, 0x72, + 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x22, 0x20, 0x7d, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x20, 0x22, 0x24, + 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x2f, 0x64, 0x65, 0x66, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, 0x79, 0x22, 0x20, 0x7d, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x61, 0x72, + 0x72, 0x61, 0x79, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x69, 0x6e, 0x49, 0x74, + 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x31, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x75, 0x6e, + 0x69, 0x71, 0x75, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, + 0x6e, 0x79, 0x4f, 0x66, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7b, 0x20, 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, + 0x23, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2f, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x73, 0x22, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x61, 0x72, 0x72, 0x61, 0x79, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x24, 0x72, 0x65, + 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x69, 0x6d, 0x70, 0x6c, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x20, 0x7d, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x69, 0x6e, 0x49, + 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x31, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x75, 0x6e, 0x69, 0x71, 0x75, + 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x6c, 0x6c, 0x4f, 0x66, 0x22, + 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, + 0x22, 0x23, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x41, 0x72, 0x72, + 0x61, 0x79, 0x22, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x61, 0x6e, 0x79, 0x4f, 0x66, 0x22, 0x3a, 0x20, + 0x7b, 0x20, 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, + 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x41, 0x72, 0x72, 0x61, 0x79, + 0x22, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x6f, 0x6e, 0x65, 0x4f, 0x66, 0x22, 0x3a, 0x20, 0x7b, 0x20, + 0x22, 0x24, 0x72, 0x65, 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x2f, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x41, 0x72, 0x72, 0x61, 0x79, 0x22, 0x20, + 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x6e, 0x6f, 0x74, 0x22, 0x3a, 0x20, 0x7b, 0x20, 0x22, 0x24, 0x72, 0x65, + 0x66, 0x22, 0x3a, 0x20, 0x22, 0x23, 0x22, 0x20, 0x7d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, + 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x22, 0x3a, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x61, 0x78, + 0x69, 0x6d, 0x75, 0x6d, 0x22, 0x3a, 0x20, 0x5b, 0x20, 0x22, 0x6d, 0x61, + 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x22, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x78, 0x63, 0x6c, 0x75, + 0x73, 0x69, 0x76, 0x65, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x22, + 0x3a, 0x20, 0x5b, 0x20, 0x22, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, + 0x22, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, + 0x3a, 0x20, 0x7b, 0x7d, 0x0a, 0x7d, 0x0a +, 0 }; } diff --git a/src/hos_libvariant/src/src/json-schema-v4.json b/src/hos_libvariant/src/src/json-schema-v4.json new file mode 100644 index 00000000..85eb502a --- /dev/null +++ b/src/hos_libvariant/src/src/json-schema-v4.json @@ -0,0 +1,150 @@ +{ + "id": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Core schema meta-schema", + "definitions": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#" } + }, + "positiveInteger": { + "type": "integer", + "minimum": 0 + }, + "positiveIntegerDefault0": { + "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ] + }, + "simpleTypes": { + "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ] + }, + "stringArray": { + "type": "array", + "items": { "type": "string" }, + "minItems": 1, + "uniqueItems": true + } + }, + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uri" + }, + "$schema": { + "type": "string", + "format": "uri" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "default": {}, + "multipleOf": { + "type": "number", + "minimum": 0, + "exclusiveMinimum": true + }, + "maximum": { + "type": "number" + }, + "exclusiveMaximum": { + "type": "boolean", + "default": false + }, + "minimum": { + "type": "number" + }, + "exclusiveMinimum": { + "type": "boolean", + "default": false + }, + "maxLength": { "$ref": "#/definitions/positiveInteger" }, + "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" }, + "pattern": { + "type": "string", + "format": "regex" + }, + "additionalItems": { + "anyOf": [ + { "type": "boolean" }, + { "$ref": "#" } + ], + "default": {} + }, + "items": { + "anyOf": [ + { "$ref": "#" }, + { "$ref": "#/definitions/schemaArray" } + ], + "default": {} + }, + "maxItems": { "$ref": "#/definitions/positiveInteger" }, + "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" }, + "uniqueItems": { + "type": "boolean", + "default": false + }, + "maxProperties": { "$ref": "#/definitions/positiveInteger" }, + "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" }, + "required": { "$ref": "#/definitions/stringArray" }, + "additionalProperties": { + "anyOf": [ + { "type": "boolean" }, + { "$ref": "#" } + ], + "default": {} + }, + "definitions": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} + }, + "properties": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} + }, + "patternProperties": { + "type": "object", + "additionalProperties": { "$ref": "#" }, + "default": {} + }, + "dependencies": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { "$ref": "#" }, + { "$ref": "#/definitions/stringArray" } + ] + } + }, + "enum": { + "type": "array", + "minItems": 1, + "uniqueItems": true + }, + "type": { + "anyOf": [ + { "$ref": "#/definitions/simpleTypes" }, + { + "type": "array", + "items": { "$ref": "#/definitions/simpleTypes" }, + "minItems": 1, + "uniqueItems": true + } + ] + }, + "allOf": { "$ref": "#/definitions/schemaArray" }, + "anyOf": { "$ref": "#/definitions/schemaArray" }, + "oneOf": { "$ref": "#/definitions/schemaArray" }, + "not": { "$ref": "#" } + }, + "dependencies": { + "exclusiveMaximum": [ "maximum" ], + "exclusiveMinimum": [ "minimum" ] + }, + "default": {} +} diff --git a/src/hos_libvariant/src/src/varsh.cc b/src/hos_libvariant/src/src/varsh.cc new file mode 100644 index 00000000..3595288e --- /dev/null +++ b/src/hos_libvariant/src/src/varsh.cc @@ -0,0 +1,233 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief Variant tool + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace libvariant; + +struct State { + SerializeType stype; + AdvSchemaLoader loader; + Variant conf; +}; + +void Process(State &state, ostream &out, istream &in) { + Variant data; + SerializeType itype; + if (state.conf.Get("guess-in", false).AsBool()) { itype = SERIALIZE_GUESS; } + if (state.conf.Get("json-in", false).AsBool()) { itype = SERIALIZE_JSON; } + if (state.conf.Get("yaml-in", false).AsBool()) { itype = SERIALIZE_YAML; } + if (state.conf.Get("plist-in", false).AsBool()) { itype = SERIALIZE_XMLPLIST; } + if (state.conf.Get("bundlehdr-in", false).AsBool()) { itype = SERIALIZE_BUNDLEHDR; } + + if (state.conf.Get("payload-in", false).AsBool()) { + data = DeserializeWithPayloadFile(in.rdbuf(), itype); + } else { + data = DeserializeFile(in.rdbuf(), itype); + } + + if (state.conf.GetPath("extension/flatten", false).AsBool()) { + data = FlattenPath( data, state.conf.GetPath("extension/params") ); + } + else if (state.conf.GetPath("extension/expand", false).AsBool()) { + data = ExpandPath( data, state.conf.GetPath("extension/params") ); + } + + Variant conf = state.conf; + if (conf.Contains("schemas")) { + for (Variant::ListIterator i(conf["schemas"].ListBegin()), e(conf["schemas"].ListEnd()); i != e; ++i) { + SchemaResult result = SchemaValidate(*i, data, &state.loader); + if (result.Error()) { + cerr << result << endl; + exit(1); + } + } + } + if (conf.Contains("set")) { + if (!conf.Contains("path")) { + data = conf["set"]; + } else { + data.SetPath(conf["path"].AsString(), conf["set"]); + } + } else { + if (conf.Contains("path")) { + data = data.GetPath(conf["path"].AsString()); + } + } + if (conf.Contains("list") && conf["list"].AsBool()) { + for (Variant::MapIterator i(data.MapBegin()), e(data.MapEnd()); i != e; ++i) { + out << i->first << endl; + } + } else if (conf.Contains("len") && conf["len"].AsBool()) { + out << data.Size() << endl; + } else { + if (state.conf.Get("payload", false).AsBool()) { + SerializeWithPayload(out.rdbuf(), data, state.stype, conf["sparams"]); + } else { + Serialize(out.rdbuf(), data, state.stype, conf["sparams"]); + out << endl; + } + } +} + +int main(int argc, char **argv) { + ArgParse opts(*argv); + opts.AddOption("schema_path", 0, "schema-path", "Add a search path for schemas.") + .Action(ARGACTION_APPEND).Type(ARGTYPE_STRING); + opts.AddOption("schemas", 0, "schema", "Add a schema uri to verify against.") + .Action(ARGACTION_APPEND).Type(ARGTYPE_STRING); + opts.AddOption("path", 0, "path", "Set a path name to operate on rather than the whole document.") + .Type(ARGTYPE_STRING); + + opts.AddOption("set", 0, "set", "Specify the value to set at the acting path."); + opts.AddOption("set-file", 0, "set-file", "Specify a file that should be read to set at the acting path.") + .Type(ARGTYPE_STRING); + opts.AddFlag("list", 0, "list", "Print a list of keys at the acting path."); + opts.AddFlag("len", 0, "length", "Print the length of the object at the acting path."); + opts.AddGroup("set").Add("set").Add("set-file").Add("list").Add("len").MutuallyExclusive(); + + opts.AddOption("output", 'o', "out", "Specify a file to output rather than standard out.") + .Type(ARGTYPE_STRING); + + opts.AddOption("guess-in", 'G', "guess", "Specify input format should be guessed (only guesses between json/yaml/plist)").Type(ARGTYPE_BOOL).Action(ARGACTION_STORE_TRUE) + .Default(true); + opts.AddOption("json-in", 'J', "json-in", "Specify input to be JSON").Type(ARGTYPE_BOOL).Action(ARGACTION_STORE_TRUE); +#ifdef ENABLE_YAML + opts.AddOption("yaml-in", 'Y', "yaml-in", "Specify input to be YAML").Type(ARGTYPE_BOOL).Action(ARGACTION_STORE_TRUE).Group("type-in"); +#endif +#ifdef ENABLE_XML + opts.AddOption("plist-in", 'X', "xml-in", "Specify input to be XML-PLIST").Type(ARGTYPE_BOOL).Action(ARGACTION_STORE_TRUE).Group("type-in"); +#endif + opts.AddOption("bundlehdr-in", 'B', "bundlehdr-in", "Specify input to be bundle header").Type(ARGTYPE_BOOL).Action(ARGACTION_STORE_TRUE) + .Group("type-in"); + opts.AddGroup("type-in").Add("guess-in").Add("json-in").MutuallyExclusive(); + + opts.AddFlag("payload-in", 'P', "payload-in", "Run input through the WithPayload functions instead of regular"); + + opts.AddOption("json", 'j', "json", "Specify output to be JSON").Default(true).Type(ARGTYPE_BOOL).Action(ARGACTION_STORE_TRUE); +#ifdef ENABLE_YAML + opts.AddOption("yaml", 'y', "yaml", "Specify output to be YAML").Type(ARGTYPE_BOOL).Action(ARGACTION_STORE_TRUE).Group("type"); +#endif +#ifdef ENABLE_XML + opts.AddOption("plist", 'x', "xml", "Specify output to be XML-PLIST").Type(ARGTYPE_BOOL).Action(ARGACTION_STORE_TRUE).Group("type"); +#endif + opts.AddOption("bundlehdr", 'b', "bundlehdr", "Specify output to be bundle header").Type(ARGTYPE_BOOL).Action(ARGACTION_STORE_TRUE) + .Group("type"); + opts.AddGroup("type").Add("json").MutuallyExclusive(); + + opts.AddFlag("payload", 'p', "payload", "Run output through the WithPayload functions instead of regular"); + + opts.AddGroup("format", "Format specifiers"); + opts.AddOption("sparams/pretty", 0, "pretty", "Pretty print.").Default(true).Type(ARGTYPE_BOOL).Group("format"); + opts.AddOption("sparams/indent", 0, "indent", "Set indent.").Type(ARGTYPE_INT).Minimum(0).Group("format"); + opts.AddOption("sparams/precision", 0, "precision", "Floating point precision.").Type(ARGTYPE_INT).Minimum(0).Group("format"); + + opts.AddOption("sparams/width", 0, "width", "Set prefered line width (YAML only)").Type(ARGTYPE_INT).Minimum(0).Group("format"); + + opts.AddOption("sparams/scalar_style", 0, "scalar-style", "Set default scalar style (YAML only)").Type(ARGTYPE_STRING).Group("format") + .AddChoice("any").AddChoice("plain").AddChoice("single quoted").AddChoice("double quoted").AddChoice("folded"); + + opts.AddOption("sparams/map_style", 0, "map-style", "Set default map style (YAML only)").Type(ARGTYPE_STRING).Group("format") + .AddChoice("any").AddChoice("block").AddChoice("flow"); + + opts.AddOption("sparams/list_style", 0, "list-style", "Set default list style (YAML only)").Type(ARGTYPE_STRING).Group("format") + .AddChoice("any").AddChoice("block").AddChoice("flow"); + + opts.AddOption("sparams/implicit_document_begin", 0, "implicit-document-begin", "Set to let the emitter omit the document begin tag (YAML only)") + .Group("format") .Type(ARGTYPE_BOOL); + + opts.AddOption("sparams/implicit_document_end", 0, "implicit-document-end", "Set to let the emitter omit the document end tag (YAML only)") + .Group("format") .Type(ARGTYPE_BOOL); + + opts.AddFlag("extension/flatten", 'f', "flatten-path", "Flatten the paths using Flatten/Expand path format specifiers"); + opts.AddFlag("extension/expand", 'e', "expand-path", "Expand the paths using Flatten/Expand path format specifiers"); + + opts.AddGroup("extension-format", "Flatten/Expand path format specifiers"); + + opts.AddOption("extension/params/noSimpleLists", 0, "no-simple-lists") + .Type(ARGTYPE_BOOL).Default(false).Group("extension-format"); + + opts.AddOption("extension/params/pathPrefix", 0, "path-prefix") + .Type(ARGTYPE_STRING).Default("").Group("extension-format").MaxLength(1); + + opts.AddOption("extension/params/pathDelimiter", 0, "path-delimiter") + .Type(ARGTYPE_STRING).Default("/").Group("extension-format").MaxLength(1); + + opts.AddOption("extension/params/indexPrefix", 0, "index-prefix") + .Type(ARGTYPE_STRING).Default("[").Group("extension-format").MaxLength(1); + + opts.AddOption("extension/params/indexSuffix", 0, "index-suffix") + .Type(ARGTYPE_STRING).Default("]").Group("extension-format").MaxLength(1); + + opts.AddOption("extension/params/listDelimiter", 0, "list-delimiter") + .Type(ARGTYPE_STRING).Default(",").Group("extension-format").MaxLength(1); + + opts.AddArgument("input", "The files to read in, if absent read stdin.").Action(ARGACTION_APPEND).MinArgs(0).MaxArgs(0); + + State state; + state.conf = opts.Parse(argc, argv); + + if (state.conf.Get("json", false).AsBool()) { state.stype = SERIALIZE_JSON; } + if (state.conf.Get("yaml", false).AsBool()) { state.stype = SERIALIZE_YAML; } + if (state.conf.Get("plist", false).AsBool()) { state.stype = SERIALIZE_XMLPLIST; } + if (state.conf.Get("bundlehdr", false).AsBool()) { state.stype = SERIALIZE_BUNDLEHDR; } + + state.loader.AddPath("."); + + if (state.conf.Contains("schema_path")) { + for (Variant::ListIterator i(state.conf["schema_path"].ListBegin()), e(state.conf["schema_path"].ListEnd()); i != e; ++i) { + state.loader.AddPath(i->AsString()); + } + } + + if (state.conf.Contains("set-file")) { + state.conf["set"] = DeserializeGuessFile(state.conf["set-file"].AsString().c_str()); + } + + ofstream output_file; + ostream *output = &cout; + if (state.conf.Contains("output")) { + output_file.open(state.conf["output"].AsString().c_str()); + output = &output_file; + } + + if (state.conf.Contains("input")) { + for (Variant::ListIterator i(state.conf["input"].ListBegin()), e(state.conf["input"].ListEnd()); i != e; ++i) { + ifstream input(i->AsString().c_str()); + Process(state, *output, input); + } + } else { + Process(state, *output, cin); + } + return 0; +} + + diff --git a/src/hos_libvariant/src/test/CMakeLists.txt b/src/hos_libvariant/src/test/CMakeLists.txt new file mode 100644 index 00000000..484f7875 --- /dev/null +++ b/src/hos_libvariant/src/test/CMakeLists.txt @@ -0,0 +1,114 @@ + +include_directories ("../src") + +add_executable(rand_test_json rand_test_json.cc) +target_link_libraries(rand_test_json Variant) +add_test(rand_test_json ${CMAKE_CURRENT_BINARY_DIR}/rand_test_json) + +if(LIBVARIANT_ENABLE_YAML) + add_executable(rand_test_yaml rand_test_yaml.cc) + target_link_libraries(rand_test_yaml Variant) + add_test(rand_test_yaml ${CMAKE_CURRENT_BINARY_DIR}/rand_test_yaml) + + add_executable(test_yaml_parser test_yaml_parser.cc) + target_link_libraries(test_yaml_parser Variant) + add_test(test_yaml_parser ${CMAKE_CURRENT_BINARY_DIR}/test_yaml_parser) + + add_executable(test_loadall test_loadall.cc) + target_link_libraries(test_loadall Variant) + add_test(test_loadall ${CMAKE_CURRENT_BINARY_DIR}/test_loadall) +endif() + +if(LIBVARIANT_ENABLE_XML) + add_executable(rand_test_xml rand_test_xml.cc) + target_link_libraries(rand_test_xml Variant) + add_test(rand_test_xml ${CMAKE_CURRENT_BINARY_DIR}/rand_test_xml) + + add_executable(test_xml_parser test_xml_parser.cc) + target_link_libraries(test_xml_parser Variant) + add_test(test_xml_parser ${CMAKE_CURRENT_BINARY_DIR}/test_xml_parser) +endif() + +add_executable(test_variant test_variant.cc) +target_link_libraries(test_variant Variant) +add_test(test_variant ${CMAKE_CURRENT_BINARY_DIR}/test_variant) + +add_executable(test_empty test_empty.cc) +target_link_libraries(test_empty Variant) +add_test(test_empty ${CMAKE_CURRENT_BINARY_DIR}/test_empty) + +add_executable(test_base64 test_base64.cc) +target_link_libraries(test_base64 Variant) +add_test(test_base64 ${CMAKE_CURRENT_BINARY_DIR}/test_base64) + +add_executable(test_memoryoutput test_memoryoutput.cc) +target_link_libraries(test_memoryoutput Variant) +add_test(test_memoryoutput ${CMAKE_CURRENT_BINARY_DIR}/test_memoryoutput) + +add_executable(test_bundlehdr test_bundlehdr.cc) +target_link_libraries(test_bundlehdr Variant) +add_test(test_bundlehdr ${CMAKE_CURRENT_BINARY_DIR}/test_bundlehdr) + +add_executable(test_bundleparser test_bundleparser.cc) +target_link_libraries(test_bundleparser Variant) +add_test(test_bundleparser ${CMAKE_CURRENT_BINARY_DIR}/test_bundleparser) + +add_executable(test_bundleemitter test_bundleemitter.cc) +target_link_libraries(test_bundleemitter Variant) +add_test(test_bundleemitter ${CMAKE_CURRENT_BINARY_DIR}/test_bundleemitter) + +add_executable(test_guess test_guess.cc) +target_link_libraries(test_guess Variant) +add_test(test_guess ${CMAKE_CURRENT_BINARY_DIR}/test_guess) + +add_executable(test_numerics test_numerics.cc) +target_link_libraries(test_numerics Variant) +add_test(test_numerics ${CMAKE_CURRENT_BINARY_DIR}/test_numerics) + +add_definitions("-DTEST_SCHEMA_DATA=\"${CMAKE_CURRENT_SOURCE_DIR}/test_schema_data/\"") +add_executable(test_schema test_schema.cc) +target_link_libraries(test_schema Variant) +add_test(test_schema ${CMAKE_CURRENT_BINARY_DIR}/test_schema) + +add_executable(test_path test_path.cc) +target_link_libraries(test_path Variant) +add_test(test_path ${CMAKE_CURRENT_BINARY_DIR}/test_path) + +add_executable(test_extensions test_extensions.cc) +target_link_libraries(test_extensions Variant) +add_test(test_extensions ${CMAKE_CURRENT_BINARY_DIR}/test_extensions) + +add_executable(test_argparse test_argparse.cc) +target_link_libraries(test_argparse Variant) +configure_file(test_argparse.sh.in + "${CMAKE_CURRENT_BINARY_DIR}/test_argparse.sh" @ONLY) +add_test(test_argparse sh ${CMAKE_CURRENT_BINARY_DIR}/test_argparse.sh) + + +add_executable(test_payload test_payload.cc) +target_link_libraries(test_payload Variant) +add_test(test_payload ${CMAKE_CURRENT_BINARY_DIR}/test_payload) + +add_executable(test_roundtrip test_roundtrip.cc) +target_link_libraries(test_roundtrip Variant) +add_test(test_roundtrip ${CMAKE_CURRENT_BINARY_DIR}/test_roundtrip) + +add_executable(test_argparse_merge test_argparse_merge.cc) +target_link_libraries(test_argparse_merge Variant) +add_test(test_argparse_merge ${CMAKE_CURRENT_BINARY_DIR}/test_argparse_merge) + +add_executable(test_json_parser test_json_parser.cc) +target_link_libraries(test_json_parser Variant) +add_test(test_json_parser ${CMAKE_CURRENT_BINARY_DIR}/test_json_parser) + +if(LIBVARIANT_ENABLE_MSGPACK) + + add_executable(prof_msgpack prof_msgpack.cc) + target_link_libraries(prof_msgpack Variant) + add_test(prof_msgpack ${CMAKE_CURRENT_BINARY_DIR}/prof_msgpack) + + add_executable(rand_test_msgpack rand_test_msgpack.cc) + target_link_libraries(rand_test_msgpack Variant) + add_test(rand_test_msgpack ${CMAKE_CURRENT_BINARY_DIR}/rand_test_msgpack) + +endif() diff --git a/src/hos_libvariant/src/test/TestAssert.h b/src/hos_libvariant/src/test/TestAssert.h new file mode 100644 index 00000000..7c5db218 --- /dev/null +++ b/src/hos_libvariant/src/test/TestAssert.h @@ -0,0 +1,20 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#ifndef TEST_ASSERT_H +#define TEST_ASSERT_H +#include +#include + +inline void test_assert_throw(const char *file, unsigned line, const char *expression) { + std::ostringstream oss; + oss << "Assert failed in " << file << " line " << line + << "\nExpression: " << expression; + throw std::runtime_error(oss.str()); +} + +#define ASSERT(x) if (!(x)) { test_assert_throw(__FILE__, __LINE__, #x); } else (void)0 + +#endif diff --git a/src/hos_libvariant/src/test/TestCommon.h b/src/hos_libvariant/src/test/TestCommon.h new file mode 100644 index 00000000..110c5b2e --- /dev/null +++ b/src/hos_libvariant/src/test/TestCommon.h @@ -0,0 +1,103 @@ +/** \file + * \author John Bridgman + * \brief + */ +#ifndef TESTCOMMON_H +#define TESTCOMMON_H + +#pragma once +#include "../../src/src/EventBuffer.h" +#include "../../src/include/Variant/Variant.h" +#include "../../src/include/Variant/Parser.h" +#include "../../src/include/Variant/Emitter.h" +#include +#include +#include +#include + +namespace libvariant { + +inline bool ErrorCheckEventBuffer(shared_ptr expected, shared_ptr result) { + if (!result->Equal(*expected)) { + if (result->NumEvents() != expected->NumEvents()) { + std::cout << "Error size of action are different, got " << result->NumEvents() << " expected " << expected->NumEvents() << "\n"; + } + for (unsigned i = 0; i < std::max(expected->NumEvents(), result->NumEvents()); ++i) { + if (i < expected->NumEvents() && i < result->NumEvents()) { + if (!(expected->GetEvent(i) == result->GetEvent(i))) { + std::cout << "Action number " << i << " not expected action\nExpected: " << expected->GetEvent(i) + << "\nGot: " << result->GetEvent(i) << "\n"; + } + } else if (i < expected->NumEvents()) { + std::cout << "Action in original not in result: " << expected->GetEvent(i) << "\n"; + } else if (i < result->NumEvents()) { + std::cout << "Action in result not in original: " << result->GetEvent(i) << "\n"; + } + } + return false; + } + return true; +} + +inline int DoRandomTest(int argc, char **argv, +libvariant::Emitter (*Emitter_t)(libvariant::shared_ptr, libvariant::Variant), +libvariant::Parser (*Parser_t)(libvariant::shared_ptr), bool allow_nan) { + int verbose = 0; + int num_tests = 100; + while (true) { + int c = getopt(argc, argv, "n:v:s:h"); + if (c == -1) break; + switch (c) { + case 'n': + num_tests = atoi(optarg); + break; + case 'v': + verbose = atoi(optarg); + break; + case 's': + srand(strtoll(optarg, 0, 0)); + break; + default: + std::cout << *argv << " -s seed -v verbosity -n num_tests\n"; + return 0; + } + } + for (int test = 0; test < num_tests; ++test) { + if (verbose > 0) { std::cout << "Performing test " << test << "\n"; } + shared_ptr expected(new EventBuffer); + expected->FillRandom(EventBuffer::NO_EVENT, 10, allow_nan); + if (verbose > 0) { std::cout << "Generated " << expected->NumEvents() << " events\n"; } + std::ostringstream oss; + libvariant::Variant params; + libvariant::Emitter emitter = Emitter_t(libvariant::CreateEmitterOutput(oss.rdbuf()), params); + shared_ptr event_copy(new EventBuffer(*expected)); + event_copy->Playback(emitter); + emitter.Close(); + std::string val = oss.str(); + if (verbose > 1) { + std::cout << val; + std::cout.flush(); + } + std::istringstream iss(val); + libvariant::Parser parser = Parser_t(libvariant::CreateParserInputFile(iss.rdbuf())); + shared_ptr result(new EventBuffer); + result->Fill(parser); + + bool err = !ErrorCheckEventBuffer(expected, result); + if (err) return 1; + if (verbose > 0) { printf("End test %d\n\n", test); } + } + + return 0; +} + +inline Variant GenerateRandomVariant(bool allow_nan) { + shared_ptr events(new EventBuffer); + events->FillRandom(EventBuffer::NO_EVENT, 10, allow_nan); + Parser p(events); + return ParseVariant(p); +} + +} + +#endif diff --git a/src/hos_libvariant/src/test/prof_msgpack.cc b/src/hos_libvariant/src/test/prof_msgpack.cc new file mode 100644 index 00000000..4336b3c3 --- /dev/null +++ b/src/hos_libvariant/src/test/prof_msgpack.cc @@ -0,0 +1,129 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include "TestCommon.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace libvariant; +using namespace std; + +static double getTime() { + timeval tv; + if (gettimeofday(&tv, 0) != 0) { + throw std::runtime_error(strerror(errno)); + } + return static_cast(tv.tv_sec) + 1e-6 * static_cast(tv.tv_usec); +} + +ostream &operator<<(ostream &os, Variant v) { + SerializeJSON(os.rdbuf(), v, true); + return os; +} + +static const char *suffix[] = { "y", "z", "a", "f", "p", "n", "u", "m", "", +"k", "M", "G", "T", "P", "E", "Z", "Y" }; +static const int suffix_len = sizeof(suffix)/sizeof(char *); + +class engrfmt { +public: + engrfmt(double v) + : value(v){} + + void Print(std::ostream &os) const { + double v = value; + int suffix_off = 8; + while (v >= 1e3 && suffix_off < suffix_len) { + v /= 1e3; + suffix_off++; + } + while (v < 1.0 && suffix_off > 0) { + v /= 1e-3; + suffix_off--; + } + os << v << suffix[suffix_off]; + } +private: + double value; +}; + +ostream &operator<<(ostream &os, const engrfmt &fmt) { + fmt.Print(os); + return os; +} + +std::vector msgpack_serialize_time; +std::vector msgpack_deserialize_time; +std::vector json_serialize_time; +std::vector json_deserialize_time; + +int DoTest(Variant v) { + stringstream ss_msgpack; + //cout << "Testing...\n" << v << endl; + double start = getTime(); + Serialize(ss_msgpack.rdbuf(), v, SERIALIZE_MSGPACK); + msgpack_serialize_time.push_back(getTime() - start); + start = getTime(); + Variant v2 = DeserializeFile(ss_msgpack.rdbuf(), SERIALIZE_MSGPACK); + msgpack_deserialize_time.push_back(getTime() - start); + if (v2 != v) { + cout << "Msgpack: Error not equal:\n"; + cout << "Expected: " << v << endl << "Got: " << v2 << endl; + return 1; + } + stringstream ss_json; + start = getTime(); + Serialize(ss_json.rdbuf(), v, SERIALIZE_JSON); + json_serialize_time.push_back(getTime() - start); + start = getTime(); + v2 = DeserializeFile(ss_json.rdbuf(), SERIALIZE_JSON); + json_deserialize_time.push_back(getTime() - start); + if (v2 != v) { + cout << "JSON: Error not equal:\n"; + cout << "Expected: " << v << endl << "Got: " << v2 << endl; + return 1; + } + return 0; +} + +int main(int argc, char **argv) { + int iterations = 100; + if (argc > 1) { + iterations = 1; + Variant v = DeserializeGuessFile(argv[1]); + if (DoTest(v)) { return 1; } + } else { + for (int i = 0; i < iterations; ++i) { + Variant v = GenerateRandomVariant(false); + if (DoTest(v)) { return 1; } + } + } + double mp_s_avg = 0, mp_d_avg = 0, j_s_avg = 0, j_d_avg = 0; + for (int i = 0; i < iterations; ++i) { + mp_s_avg += msgpack_serialize_time[i]; + mp_d_avg += msgpack_deserialize_time[i]; + j_s_avg += json_serialize_time[i]; + j_d_avg += json_deserialize_time[i]; + } + mp_s_avg /= iterations; + mp_d_avg /= iterations; + j_s_avg /= iterations; + j_d_avg /= iterations; + cout << "msgpack serialize avg time: " << engrfmt(mp_s_avg) << endl; + cout << "msgpack deserialize avg time: " << engrfmt(mp_d_avg) << endl; + cout << "msgpack avg time: " << engrfmt(mp_s_avg + mp_d_avg) << endl; + cout << "json serialize avg time: " << engrfmt(j_s_avg) << endl; + cout << "json deserialize avg time: " << engrfmt(j_d_avg) << endl; + cout << "json avg time: " << engrfmt(j_s_avg + j_d_avg) << endl; + cout << "serialize msgpack/json: " << (mp_s_avg/j_s_avg) << "\tjson/msgpack: " << (j_s_avg/mp_s_avg) << endl; + cout << "deserialize msgpack/json: " << (mp_d_avg/j_d_avg) << "\tjson/msgpack: " << (j_d_avg/mp_d_avg) << endl; + cout << "msgpack/json: " << ((mp_s_avg+mp_d_avg)/(j_s_avg+j_d_avg)) << "\tjson/msgpack: " << (j_s_avg+j_d_avg)/(mp_s_avg+mp_d_avg) << endl; + return 0; +} diff --git a/src/hos_libvariant/src/test/rand_test_json.cc b/src/hos_libvariant/src/test/rand_test_json.cc new file mode 100644 index 00000000..e7192310 --- /dev/null +++ b/src/hos_libvariant/src/test/rand_test_json.cc @@ -0,0 +1,12 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include "TestCommon.h" + +using namespace libvariant; + +int main(int argc, char **argv) { + return DoRandomTest(argc, argv, JSONEmitter, JSONParser, false); +} diff --git a/src/hos_libvariant/src/test/rand_test_msgpack.cc b/src/hos_libvariant/src/test/rand_test_msgpack.cc new file mode 100644 index 00000000..b57d664b --- /dev/null +++ b/src/hos_libvariant/src/test/rand_test_msgpack.cc @@ -0,0 +1,12 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include "TestCommon.h" + +using namespace libvariant; + +int main(int argc, char **argv) { + return DoRandomTest(argc, argv, MsgPackEmitter, MsgPackParser, true); +} diff --git a/src/hos_libvariant/src/test/rand_test_xml.cc b/src/hos_libvariant/src/test/rand_test_xml.cc new file mode 100644 index 00000000..0278dfd0 --- /dev/null +++ b/src/hos_libvariant/src/test/rand_test_xml.cc @@ -0,0 +1,11 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include "TestCommon.h" + +using namespace libvariant; + +int main(int argc, char **argv) { + return DoRandomTest(argc, argv, XMLPLISTEmitter, XMLPLISTParser, true); +} diff --git a/src/hos_libvariant/src/test/rand_test_yaml.cc b/src/hos_libvariant/src/test/rand_test_yaml.cc new file mode 100644 index 00000000..841245c7 --- /dev/null +++ b/src/hos_libvariant/src/test/rand_test_yaml.cc @@ -0,0 +1,11 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include "TestCommon.h" + +using namespace libvariant; + +int main(int argc, char **argv) { + return DoRandomTest(argc, argv, YAMLEmitter, YAMLParser, true); +} diff --git a/src/hos_libvariant/src/test/test_argparse.cc b/src/hos_libvariant/src/test/test_argparse.cc new file mode 100644 index 00000000..e8ce82b1 --- /dev/null +++ b/src/hos_libvariant/src/test/test_argparse.cc @@ -0,0 +1,181 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include +#include +#include +#include +#include + +using namespace libvariant; +using namespace std; + +SerializeType stype = SERIALIZE_JSON; +Variant sparams = Variant::MapType; + +Variant OtherConfig() { + ArgParse args; + args.AddOption("adv-option1", 's', "adv1", "adv1").Advanced(true); + args.AddOption("adv-option2", 0, "adv2", "adv2").Group("adv"); + args.AddGroup("adv", "adv group").Advanced(true); + return args.GetDescription(); +} + +int Compare(Variant exp, Variant opts) { + for (Variant::MapIterator ci(exp.MapBegin()), ce(exp.MapEnd()); ci != ce; ++ci) { + if (!opts.Contains(ci->first)) { + cout << "Missing key " << ci->first << endl; + return 1; + } + if (ci->second.IsMap()) { + if (Compare(ci->second, opts[ci->first])) { + cout << "In sub map: \"" << ci->first << "\"\n"; + return 1; + } + } else if (opts[ci->first] != ci->second) { + cout << "Value at key \"" << ci->first << "\" differs\n"; + cout << "Got:\n"; + Serialize(cout.rdbuf(), opts[ci->first], stype, sparams); + cout << "\nExpected:\n"; + Serialize(cout.rdbuf(), ci->second, stype, sparams); + cout << endl; + return 1; + } + } + return 0; +} + +int main(int argc, char **argv) { + sparams["pretty"] = true; + + ArgParse args(*argv); + // store -- store the value into the key (default) + args.AddOption("store", 's', "store", "Test store number").Action(ARGACTION_STORE) + .Type(ARGTYPE_FLOAT).Env("TEST_STORE").Minimum(0).Maximum(1) + .Default(0.54321); + args.AddOption("store_bool", 0, "store_bool", "Test store boolean").Action(ARGACTION_STORE) + .Type(ARGTYPE_BOOL).Env("TEST_STORE_BOOLEAN"); + args.AddOption("store_int", 0, "store_int", "Test store int").Action(ARGACTION_STORE) + .Type(ARGTYPE_INT).Minimum(-10).Maximum(10).Default(0); + args.AddOption("store_string", 0, "store_string", "Test store string").Action(ARGACTION_STORE) + .Type(ARGTYPE_STRING).MinLength(4).MaxLength(10).Pattern("^[0-9a-zA-Z]*$") + .Default("abc123"); + try { + args.AddOption("store", 0, "blahblah", ""); + cerr << "Duplicate path successfully added." << endl; + return 1; + } catch (const std::runtime_error&) {} + try { + args.AddOption("blahblah", 0, "store", ""); + cerr << "Duplicate long option successfully added." << endl; + return 1; + } catch (const std::runtime_error&) {} + try { + args.AddOption("blahblah", 's', "", ""); + cerr << "Duplicate short option successfully added." << endl; + return 1; + } catch (const std::runtime_error&) {} + try { + args.AddOption("store", 0, "", ""); + cerr << "Option with no short or long opt sucessfully added." << endl; + return 1; + } catch (const std::runtime_error&) {} + try { + //args.AddOption("abc", 0, "abc", "").Type("abc"); + args.AddOption("abc", 0, "abc", "").Type((ArgParseType)Variant::MapType); + cerr << "Option with invalid type successfully added." << endl; + return 1; + } catch (const std::runtime_error&) {} + + //cerr << "Turning conflict resolution on" << endl; + args.ConflictResolution(true); + try { + args.AddOption("blahblah", 's', "", ""); + cerr << "Duplicate short option with no long option succesfully added" << endl; + return 1; + } catch (const std::runtime_error&) {} + try { + args.AddOption("blahblah", 's', "blahblah", ""); + } catch (const std::runtime_error&) { + cerr << "Failed to add duplicate short option with long option with conflict resolution on." << endl; + return 1; + } + + args.AddOption("store_undef", 0, "store_undef", "Test store").Action(ARGACTION_STORE); + // store_const -- store const (see Const) into the key + args.AddOption("store_const", 0, "store_const", "Test store const").Action(ARGACTION_STORE_CONST) + .Const(123); + // store_true -- store true into the key (i.e. no option argument) + args.AddOption("store_true", 0, "store_true", "Test store_true").Action(ARGACTION_STORE_TRUE) + .Default(false).Type(ARGTYPE_BOOL); + // store_false -- store false into the key + args.AddOption("store_false", 0, "store_false", "Test store_false").Action(ARGACTION_STORE_FALSE) + .Default(true).Type(ARGTYPE_BOOL); + // append -- make the value a list of instances of the option + args.AddOption("append", 0, "append", "Test append").Action(ARGACTION_APPEND) + .Type(ARGTYPE_FLOAT).Minimum(0).Maximum(1).MinArgs(1).MaxArgs(10); + // count -- count the number of instances of this argument + args.AddOption("count", 0, "count", "Test count").Action(ARGACTION_COUNT); + // config -- load a file and merge it into the result (uses GuessFormat) + args.AddOption("load", 0, "load", "Test config").Action(ARGACTION_CONFIG); + + args.AddOption("choice", 0, "choice", "Test choices").AddChoice("a").AddChoice("b"); + + args.AddOption("abc/a", 0, "abc-a", "abc-a"); + args.AddOption("abc/b", 0, "abc-b", "abc-b"); + args.AddGroup("abc", "abc").Add("abc/a").Add("abc/b").MutuallyExclusive(); + args.AddOption("abc/c", 0, "abc-c", "Test group mutual exclusion with default").Default(123); + args.AddOption("abc/d", 0, "abc-d", "Mutually exclusive wth abc-c"); + args.AddGroup("abc-m").Add("abc/c").Add("abc/d").MutuallyExclusive(); + + args.AddArgument("comp", "Comparison file for options") + .Action(ARGACTION_APPEND).Type(ARGTYPE_STRING).MinArgs(0); + + args.AddOption("shortonly", 'a', "", "short only option").Type(ARGTYPE_GUESS); + + args.AddOption("list[0]", 0, "list0", "List zero option").Title("ListOp1"); + args.AddOption("list[1]", 0, "list1", "List one option"); + args.AddOption("list[2]", 0, "list2", "List two option"); + + args.Merge(OtherConfig()); + args.AddConfigDefaults(); + + args.Validate(); + + Variant opts = args.Parse(argc, argv); + + ArgParse arg2; + arg2.Merge(args); + + Variant opt2 = arg2.Parse(argc, argv); + if (opts != opt2) { + cout << "Second parsing of option failed...\n"; + cout << "First pass gave:\n\n"; + Serialize(cout.rdbuf(), opts, stype, sparams); + cout << "\n\nsecond pass gave:\n\n"; + Serialize(cout.rdbuf(), opt2, stype, sparams); + cout << endl; + return 1; + } + + cout << "parsed arguments:\n\n"; + Serialize(cout.rdbuf(), opts, stype, sparams); + cout << "\n\n"; + cout << "Validating..."; + SchemaResult valres = SchemaValidate(args.GenerateSchema(), opts); + if (valres.Error()) { + cout << endl << valres << endl << endl; + return 1; + } else { cout << " passed\n\n"; } + + Variant::ListIterator i(opts["comp"].ListBegin()), + e(opts["comp"].ListEnd()); + while (i != e) { + Variant comp = DeserializeGuessFile(i->AsString().c_str()); + if (Compare(comp, opts)) { return 1; } + ++i; + } + return 0; +} diff --git a/src/hos_libvariant/src/test/test_argparse.sh.in b/src/hos_libvariant/src/test/test_argparse.sh.in new file mode 100644 index 00000000..a6ac5243 --- /dev/null +++ b/src/hos_libvariant/src/test/test_argparse.sh.in @@ -0,0 +1,104 @@ +#!/bin/sh + +ex=@CMAKE_CURRENT_BINARY_DIR@/test_argparse + +echo "Test required argument" +if $ex; then exit 1; fi +echo "Test append argument minimum" +if $ex --append -1; then exit 1; fi +echo "Test append argument maximum" +if $ex --append 2; then exit 1; fi +echo "Test store minimum" +if $ex -s'-1' --append 1; then exit 1; fi +echo "Test store maximum" +if $ex -s'2' --append 1; then exit 1; fi + +echo "Testing store boolean" +if ! echo '{ "store_bool": true }' | $ex --append 1 --store_bool=yes /dev/stdin; then exit 1; fi +if ! echo '{ "store_bool": true }' | $ex --append 1 --store_bool=Y /dev/stdin; then exit 1; fi +if ! echo '{ "store_bool": true }' | $ex --append 1 --store_bool=t /dev/stdin; then exit 1; fi +if ! echo '{ "store_bool": true }' | $ex --append 1 --store_bool=1 /dev/stdin; then exit 1; fi +if ! echo '{ "store_bool": false }' | $ex --append 1 --store_bool=N /dev/stdin; then exit 1; fi +if ! echo '{ "store_bool": false }' | $ex --append 1 --store_bool=no /dev/stdin; then exit 1; fi +if ! echo '{ "store_bool": false }' | $ex --append 1 --store_bool=0 /dev/stdin; then exit 1; fi +if ! echo '{ "store_bool": false }' | $ex --append 1 --store_bool=f /dev/stdin; then exit 1; fi +if ! echo '{ "store_bool": true }' | TEST_STORE_BOOLEAN=yes $ex --append 1 /dev/stdin; then exit 1; fi + +echo "Test store integer" + +if $ex --append 1 --store_int -11; then exit 1; fi +if $ex --append 1 --store_int 11; then exit 1; fi +if $ex --append 1 --store_int 'abc'; then exit 1; fi +if $ex --append 1 --store_int 1.4; then exit 1; fi +if ! echo '{ "store_int": 4}' | $ex --append 1 --store_int 4 /dev/stdin; then exit 1; fi + +echo "Test store string" +if $ex --append 1 --store_string "@#$^aaa"; then exit 1; fi +if $ex --append 1 --store_string "a"; then exit 1; fi +if $ex --append 1 --store_string "0123456789aaaaaa"; then exit 1; fi +if ! echo '{ "store_string": "abc123" }' | $ex --append 1 /dev/stdin; then exit 1; fi +if ! echo '{ "store_string": "7j34d" }' | $ex --append 1 --store_string 7j34d /dev/stdin; then exit 1; fi + +if $ex --append 1 --choice "aaaa"; then exit 1; fi +if ! echo '{ "choice": "a" }' | $ex --append 1 --choice "a" /dev/stdin; then exit 1; fi +if ! echo '{ "choice": "b" }' | $ex --append 1 --choice "b" /dev/stdin; then exit 1; fi + +echo "Test group mutual exclusion" +if $ex --append 1 --abc-a=1 --abc-b=2; then exit 1; fi +if ! echo '{ "abc": { "a": 1 } }' | $ex --append 1 --abc-a=1 /dev/stdin; then + exit 1 +fi +if ! echo '{ "abc": { "b": 1 } }' | $ex --append 1 --abc-b=1 /dev/stdin; then + exit 1 +fi + +if $ex --append 1 --abc-c=1 --abc-d=2; then exit 1; fi +if ! echo '{ "abc": { "c": 1 } }' | $ex --append 1 --abc-c=1 /dev/stdin; then + exit 1 +fi +if ! echo '{ "abc": { "d": 1 } }' | $ex --append 1 --abc-d=1 /dev/stdin; then + exit 1 +fi +if ! echo '{ "abc": { "c": 123 } }' | $ex --append 1 /dev/stdin; then exit 1; fi + +echo "Generic tests" +expected=' +{ + "append": [ 0.1 ], + "store": 0.54321, + "store_int": 0, + "store_string": "abc123", + "store_true": false, + "store_false": true +}'; + +if ! echo $expected | $ex --append 0.1 /dev/stdin; then exit 1; fi + +expected=' +{ + "store": 0.5, + "append": [ 1, 0.4 ], + "store_bool": true, + "store_int": 5, + "store_string": "zxcv098784", + "store_undef": true, + "store_true": true, + "store_const": 123, + "store_false": false, + "count": 3, + "comp": [ "/dev/stdin" ] +} +'; +echo $expected | $ex --store 0.5 --append 1 --append 0.4 --store_bool yes --store_int 5 --store_string "zxcv098784" \ + --store_undef true --store_true --store_false --count --store_const --count --count /dev/stdin; +if [[ $? != 0 ]]; then exit 1; fi; + +tmpfile=$(mktemp) +echo $expected >$tmpfile +echo $expected | $ex --config $tmpfile; +if [[ $? != 0 ]]; then exit 1; fi; +rm $tmpfile + +echo "PASS!!"; +exit 0; + diff --git a/src/hos_libvariant/src/test/test_argparse_merge.cc b/src/hos_libvariant/src/test/test_argparse_merge.cc new file mode 100644 index 00000000..fd8c33d1 --- /dev/null +++ b/src/hos_libvariant/src/test/test_argparse_merge.cc @@ -0,0 +1,109 @@ +//============================================================================= +//! \file main.cc +//! \author Josh Staley +//============================================================================= + +//=== Includes ================================================================ + +#include +#include +#include + +#include + +using namespace std; +using namespace libvariant; + +//=== Foo ===================================================================== + +class Foo { + +public: + + Foo ( Variant opts = Variant::MapType ): + mOpts ( opts ) + { + SchemaResult result = SchemaValidate( Foo::GetArgParse().GenerateSchema(), mOpts ); + if ( result.Error() ) + cerr << "# Foo: " << result.PrettyPrintMessage() << endl; + } + + static ArgParse GetArgParse () + { + ArgParse argParse; + + // -v --verbose + argParse.AddOption( "foo/verbosity", 'v', "foo-verbose", + "Set foo verbosity level" + ).Action( ARGACTION_COUNT ).Default(0); + + argParse.AddOption( "list[0]/foo", 'f', "foo", "FoOOooOooOoo!" ); + + return argParse; + } + +private: + + Variant mOpts; + +}; + +//=== Bar ===================================================================== + +class Bar { + +public: + + Bar ( Variant opts = Variant::MapType ): + mOpts ( opts ) + { + SchemaResult result = SchemaValidate( Bar::GetArgParse().GenerateSchema(), mOpts ); + if ( result.Error() ) + cerr << "# Bar: " << result.PrettyPrintMessage() << endl; + } + + static ArgParse GetArgParse () + { + ArgParse argParse; + + // -v --verbose + argParse.AddOption( "bar/verbosity", 'v', "bar-verbose", + "Set bar verbosity level" + ).Action( ARGACTION_COUNT ).Default(0); + + argParse.AddOption( "list[1]/bar", 'b', "bar", "BaaaaAAAaaar!" ); + + return argParse; + } + +private: + + Variant mOpts; + +}; + +//=== Main ==================================================================== + +int main ( int argc, char *argv[] ) +{ + ArgParse argParse( "Test" ); + argParse.ConflictResolution(); + argParse.Merge( Foo::GetArgParse() ); + argParse.Merge( Bar::GetArgParse() ); + Variant opts = argParse.Parse( argc, argv ); + + Foo foo( opts ); + Bar bar( opts ); + + cout << "--- Foo ---" << endl; + cout << Serialize( Foo::GetArgParse().GenerateSchema(), SERIALIZE_JSON, Variant().Set( "pretty", true ) ) << endl; + + cout << "--- Bar ---" << endl; + cout << Serialize( Bar::GetArgParse().GenerateSchema(), SERIALIZE_JSON, Variant().Set( "pretty", true ) ) << endl; + + cout << "--- Merged ---" << endl; + cout << Serialize( argParse.GenerateSchema(), SERIALIZE_JSON, Variant().Set( "pretty", true ) ) << endl; + return 0; +} + +//============================================================================= diff --git a/src/hos_libvariant/src/test/test_base64.cc b/src/hos_libvariant/src/test/test_base64.cc new file mode 100644 index 00000000..5bc66f81 --- /dev/null +++ b/src/hos_libvariant/src/test/test_base64.cc @@ -0,0 +1,1032 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include "Base64.h" +#include +#include +#include +using namespace libvariant; + +unsigned char test_data[] = { + 0xde, 0xc1, 0x9a, 0x7c, 0xc6, 0xdb, 0xda, 0x3d, 0x77, 0xc5, 0x37, 0xf7, + 0x2c, 0xf1, 0x15, 0x47, 0xe4, 0x63, 0xe5, 0x68, 0x62, 0x8e, 0x6c, 0x09, + 0xbd, 0xd7, 0x74, 0xfc, 0x73, 0x00, 0xe8, 0x82, 0xc2, 0x7c, 0x73, 0x1b, + 0x26, 0xe5, 0x73, 0x6b, 0xf7, 0xcc, 0x15, 0xf6, 0xc2, 0x21, 0x8f, 0x3e, + 0x28, 0xd9, 0xb2, 0x96, 0xaf, 0x96, 0xef, 0xfe, 0xcd, 0x3a, 0x55, 0x68, + 0xc6, 0xaa, 0xe7, 0xfa, 0x36, 0x34, 0x34, 0xa9, 0xa7, 0xd9, 0x1f, 0x10, + 0x85, 0x98, 0xd5, 0x4a, 0x7b, 0x88, 0x04, 0xba, 0x6c, 0x36, 0xdb, 0x69, + 0x31, 0xbd, 0x06, 0x70, 0xfb, 0x06, 0x3a, 0x4b, 0x4f, 0xc2, 0x11, 0xca, + 0x5d, 0x3a, 0x11, 0x0d, 0x39, 0x40, 0x18, 0xa7, 0x5a, 0xd2, 0x7f, 0x85, + 0x4a, 0xcf, 0x3e, 0x9f, 0x02, 0x24, 0x07, 0x9b, 0x67, 0x1e, 0x09, 0x54, + 0xcf, 0xab, 0xb5, 0x18, 0xaa, 0xd3, 0xc7, 0xbd, 0x48, 0xd5, 0x17, 0xe6, + 0x16, 0x93, 0x8d, 0x2e, 0x84, 0xc0, 0x97, 0x71, 0xb4, 0x6a, 0xae, 0x2e, + 0x0b, 0x0c, 0x04, 0xad, 0xae, 0x28, 0x4e, 0x63, 0x22, 0x9b, 0x52, 0xfd, + 0x9e, 0xf3, 0xac, 0x54, 0x8d, 0xaa, 0xe4, 0x15, 0x68, 0x25, 0x6b, 0x3e, + 0x07, 0xd6, 0x0a, 0x15, 0x8f, 0x37, 0xa0, 0xb1, 0xbf, 0xd0, 0x24, 0xff, + 0x58, 0x73, 0xd6, 0xcd, 0xca, 0xc2, 0x32, 0x34, 0xb4, 0x09, 0x8d, 0xf8, + 0xf8, 0xa1, 0xa9, 0xba, 0xcc, 0xde, 0x1b, 0x79, 0x62, 0xd7, 0x47, 0xcf, + 0x32, 0x48, 0xbc, 0xc1, 0x66, 0xf5, 0x87, 0xf8, 0xcd, 0xa0, 0x5a, 0xee, + 0x4f, 0x8b, 0xf1, 0x68, 0xf8, 0xf4, 0x63, 0x19, 0x4c, 0xe0, 0x3c, 0x3b, + 0x1a, 0x69, 0x8f, 0xf6, 0x17, 0xe2, 0x38, 0x6c, 0x53, 0x9b, 0x90, 0x73, + 0x1f, 0xd6, 0x5d, 0x7d, 0xfa, 0xb7, 0x80, 0x83, 0xe8, 0x7a, 0xbd, 0x84, + 0x0a, 0xff, 0xdf, 0x02, 0xee, 0x29, 0x75, 0x6e, 0x25, 0x9d, 0x37, 0x90, + 0x62, 0x53, 0x5a, 0x88, 0xb9, 0x8e, 0x5a, 0xfa, 0x5f, 0x6c, 0x1f, 0xed, + 0x9a, 0x4b, 0x69, 0x0e, 0xd2, 0x61, 0xd3, 0x17, 0x57, 0x0c, 0x52, 0x32, + 0x43, 0x83, 0x6a, 0x3b, 0x41, 0x43, 0xa4, 0xbe, 0xb9, 0xbd, 0xd5, 0xe7, + 0xe5, 0xb2, 0x16, 0x59, 0xba, 0xb0, 0xf5, 0xbc, 0xe2, 0x5b, 0x79, 0x96, + 0xd2, 0xa0, 0xa3, 0x08, 0x76, 0xa8, 0xbb, 0xff, 0xcb, 0xf2, 0x15, 0x66, + 0x6c, 0x49, 0x9b, 0xcb, 0xc5, 0x8d, 0xb2, 0xc6, 0xea, 0xaa, 0x17, 0x09, + 0x1b, 0x1c, 0x87, 0xb9, 0x67, 0xc7, 0x85, 0xc1, 0x38, 0xe6, 0x2c, 0xd3, + 0x09, 0x97, 0xf8, 0xe0, 0xd2, 0xb1, 0x62, 0x72, 0xfc, 0x79, 0x77, 0x35, + 0xbb, 0x6e, 0x54, 0xdc, 0xdf, 0x9b, 0xcf, 0x46, 0xdb, 0xb2, 0xbb, 0xf9, + 0xb9, 0x7c, 0xa8, 0xeb, 0x01, 0x2e, 0x37, 0xb4, 0xfd, 0x3e, 0xa1, 0x82, + 0x6b, 0x31, 0x18, 0x72, 0x3a, 0x55, 0x7e, 0xc9, 0xb9, 0xc8, 0x1b, 0xdc, + 0xd9, 0xa0, 0x16, 0x4c, 0xfd, 0x6d, 0xfe, 0xf0, 0x6a, 0x66, 0x88, 0xb9, + 0x20, 0x6e, 0xb5, 0x4f, 0xbc, 0xdb, 0x94, 0xbb, 0x00, 0x4a, 0xa3, 0x3f, + 0x79, 0xc0, 0xf4, 0x18, 0x93, 0xa1, 0x2d, 0xec, 0xae, 0x5e, 0x42, 0xca, + 0x15, 0x01, 0x40, 0xd7, 0x59, 0x90, 0x0e, 0x92, 0x33, 0x98, 0x8f, 0xe0, + 0x68, 0xe4, 0xea, 0x8e, 0x37, 0x70, 0x3f, 0x4a, 0x83, 0x27, 0x08, 0xf0, + 0xc7, 0x39, 0x0f, 0x1c, 0x21, 0xb7, 0x6b, 0x2f, 0x9e, 0x73, 0x21, 0x23, + 0x16, 0x15, 0xdd, 0xc4, 0xbe, 0xef, 0x35, 0xea, 0xd8, 0x5e, 0xad, 0x83, + 0xa9, 0x13, 0xeb, 0x40, 0x94, 0x77, 0x9f, 0xdb, 0xdc, 0x97, 0x54, 0x01, + 0x15, 0x58, 0x09, 0x8d, 0x21, 0x1c, 0xe0, 0x3a, 0xc4, 0xbd, 0x75, 0x1b, + 0xef, 0x8a, 0xb5, 0x78, 0xaa, 0x23, 0x79, 0x69, 0xcc, 0x15, 0x43, 0xfa, + 0x65, 0xf5, 0x6a, 0xca, 0x23, 0x42, 0x7e, 0x8e, 0x19, 0xfb, 0x05, 0x43, + 0xae, 0x4c, 0x8a, 0xe6, 0xdb, 0x05, 0xc1, 0xbe, 0xd5, 0x31, 0x61, 0xab, + 0xd4, 0x8e, 0x89, 0x21, 0xe2, 0x1b, 0xa8, 0xcd, 0xa0, 0xf5, 0x9e, 0xd1, + 0x00, 0x3c, 0x05, 0xb6, 0x42, 0xba, 0x53, 0x8b, 0x52, 0x6b, 0x75, 0x99, + 0x76, 0x31, 0x09, 0x7f, 0x9d, 0xa5, 0xa3, 0xe4, 0x2f, 0x45, 0x8d, 0x7e, + 0x32, 0xd0, 0x33, 0xd3, 0xa4, 0xd2, 0x01, 0x67, 0x75, 0x08, 0xf7, 0x69, + 0x8e, 0x9d, 0xec, 0x63, 0x71, 0xa8, 0x3c, 0xcc, 0x2c, 0x15, 0x24, 0x3e, + 0x66, 0xcd, 0x24, 0xee, 0x78, 0xbc, 0x60, 0x4c, 0xd4, 0x4b, 0xc1, 0x50, + 0x44, 0xbe, 0xb4, 0x60, 0xb9, 0x22, 0x1b, 0x12, 0x33, 0x34, 0x1b, 0xa9, + 0x04, 0x9f, 0x01, 0x6b, 0xdd, 0x1f, 0x4c, 0x64, 0x98, 0x05, 0xb8, 0x7f, + 0xb3, 0x41, 0xd1, 0xee, 0xd8, 0xef, 0xb6, 0x61, 0x37, 0x22, 0x39, 0xa5, + 0x16, 0x0e, 0x9d, 0x93, 0x74, 0x6f, 0x32, 0xf0, 0xb1, 0x13, 0x00, 0x78, + 0x25, 0x96, 0x90, 0xcf, 0x8f, 0xe1, 0x1a, 0xa0, 0x81, 0xc5, 0x96, 0x1a, + 0x9c, 0x89, 0x94, 0xc7, 0xc3, 0x4c, 0xec, 0xe5, 0xa5, 0xb2, 0x4d, 0x6c, + 0x0f, 0x8d, 0x09, 0x34, 0x8e, 0x54, 0xc3, 0xbb, 0x51, 0xb7, 0x3e, 0x82, + 0xda, 0x5f, 0x21, 0x8f, 0xf3, 0x68, 0x82, 0x33, 0xcb, 0x64, 0x71, 0x9c, + 0xdf, 0xab, 0xfa, 0xb4, 0x57, 0xd9, 0x07, 0x78, 0xa2, 0xe8, 0xa6, 0xba, + 0x8c, 0x48, 0x2f, 0xb3, 0x96, 0x1c, 0x1d, 0xa4, 0x1c, 0xe0, 0x15, 0x6e, + 0xc4, 0x80, 0xd7, 0x4d, 0x78, 0xce, 0x9a, 0x77, 0x2a, 0x90, 0xe4, 0xde, + 0x66, 0x88, 0x54, 0xda, 0x14, 0x3f, 0x02, 0x30, 0x67, 0x23, 0x94, 0x76, + 0xc3, 0x28, 0xe4, 0x1b, 0xbf, 0x37, 0x13, 0x0f, 0xc9, 0xa9, 0xdd, 0x75, + 0x63, 0x41, 0x07, 0x7c, 0xad, 0xda, 0xb2, 0x62, 0x9c, 0xaf, 0x1d, 0x4b, + 0x46, 0x71, 0x16, 0xc8, 0xb4, 0x04, 0x62, 0xa3, 0x1c, 0x06, 0xdd, 0x58, + 0x3a, 0xb8, 0x83, 0x4b, 0x1c, 0xa8, 0x7b, 0xa8, 0x9c, 0x36, 0x1a, 0x01, + 0x23, 0x99, 0x10, 0xf6, 0x1d, 0x1e, 0x2e, 0x80, 0xe4, 0x46, 0x8a, 0x30, + 0x42, 0xc2, 0x48, 0x18, 0x70, 0x2a, 0x60, 0x52, 0xc0, 0x55, 0xc0, 0xef, + 0x2a, 0x2d, 0x44, 0x5e, 0xea, 0x77, 0x74, 0x81, 0xde, 0xed, 0x74, 0x48, + 0xac, 0x27, 0xf9, 0x5d, 0xff, 0xb2, 0xab, 0xd9, 0x6b, 0x03, 0x5a, 0x9f, + 0x6a, 0x7d, 0x7b, 0x05, 0xad, 0x76, 0x51, 0x9c, 0xc1, 0x46, 0x86, 0x9b, + 0x7b, 0x7d, 0x90, 0x57, 0x14, 0x35, 0xf8, 0xa4, 0xb6, 0xb7, 0xcd, 0x19, + 0x0a, 0x86, 0x37, 0x6a, 0xc3, 0xe9, 0xeb, 0x78, 0x77, 0x4d, 0x06, 0x0a, + 0xad, 0x0a, 0xec, 0xdb, 0x6e, 0xe5, 0xdc, 0x58, 0xba, 0x65, 0xbf, 0x01, + 0x76, 0x8a, 0xed, 0x0a, 0x88, 0x24, 0x95, 0x91, 0x14, 0x47, 0x52, 0x77, + 0xb1, 0x02, 0x19, 0x79, 0x78, 0xaf, 0x73, 0x37, 0x8c, 0xed, 0x07, 0x6e, + 0x64, 0xfe, 0xde, 0x29, 0x2d, 0x29, 0x95, 0x4e, 0xc8, 0x12, 0x65, 0x8c, + 0x93, 0x7f, 0xa7, 0xde, 0x88, 0x03, 0xb9, 0x14, 0x5e, 0xc2, 0x8c, 0x97, + 0x88, 0xe4, 0x30, 0x3a, 0xc8, 0x00, 0x52, 0x26, 0x61, 0x98, 0x8a, 0xdc, + 0x59, 0x1b, 0xc9, 0x98, 0x75, 0xf1, 0xbf, 0xc0, 0x79, 0xe0, 0x65, 0x29, + 0xd2, 0xc6, 0x51, 0x33, 0x67, 0xaf, 0x0f, 0xcb, 0x1a, 0x89, 0xce, 0xf9, + 0x27, 0x2d, 0x23, 0xc3, 0x56, 0x07, 0xb6, 0xb9, 0x74, 0x0a, 0x90, 0xcc, + 0x47, 0x53, 0xcf, 0x77, 0xa7, 0x9d, 0x03, 0xc6, 0x73, 0xce, 0x3e, 0xc5, + 0x5b, 0xfc, 0xc8, 0x6a, 0x18, 0x09, 0xac, 0x27, 0x66, 0x18, 0x7a, 0xba, + 0x9e, 0x3d, 0xd1, 0x0a, 0xdd, 0xc2, 0x1e, 0x40, 0x20, 0xf1, 0x05, 0x66, + 0xbb, 0x4c, 0xa0, 0x2b, 0xd0, 0x8b, 0x53, 0xcb, 0x35, 0x45, 0xa3, 0x0e, + 0x75, 0x8b, 0xea, 0x27, 0xcc, 0xb2, 0xa3, 0xd7, 0x7d, 0xaf, 0x60, 0xcb, + 0x62, 0xab, 0x2c, 0x24, 0x93, 0x29, 0xa7, 0x71, 0xed, 0x66, 0x26, 0x98, + 0xaf, 0xc9, 0x6b, 0x7d, 0x57, 0xc4, 0x4f, 0xb7, 0x48, 0x81, 0x0c, 0x1a, + 0xc3, 0x7e, 0xde, 0x33, 0xff, 0x12, 0xec, 0xe9, 0x6c, 0x2f, 0xcd, 0x67, + 0x16, 0x80, 0x67, 0x21, 0x6b, 0x09, 0x8d, 0x1b, 0xa4, 0xd0, 0xec, 0x63, + 0x07, 0xc2, 0x38, 0x50, 0xcd, 0x7a, 0xc3, 0xe5, 0x43, 0x1d, 0xd0, 0x22, + 0x86, 0x4f, 0xa3, 0x84, 0x07, 0xb2, 0xc3, 0x7d, 0x8e, 0xb4, 0xb1, 0x1d, + 0xe0, 0x73, 0x1b, 0xf9, 0x6f, 0xc9, 0x60, 0xa6, 0x78, 0x34, 0x60, 0x66, + 0xd1, 0x47, 0x26, 0x78, 0x11, 0x24, 0x39, 0x27, 0x33, 0xae, 0x38, 0x96, + 0x97, 0x7c, 0x14, 0x7d, 0xc5, 0x74, 0xd4, 0xaf, 0xb3, 0x7d, 0x28, 0x61, + 0xe5, 0x21, 0xc0, 0xba, 0xdc, 0xcf, 0x55, 0xba, 0x2a, 0x6f, 0xcc, 0x29, + 0x96, 0x5e, 0xca, 0x35, 0x7c, 0xbc, 0x93, 0xf0, 0xa8, 0xf8, 0x09, 0xc1, + 0xa5, 0xf1, 0xb2, 0x05, 0x64, 0xa1, 0xf8, 0x43, 0x62, 0xea, 0xce, 0x2a, + 0xc2, 0x95, 0xcc, 0x11, 0x0b, 0xf6, 0xff, 0x66, 0x50, 0xf0, 0xfe, 0xd1, + 0x95, 0xa5, 0xd1, 0x8a, 0x95, 0x00, 0x6b, 0x4a, 0x1c, 0x14, 0xdd, 0x7d, + 0xf6, 0x97, 0x07, 0xbe, 0x3b, 0x7d, 0x58, 0x4e, 0x09, 0xed, 0x9b, 0x13, + 0x6e, 0xca, 0xca, 0xf9, 0x66, 0x0f, 0xc3, 0x2a, 0xed, 0xd1, 0xe7, 0x3e, + 0x52, 0x0c, 0xde, 0x0d, 0xe3, 0x02, 0x4d, 0x29, 0xac, 0xae, 0x9f, 0xb8, + 0xb1, 0x46, 0x3c, 0xa4, 0xad, 0x27, 0x77, 0x39, 0x42, 0xc7, 0x09, 0x0a, + 0x12, 0x91, 0xfd, 0x3e, 0xd4, 0x00, 0x13, 0x9b, 0xd6, 0xe7, 0xc8, 0x88, + 0x35, 0x7b, 0x65, 0x26, 0x94, 0x74, 0x59, 0x1a, 0x9f, 0xc1, 0x3a, 0xa4, + 0x4a, 0x2b, 0xf0, 0xaa, 0x7e, 0xc9, 0x7c, 0x8f, 0xbf, 0x15, 0x32, 0xbd, + 0x8d, 0xb3, 0xa4, 0x8e, 0x1f, 0x15, 0x1d, 0x4b, 0xda, 0xf4, 0x20, 0xa5, + 0xcc, 0x09, 0xc3, 0x18, 0x18, 0x7e, 0xcb, 0xb3, 0x38, 0x56, 0x07, 0x67, + 0x75, 0x5d, 0x53, 0xde, 0x8f, 0xc9, 0x45, 0xac, 0x9e, 0xb2, 0xa9, 0x47, + 0xb0, 0x61, 0x87, 0xa0, 0x39, 0x8f, 0x86, 0xde, 0xa3, 0xc3, 0xc8, 0x76, + 0x9c, 0xc2, 0x75, 0x02, 0x81, 0x7c, 0xcf, 0x20, 0x98, 0xc7, 0x05, 0xfd, + 0xa6, 0x2f, 0x28, 0xdb, 0x96, 0xa4, 0xad, 0x05, 0xd7, 0xb2, 0x55, 0xef, + 0x3b, 0xa3, 0x30, 0x7a, 0x32, 0x34, 0x4e, 0x6c, 0xd3, 0x63, 0x9c, 0x85, + 0x88, 0xa3, 0x9a, 0x14, 0xdb, 0x6d, 0xa5, 0xaa, 0xa2, 0x45, 0x3e, 0xca, + 0x95, 0x96, 0x5d, 0x26, 0xd0, 0x8b, 0x1e, 0xf3, 0x1a, 0x3f, 0xe1, 0xca, + 0x24, 0x09, 0xc1, 0x9a, 0x1a, 0xbb, 0xba, 0x84, 0x70, 0x1b, 0x9b, 0x30, + 0xdc, 0x33, 0x16, 0xb5, 0x17, 0x37, 0x90, 0x78, 0x16, 0x2c, 0x09, 0x24, + 0x4e, 0xdc, 0x83, 0x55, 0x13, 0xe8, 0x19, 0x49, 0xfa, 0xb8, 0x19, 0x8e, + 0x80, 0x18, 0xe7, 0x89, 0xa7, 0xe1, 0x88, 0x31, 0x14, 0xd5, 0xc6, 0xdf, + 0xe7, 0x5e, 0x95, 0x9e, 0x48, 0x24, 0xdd, 0x09, 0x28, 0xd1, 0xbb, 0xe0, + 0x61, 0xbb, 0x2a, 0x76, 0xbf, 0xe5, 0x28, 0x21, 0x0e, 0x6f, 0x6c, 0x96, + 0xbb, 0xf0, 0x25, 0x66, 0xfe, 0xb2, 0x22, 0x07, 0x77, 0xf5, 0x11, 0x3e, + 0xa7, 0x1d, 0x12, 0x55, 0x03, 0x48, 0xc9, 0xae, 0xb4, 0x86, 0x44, 0xf1, + 0x37, 0xe6, 0x92, 0xc8, 0x4d, 0xc6, 0xb4, 0xa9, 0x12, 0xc6, 0xe8, 0x10, + 0x48, 0x91, 0xea, 0xe3, 0x38, 0x40, 0x86, 0x27, 0x43, 0x1d, 0xdf, 0x34, + 0xbb, 0x7a, 0x64, 0xf0, 0x7e, 0x00, 0x79, 0x24, 0x3b, 0x6b, 0x16, 0x2b, + 0x1d, 0x94, 0xb5, 0xc5, 0xe7, 0x16, 0x62, 0xac, 0x10, 0xba, 0xe0, 0x83, + 0x7e, 0xd7, 0x40, 0xd2, 0x6f, 0x3c, 0x49, 0x22, 0x4f, 0x34, 0x82, 0x55, + 0xd6, 0xb1, 0x56, 0x4a, 0x8d, 0x8f, 0x34, 0x82, 0x66, 0x92, 0x58, 0xf1, + 0x01, 0x67, 0x0d, 0xac, 0xdb, 0x5b, 0xcb, 0xbc, 0xe7, 0xd7, 0x68, 0x42, + 0xb7, 0x47, 0x3c, 0x63, 0x8c, 0x33, 0x94, 0x36, 0xfa, 0x5a, 0x0c, 0x1d, + 0x7a, 0x46, 0x26, 0x6c, 0xb4, 0x12, 0x01, 0x89, 0xab, 0x36, 0x78, 0x05, + 0x75, 0xda, 0x63, 0xf4, 0xe6, 0x20, 0x37, 0x6e, 0x51, 0xea, 0x7a, 0xa5, + 0xdd, 0xde, 0xc8, 0x74, 0x66, 0x27, 0x05, 0x56, 0x9b, 0xbf, 0x05, 0x31, + 0x77, 0x0f, 0x93, 0xb7, 0x15, 0xb8, 0x20, 0x13, 0x83, 0x0b, 0xe2, 0xe6, + 0x36, 0x3e, 0x89, 0xf0, 0x3b, 0xe3, 0x5b, 0xbf, 0x8e, 0xb8, 0x33, 0x5e, + 0x43, 0xc9, 0xc1, 0xdd, 0x9a, 0xcd, 0x9b, 0x5a, 0x58, 0x2e, 0x6e, 0x50, + 0xd4, 0x13, 0x64, 0x07, 0x46, 0x7e, 0x83, 0x80, 0x33, 0x43, 0xd3, 0xa7, + 0x1e, 0x07, 0x2c, 0xaf, 0x03, 0xd5, 0x1f, 0x7d, 0x95, 0xf4, 0x70, 0x08, + 0xab, 0xa9, 0x36, 0xff, 0xf2, 0xc5, 0xbc, 0x82, 0x5e, 0x75, 0x8a, 0xd0, + 0x32, 0xfb, 0xf4, 0x34, 0x44, 0x42, 0x42, 0x76, 0xce, 0x27, 0x42, 0x93, + 0x29, 0x54, 0x21, 0x14, 0x2a, 0x2f, 0x93, 0xd8, 0x2a, 0xe8, 0xf8, 0x44, + 0xec, 0x4c, 0x8b, 0xdb, 0xe9, 0xdc, 0x38, 0x35, 0xca, 0xb8, 0x34, 0x9f, + 0xec, 0x32, 0x24, 0xda, 0x45, 0x6f, 0x74, 0x4d, 0x42, 0xa3, 0x9c, 0x18, + 0xee, 0x91, 0x25, 0x11, 0xae, 0xbc, 0x94, 0x48, 0x0e, 0x9a, 0x4f, 0x5b, + 0x60, 0x41, 0x76, 0x1a, 0x06, 0xae, 0x1a, 0x0f, 0x57, 0x23, 0xe8, 0xcd, + 0x00, 0xc6, 0xc2, 0x83, 0xa2, 0x36, 0x90, 0x4d, 0xf1, 0xe3, 0x7e, 0xda, + 0xf6, 0xff, 0x36, 0x37, 0x10, 0x78, 0xe2, 0x5f, 0x59, 0x7c, 0x07, 0xe9, + 0xe6, 0x3c, 0x7a, 0x3c, 0xbf, 0x89, 0x80, 0xce, 0x07, 0xca, 0xbc, 0xee, + 0x54, 0x09, 0x12, 0xa1, 0x0f, 0x34, 0xe3, 0xde, 0x8e, 0x96, 0xdf, 0xe5, + 0x36, 0x68, 0xb4, 0x3a, 0x6d, 0x51, 0x96, 0x9b, 0x10, 0xdb, 0x7e, 0x31, + 0x22, 0xd2, 0x60, 0x3e, 0x2f, 0x63, 0xb8, 0x40, 0x56, 0x4c, 0x3d, 0xae, + 0xba, 0x3b, 0x06, 0x66, 0x31, 0xc8, 0xa7, 0x2b, 0xea, 0xa1, 0xc4, 0x8c, + 0x80, 0x5f, 0xcc, 0x85, 0xc4, 0xd4, 0xc5, 0x77, 0xb3, 0x30, 0x1f, 0xfe, + 0xe6, 0x19, 0x4a, 0x95, 0x41, 0x57, 0x5c, 0xb4, 0x73, 0x5d, 0x78, 0x47, + 0x02, 0x28, 0x91, 0x67, 0x3a, 0xd0, 0x86, 0x23, 0xa9, 0x74, 0x10, 0x15, + 0x79, 0x71, 0x36, 0x6d, 0xf4, 0xb3, 0x89, 0xb3, 0x77, 0xa5, 0xf0, 0x5f, + 0x37, 0x89, 0xc3, 0xec, 0xcf, 0x80, 0x2b, 0x0b, 0x99, 0xd3, 0xe5, 0x19, + 0x23, 0x94, 0x85, 0x1f, 0x07, 0x3d, 0x19, 0x3a, 0x60, 0xaa, 0x71, 0xfb, + 0xf1, 0x17, 0x3d, 0xd9, 0x07, 0x42, 0x92, 0xf5, 0xc5, 0xb2, 0x53, 0x50, + 0x7c, 0x00, 0x45, 0xb5, 0x05, 0xa1, 0xf8, 0x02, 0x91, 0x6e, 0x9e, 0x2f, + 0x5b, 0x42, 0x48, 0x01, 0x12, 0x53, 0x79, 0xbe, 0x2f, 0x18, 0x0e, 0xa0, + 0x8d, 0x22, 0x1b, 0xfd, 0x51, 0x33, 0x56, 0x16, 0x2f, 0x2e, 0x38, 0x75, + 0x5f, 0xcd, 0x58, 0xa1, 0x0c, 0x27, 0x35, 0x0c, 0x27, 0x6d, 0xfa, 0x57, + 0x99, 0x14, 0xee, 0xe1, 0xcb, 0x52, 0xd7, 0xee, 0x0f, 0x24, 0xf0, 0x32, + 0xf3, 0x6f, 0x82, 0x63, 0x99, 0xa3, 0xd7, 0xd7, 0x82, 0xff, 0xc2, 0xd9, + 0x66, 0x69, 0x27, 0x73, 0x24, 0x37, 0xac, 0xff, 0x21, 0x97, 0x4a, 0xf9, + 0xba, 0x75, 0x2d, 0x89, 0x49, 0x35, 0x4a, 0x07, 0x19, 0xd7, 0x83, 0xc1, + 0x89, 0x67, 0x6a, 0x57, 0x7a, 0xf8, 0x28, 0x62, 0xd3, 0xa6, 0x26, 0x8d, + 0x85, 0xe6, 0xb0, 0x91, 0x10, 0xf4, 0xbd, 0x65, 0x5a, 0x9e, 0x62, 0x30, + 0x07, 0x5d, 0x73, 0xbd, 0x29, 0xaf, 0x68, 0xbf, 0x8d, 0x6f, 0xab, 0xab, + 0xf9, 0x3e, 0x8e, 0x6a, 0xe4, 0xfb, 0x0f, 0xb9, 0xc9, 0xe9, 0xe8, 0xbe, + 0xb1, 0x6e, 0x81, 0xc7, 0xb7, 0xaf, 0xc7, 0xf7, 0xc4, 0x07, 0x2c, 0x15, + 0xaf, 0xb4, 0x10, 0xf5, 0x78, 0x0f, 0x52, 0x1d, 0x2c, 0xd4, 0xb7, 0x08, + 0xc9, 0xba, 0x9a, 0xfa, 0x46, 0x86, 0x16, 0x7a, 0x8d, 0x21, 0xb6, 0xb1, + 0xb5, 0xd4, 0x8a, 0xcc, 0x16, 0x2a, 0x17, 0xeb, 0xcd, 0xb3, 0xb0, 0xb0, + 0xe1, 0x75, 0x09, 0x15, 0x65, 0xd8, 0x6c, 0x73, 0xfc, 0xed, 0x2f, 0x24, + 0xbb, 0xfb, 0xbc, 0xaa, 0xf4, 0xf5, 0x2e, 0xf9, 0x0b, 0xbe, 0xb8, 0x49, + 0x7d, 0xf4, 0x85, 0xae, 0x2a, 0xb8, 0x06, 0x33, 0x73, 0x5f, 0x30, 0x62, + 0xdb, 0xc0, 0xb3, 0x21, 0xeb, 0x4b, 0x33, 0x08, 0x52, 0x91, 0xdc, 0x9d, + 0xf1, 0x70, 0x02, 0x47, 0x84, 0x1a, 0xa5, 0xdd, 0x9c, 0x69, 0x8f, 0xf1, + 0x97, 0x92, 0xd8, 0xbe, 0x22, 0xf2, 0x91, 0x0e, 0xca, 0x46, 0xc1, 0x21, + 0x9f, 0x93, 0xb9, 0x89, 0xb7, 0xbb, 0x88, 0x10, 0xa3, 0x78, 0xa7, 0x41, + 0xea, 0x13, 0x7f, 0x6a, 0x62, 0xc4, 0x52, 0x4f, 0xf2, 0x8c, 0x16, 0xf0, + 0x32, 0x08, 0x6c, 0x58, 0xd8, 0xb9, 0x9d, 0x02, 0x68, 0x59, 0x26, 0x2f, + 0xb1, 0x70, 0x6c, 0xc1, 0x8c, 0xbc, 0xa3, 0x7e, 0x0f, 0x7c, 0xb2, 0x4f, + 0xc5, 0x3e, 0xef, 0xec, 0xa1, 0xc6, 0x8a, 0x35, 0x19, 0xcc, 0x24, 0xdc, + 0xbe, 0x24, 0x30, 0x8c, 0xf2, 0x1a, 0x88, 0x8d, 0xe6, 0x7a, 0xd0, 0xc5, + 0x17, 0x3c, 0x1d, 0xe6, 0xb4, 0xdf, 0x62, 0xec, 0xfc, 0x14, 0xb3, 0x2f, + 0x03, 0xd6, 0xc8, 0x73, 0x43, 0x12, 0x15, 0x44, 0x52, 0xeb, 0xc9, 0x2a, + 0x7b, 0x6c, 0x3e, 0x82, 0x52, 0xaf, 0x2f, 0xf8, 0xa8, 0xd5, 0xcc, 0xc7, + 0x8f, 0xfd, 0xbd, 0xb7, 0xbe, 0xd2, 0x94, 0x6a, 0x01, 0x7c, 0xae, 0xf1, + 0x2a, 0xab, 0x0c, 0xc2, 0x7a, 0x62, 0x7a, 0x57, 0x73, 0x2e, 0x6c, 0x1c, + 0x25, 0x17, 0xd8, 0x47, 0x92, 0x9b, 0xec, 0xcd, 0x73, 0x58, 0x0c, 0x9b, + 0x4d, 0x79, 0x97, 0x10, 0xa7, 0x47, 0xe3, 0x33, 0xba, 0xf8, 0x9d, 0xec, + 0x4a, 0xce, 0xf7, 0xab, 0x78, 0x9a, 0x5e, 0x51, 0x63, 0x1a, 0xd5, 0x47, + 0x10, 0x1f, 0x29, 0x6d, 0x54, 0x06, 0xb9, 0xb9, 0xd8, 0xd5, 0x60, 0x88, + 0xc3, 0x84, 0x96, 0x09, 0x18, 0xd6, 0x20, 0xa5, 0xda, 0x2b, 0x9d, 0xca, + 0xeb, 0x69, 0x54, 0x50, 0xae, 0x97, 0x02, 0x4c, 0x14, 0x85, 0x89, 0x46, + 0x4e, 0xfc, 0x0c, 0x71, 0x77, 0x88, 0xb3, 0x0c, 0xfc, 0x50, 0xff, 0xf5, + 0xa9, 0x8f, 0x5f, 0xe9, 0x1d, 0x07, 0xed, 0xf6, 0xdd, 0xe0, 0xeb, 0xc1, + 0x4a, 0x25, 0xc7, 0xca, 0x7b, 0x10, 0x8f, 0x9c, 0x11, 0xf3, 0x23, 0xe6, + 0x20, 0xe2, 0x13, 0x34, 0xe2, 0x88, 0x54, 0x77, 0xbb, 0x9a, 0x37, 0xa5, + 0x47, 0xde, 0x30, 0xa0, 0x1e, 0xd9, 0x88, 0x73, 0x4c, 0x05, 0xce, 0x58, + 0xeb, 0x32, 0x87, 0x67, 0x5a, 0x57, 0xc2, 0x38, 0x0e, 0xc6, 0x00, 0xa4, + 0x37, 0x8d, 0x89, 0x7f, 0xa9, 0xba, 0x09, 0x9f, 0x40, 0x74, 0x61, 0xe5, + 0x61, 0x3a, 0xee, 0xb4, 0x75, 0x16, 0x13, 0x9e, 0x98, 0x1b, 0x9f, 0x92, + 0x14, 0xd0, 0x09, 0x9f, 0x33, 0xc3, 0x29, 0xda, 0xac, 0x5b, 0x3d, 0xac, + 0xf5, 0x73, 0x89, 0xf7, 0xa0, 0x21, 0xab, 0xf1, 0x3b, 0x95, 0xff, 0x24, + 0x76, 0xa6, 0xe6, 0x06, 0xec, 0xfe, 0xce, 0x57, 0xb8, 0x68, 0x5d, 0x73, + 0xa5, 0xa9, 0x00, 0xed, 0x66, 0xd7, 0x05, 0x8b, 0x28, 0xff, 0xf1, 0x91, + 0x67, 0x21, 0xe1, 0xe7, 0xcd, 0x65, 0x20, 0x22, 0x4e, 0x5d, 0x1b, 0x7b, + 0x2d, 0x9d, 0x2d, 0xc9, 0xb5, 0xee, 0xaf, 0x55, 0xa0, 0x18, 0xf5, 0xd7, + 0xd8, 0x1e, 0xf0, 0x3a, 0xe6, 0x27, 0xd4, 0x1a, 0x93, 0x39, 0xbb, 0x19, + 0x2d, 0xae, 0xf0, 0xf0, 0xee, 0x34, 0x12, 0xfc, 0x48, 0xb0, 0x97, 0xce, + 0x7c, 0x52, 0xdd, 0xf7, 0x2a, 0x9b, 0x15, 0xb4, 0xf5, 0xf3, 0x13, 0x16, + 0x2d, 0x0f, 0x30, 0xbf, 0x7b, 0xdf, 0xca, 0x44, 0xd4, 0x46, 0x27, 0x47, + 0xcd, 0x3c, 0xbf, 0xd6, 0x1b, 0xc4, 0x24, 0x4b, 0x1e, 0xf5, 0x50, 0x55, + 0xcd, 0x84, 0x85, 0x71, 0x46, 0xd4, 0xac, 0x6f, 0xbf, 0x2c, 0x80, 0xb8, + 0x8e, 0x54, 0xf1, 0x0d, 0xd8, 0x07, 0x77, 0xbc, 0xad, 0x84, 0x9e, 0xcd, + 0xc0, 0xb8, 0x61, 0x73, 0x08, 0x41, 0xfd, 0x4f, 0xb3, 0xe3, 0xdc, 0x5b, + 0x3e, 0xfe, 0xe5, 0xbd, 0xf4, 0xcb, 0xab, 0x85, 0x1a, 0x1d, 0x4e, 0x3b, + 0xa9, 0x0e, 0xdd, 0xff, 0x8b, 0x07, 0xcf, 0x5b, 0x32, 0x2b, 0xb9, 0x4c, + 0x2c, 0x3e, 0xe9, 0x43, 0x5d, 0x32, 0x69, 0xa2, 0xc9, 0xb0, 0x4f, 0x14, + 0x07, 0x28, 0xa0, 0x2e, 0xa5, 0x6d, 0x13, 0x07, 0x96, 0x90, 0xb1, 0x55, + 0x33, 0x43, 0x23, 0x53, 0x9d, 0x6b, 0x8a, 0xb5, 0xa9, 0x46, 0xe6, 0xeb, + 0x19, 0xd4, 0x85, 0xb1, 0x70, 0xe5, 0xd4, 0xdd, 0x56, 0x4a, 0x07, 0xa8, + 0xd1, 0x9b, 0xae, 0xec, 0x02, 0x5d, 0xb4, 0x10, 0xa1, 0x77, 0x56, 0xe6, + 0x4b, 0xff, 0x55, 0xf4, 0x70, 0xa2, 0x04, 0x5c, 0xb7, 0xa8, 0x10, 0xbe, + 0xdc, 0xac, 0xb8, 0xa0, 0xd3, 0x24, 0x94, 0xb1, 0x68, 0x4e, 0x85, 0xf0, + 0xdf, 0x67, 0x02, 0xd7, 0x4e, 0x3d, 0x70, 0x88, 0x86, 0xe6, 0x1e, 0xe4, + 0xe1, 0x3d, 0x1f, 0x04, 0x7b, 0xae, 0x17, 0x10, 0x73, 0xa8, 0xdd, 0x60, + 0xe0, 0x48, 0x29, 0xbd, 0x38, 0xa8, 0x45, 0x0a, 0x13, 0x6d, 0x88, 0xe7, + 0x96, 0x92, 0x4f, 0x8e, 0x1b, 0xb1, 0x43, 0xc0, 0x76, 0xc5, 0x0c, 0x3c, + 0xe3, 0xd8, 0xf1, 0xe2, 0x80, 0xc3, 0x72, 0xb4, 0x1d, 0x7f, 0x79, 0x0b, + 0x3e, 0xba, 0x3c, 0x8b, 0xf1, 0xd0, 0x06, 0x05, 0x3c, 0x83, 0x33, 0xe6, + 0x88, 0x0a, 0x10, 0x60, 0xe4, 0x40, 0x56, 0x68, 0x46, 0xec, 0x43, 0xbc, + 0x29, 0x9b, 0x7c, 0x2e, 0xbb, 0xd1, 0xc0, 0x82, 0x10, 0x26, 0xfa, 0x59, + 0x76, 0x83, 0xca, 0x93, 0xcf, 0x42, 0x84, 0x7b, 0x0d, 0x1f, 0x32, 0x65, + 0xe6, 0xac, 0x11, 0x37, 0x67, 0xc0, 0xb1, 0xe4, 0x74, 0xca, 0x22, 0x8f, + 0xd1, 0xd2, 0x55, 0x3f, 0x33, 0x10, 0x2d, 0x9e, 0xa3, 0x0a, 0xcd, 0x2e, + 0x5a, 0x19, 0xeb, 0xb9, 0x53, 0xd6, 0x09, 0xe3, 0x4c, 0xca, 0x40, 0x06, + 0xb7, 0xde, 0x26, 0x90, 0xab, 0xe3, 0xc6, 0x49, 0x14, 0x6d, 0xbf, 0x59, + 0x4b, 0xb7, 0x3d, 0x64, 0xe6, 0x6a, 0xc0, 0x1b, 0xe8, 0x5a, 0x09, 0xd3, + 0x07, 0x39, 0xaa, 0x69, 0x35, 0xf2, 0xc0, 0x2d, 0xe1, 0x8b, 0xc0, 0xb4, + 0x2d, 0x46, 0x34, 0x5d, 0xeb, 0x1e, 0x5b, 0x09, 0x69, 0x34, 0x8f, 0xe4, + 0xed, 0x40, 0x4c, 0xf5, 0xc1, 0x28, 0xa4, 0x31, 0x45, 0xf3, 0xe7, 0x11, + 0x8e, 0x02, 0x5c, 0xd7, 0x47, 0x4d, 0x02, 0x84, 0x11, 0xbf, 0xc7, 0xba, + 0xd1, 0x6b, 0x6c, 0x99, 0x71, 0x39, 0x2d, 0x52, 0x7b, 0x7c, 0xd5, 0x9d, + 0x4e, 0x2c, 0xc6, 0x56, 0x72, 0xf3, 0x72, 0x61, 0xbc, 0xc4, 0x44, 0x4d, + 0x3f, 0x4c, 0xd9, 0x31, 0x45, 0xcd, 0x9f, 0xf5, 0xf8, 0xcc, 0x5b, 0xbd, + 0x42, 0xe8, 0xc3, 0x9e, 0x76, 0x2e, 0x7b, 0x99, 0x4f, 0x10, 0xea, 0x22, + 0xad, 0x81, 0x42, 0x49, 0xe3, 0x69, 0xa9, 0x76, 0xd2, 0x42, 0xec, 0xae, + 0x69, 0x81, 0x1c, 0x9b, 0x25, 0xab, 0xca, 0xed, 0x5c, 0x56, 0x84, 0x2b, + 0xee, 0xfc, 0x12, 0xc5, 0x65, 0xbf, 0x7d, 0xb2, 0x2a, 0x65, 0x56, 0xaf, + 0xf7, 0x02, 0x9b, 0x74, 0x7f, 0x13, 0x56, 0xf5, 0x51, 0x84, 0xd9, 0x02, + 0xeb, 0x23, 0xa8, 0xa5, 0x41, 0xca, 0xea, 0xb6, 0xcc, 0x73, 0xb3, 0x67, + 0x0b, 0xb3, 0x6f, 0x1e, 0xce, 0x08, 0xcf, 0x4b, 0xb7, 0xad, 0x6d, 0x4a, + 0x44, 0x04, 0x94, 0x15, 0x59, 0x1d, 0x04, 0xcf, 0x2b, 0x45, 0x93, 0x29, + 0x3e, 0xe6, 0x1f, 0xe3, 0x69, 0x81, 0x81, 0x56, 0x1c, 0x61, 0xe5, 0xcb, + 0xd8, 0x13, 0x97, 0x8e, 0xf2, 0x01, 0x2f, 0xb6, 0x41, 0x1f, 0xfa, 0x28, + 0x7f, 0x92, 0xc8, 0x52, 0x38, 0x7c, 0x2a, 0x1f, 0x89, 0x07, 0xcf, 0xf5, + 0xc8, 0x1d, 0x57, 0x81, 0xa3, 0x1a, 0x48, 0xd8, 0x7e, 0xdb, 0xc3, 0x1f, + 0xbb, 0xcc, 0xf2, 0xc8, 0x17, 0xa9, 0xaf, 0xb7, 0x0b, 0xbd, 0x6e, 0xf0, + 0xcd, 0x96, 0x22, 0x00, 0xda, 0x10, 0x39, 0xd2, 0xc5, 0xc3, 0x92, 0x9c, + 0xc0, 0x61, 0x22, 0x43, 0x9d, 0x17, 0x0f, 0x22, 0x37, 0x22, 0xe1, 0x6b, + 0xd2, 0x05, 0xd7, 0xf2, 0xdb, 0xec, 0x3f, 0x99, 0xe7, 0x86, 0x45, 0x1a, + 0x4e, 0xf7, 0x33, 0xef, 0xf1, 0x11, 0xad, 0xb7, 0x72, 0x95, 0x73, 0x78, + 0x52, 0x2c, 0x83, 0x6f, 0x19, 0x0d, 0x9e, 0xfa, 0x20, 0x6a, 0x82, 0xbe, + 0x9f, 0x7a, 0xe5, 0x47, 0x29, 0xf6, 0xfd, 0xbf, 0xd5, 0x3d, 0x2f, 0x89, + 0xac, 0xd3, 0xae, 0xad, 0x15, 0x21, 0xed, 0x72, 0x38, 0x25, 0x8e, 0x68, + 0xd8, 0xf0, 0x72, 0xd6, 0xde, 0x30, 0x60, 0x42, 0x1d, 0x20, 0x13, 0x29, + 0xf8, 0x6c, 0x50, 0xe2, 0x06, 0xa6, 0xae, 0xdc, 0x1b, 0x34, 0x8c, 0x3e, + 0xe2, 0xd8, 0x8a, 0x09, 0x9a, 0x99, 0x7a, 0xb0, 0xf9, 0x38, 0xb0, 0xf5, + 0x68, 0x97, 0xfd, 0x4d, 0x9c, 0xfd, 0xa1, 0x97, 0x57, 0xfc, 0x79, 0x8d, + 0x47, 0xca, 0x2b, 0xba, 0x68, 0x42, 0xfe, 0x1a, 0x84, 0xd4, 0x93, 0x99, + 0x51, 0x8f, 0xe3, 0xb1, 0x76, 0x86, 0xd0, 0x24, 0x66, 0x18, 0x88, 0xfb, + 0x18, 0x17, 0x46, 0x30, 0xf9, 0x4d, 0xe4, 0x7a, 0x45, 0x52, 0x78, 0xee, + 0xa1, 0x41, 0xa5, 0xd6, 0x5d, 0x54, 0x39, 0xdd, 0xba, 0x31, 0x5c, 0x92, + 0xcc, 0xc5, 0xe8, 0xcb, 0xac, 0x5a, 0xbf, 0x36, 0xde, 0xe6, 0xbe, 0x5c, + 0xef, 0xa3, 0x24, 0x46, 0x23, 0x92, 0xd2, 0x96, 0xe8, 0x8b, 0x89, 0xae, + 0x01, 0xde, 0xfc, 0xe3, 0xde, 0xb2, 0x04, 0xab, 0x27, 0x82, 0xec, 0xd4, + 0xdf, 0x0f, 0xb7, 0xa3, 0x5d, 0xb9, 0x61, 0x37, 0x60, 0x7c, 0xb1, 0x4d, + 0x51, 0xec, 0xc7, 0xbe, 0xf3, 0x00, 0xa2, 0xdb, 0x01, 0x42, 0x02, 0x45, + 0x77, 0x12, 0xe1, 0xc1, 0x22, 0xd8, 0x21, 0x91, 0x90, 0x12, 0x41, 0x60, + 0x45, 0xfd, 0x6a, 0x2d, 0x79, 0x1b, 0x4e, 0xcb, 0x33, 0xc4, 0x0f, 0x7e, + 0x5b, 0xb3, 0xec, 0x13, 0x22, 0xad, 0x79, 0x5f, 0x89, 0x1c, 0xeb, 0xcb, + 0x82, 0x0a, 0x6d, 0xbc, 0x6c, 0xea, 0x06, 0x7d, 0x3d, 0xea, 0x48, 0xd8, + 0x62, 0x1f, 0x1d, 0x09, 0xe6, 0xab, 0x69, 0xbd, 0x88, 0x4f, 0x68, 0x3e, + 0x34, 0x80, 0xcf, 0x0c, 0x15, 0x20, 0x5d, 0xae, 0x75, 0x6b, 0xc5, 0xef, + 0x66, 0xfc, 0x67, 0xac, 0x85, 0x7a, 0x30, 0xac, 0xb8, 0x61, 0xfc, 0x4b, + 0x48, 0xa4, 0xcb, 0x6b, 0x98, 0x02, 0x3c, 0x56, 0xff, 0xb0, 0xbb, 0x59, + 0x41, 0x00, 0xd4, 0x6b, 0x21, 0xef, 0x32, 0x86, 0x25, 0x9d, 0xf2, 0xc4, + 0x98, 0x38, 0xea, 0x20, 0x39, 0x9f, 0x97, 0xae, 0xe1, 0x63, 0xf6, 0x5e, + 0x2d, 0x3a, 0x0d, 0xb6, 0xf6, 0x01, 0xec, 0x8c, 0x87, 0x8d, 0x45, 0x00, + 0xa0, 0xa3, 0xfa, 0xe8, 0xf6, 0x60, 0xaa, 0xe9, 0xab, 0xff, 0xfc, 0x6c, + 0x82, 0xcc, 0x8a, 0x57, 0x82, 0x23, 0xf3, 0x26, 0x80, 0xfb, 0xac, 0x42, + 0xc1, 0xc8, 0xe8, 0x99, 0x21, 0xf3, 0xff, 0x61, 0x02, 0xb6, 0xb7, 0x59, + 0x14, 0xd2, 0xb2, 0x5b, 0xae, 0x7e, 0xa6, 0xf0, 0xed, 0x75, 0xdc, 0xe3, + 0x3f, 0x29, 0xed, 0x48, 0x29, 0x2b, 0x7c, 0xdb, 0x50, 0x85, 0x5f, 0xa9, + 0x6f, 0x8c, 0x0a, 0xf5, 0x0e, 0x29, 0x31, 0xc3, 0x7c, 0xb2, 0xe0, 0xf1, + 0x7f, 0x13, 0xa9, 0x13, 0x8b, 0x4d, 0xfb, 0x06, 0x95, 0x32, 0x61, 0xd1, + 0xd5, 0x62, 0xc5, 0x4f, 0xb1, 0xa5, 0xcf, 0xae, 0x46, 0x87, 0xf5, 0xb9, + 0xf9, 0x43, 0x6c, 0x95, 0x5d, 0x79, 0x1e, 0x6c, 0xec, 0x5c, 0x9a, 0x87, + 0x27, 0x1a, 0x00, 0xe1, 0x53, 0x7c, 0x9c, 0xa8, 0xab, 0xa4, 0x1a, 0x35, + 0x63, 0x60, 0x46, 0x95, 0xf3, 0xc1, 0xa2, 0xa5, 0x65, 0xf8, 0xd3, 0xdd, + 0xba, 0x3f, 0x4e, 0x12, 0xd2, 0xab, 0xba, 0xaf, 0x22, 0x2b, 0xe7, 0x54, + 0x61, 0xab, 0x5d, 0xe8, 0xb6, 0xa2, 0xf9, 0x02, 0x16, 0xc8, 0x31, 0x81, + 0xa4, 0xa5, 0x7a, 0x73, 0xea, 0x41, 0x13, 0x7f, 0x44, 0x06, 0x89, 0x38, + 0xd3, 0x1d, 0xaa, 0xb9, 0x4b, 0xd4, 0x61, 0xb0, 0xf2, 0x19, 0x66, 0x1b, + 0xa0, 0x15, 0xbe, 0xac, 0xb2, 0x93, 0x5c, 0x49, 0x6b, 0x3c, 0x89, 0xad, + 0x19, 0x19, 0xf5, 0x16, 0x46, 0xd7, 0x86, 0x77, 0x4a, 0xc7, 0x55, 0xcf, + 0x7a, 0x9b, 0xb4, 0xa5, 0x8a, 0xdd, 0xcf, 0x55, 0xe6, 0xc0, 0x8b, 0x59, + 0x4a, 0x57, 0xd1, 0x14, 0x76, 0x0b, 0xe5, 0xa5, 0xbc, 0xf3, 0xb4, 0x0a, + 0x93, 0xdf, 0x12, 0x44, 0xd9, 0xf8, 0x57, 0x9d, 0x99, 0xc0, 0x39, 0xe0, + 0xab, 0xa7, 0xcf, 0xe5, 0xa6, 0xd4, 0xd9, 0xcf, 0xf0, 0xc6, 0x0c, 0x15, + 0x23, 0x0c, 0x3f, 0xb5, 0xdd, 0xc9, 0x6b, 0xac, 0x06, 0x0c, 0x12, 0x1c, + 0x32, 0x13, 0x2e, 0x4b, 0x30, 0x7d, 0x1e, 0x5a, 0x22, 0x7a, 0x6a, 0x9b, + 0x09, 0xbb, 0x0c, 0xfd, 0x27, 0x02, 0xc9, 0x3d, 0x2c, 0x1b, 0xf6, 0x8a, + 0xbf, 0x99, 0x4b, 0x7b, 0xa6, 0xfd, 0x60, 0x43, 0xfd, 0x7e, 0x61, 0x0e, + 0xc6, 0x6b, 0x8d, 0xa2, 0x36, 0x06, 0xea, 0xf3, 0x72, 0x0b, 0x11, 0xd1, + 0x2f, 0xd6, 0x09, 0x00, 0x0f, 0xd7, 0x98, 0xd7, 0x76, 0x08, 0xa6, 0x01, + 0x13, 0x25, 0x5b, 0x34, 0x33, 0x4f, 0x78, 0x22, 0x60, 0x7f, 0x9d, 0x68, + 0x31, 0xbc, 0x34, 0x6a, 0xb7, 0xbc, 0x5e, 0x47, 0xdb, 0x57, 0xae, 0x08, + 0x10, 0x30, 0x84, 0x2b, 0xf5, 0x63, 0x85, 0x85, 0x90, 0xb8, 0x14, 0xa5, + 0x4d, 0x59, 0x05, 0x91, 0x75, 0xa0, 0xdb, 0x50, 0x04, 0x82, 0xdc, 0x72, + 0x57, 0x3c, 0x65, 0xd6, 0x75, 0x62, 0x02, 0x3b, 0x67, 0xd6, 0xbf, 0x18, + 0xae, 0xc1, 0x07, 0xde, 0xd4, 0x2c, 0x1b, 0x67, 0x78, 0x1f, 0x67, 0x83, + 0x2e, 0x2e, 0x88, 0xf7, 0x3c, 0x87, 0xc2, 0x6a, 0x55, 0x2b, 0x74, 0x32, + 0x7e, 0xa0, 0x46, 0x7d, 0xcb, 0x5d, 0x77, 0x16, 0x45, 0xa2, 0xd9, 0xc9, + 0xfa, 0xcb, 0x25, 0xef, 0x8d, 0x77, 0xd0, 0xe9, 0x9c, 0x81, 0x8b, 0x79, + 0x9a, 0x9e, 0x56, 0x2f, 0xf2, 0x8e, 0x5c, 0x02, 0xdc, 0x51, 0xde, 0x04, + 0x60, 0xf2, 0x17, 0x59, 0xfa, 0xa3, 0x37, 0x09, 0xb1, 0x2a, 0xec, 0x2d, + 0x9c, 0xf3, 0xe7, 0xab, 0x68, 0x2e, 0x50, 0x50, 0xf6, 0x06, 0x90, 0x79, + 0xc3, 0xf1, 0x22, 0x7a, 0xa3, 0xf6, 0x7f, 0xf9, 0x33, 0x5f, 0x0c, 0xb7, + 0x35, 0x60, 0x4c, 0xca, 0x92, 0x8f, 0x2b, 0x21, 0x4e, 0xcf, 0x6c, 0xe3, + 0x47, 0x46, 0x95, 0x03, 0x9b, 0x31, 0x00, 0x1f, 0xe6, 0xc3, 0xc6, 0x10, + 0x2d, 0x4e, 0x25, 0x4e, 0xce, 0xbd, 0xfc, 0x3e, 0x6d, 0x2b, 0x95, 0x09, + 0x0f, 0xd1, 0x58, 0x44, 0xe9, 0x9f, 0x5a, 0xe9, 0x01, 0x6b, 0x8b, 0xca, + 0xdf, 0xda, 0xd6, 0x47, 0x8c, 0x74, 0x90, 0x6a, 0xf1, 0x1a, 0xfe, 0x79, + 0x91, 0x3d, 0x68, 0x9d, 0x56, 0xb1, 0x53, 0x44, 0x9f, 0x7d, 0x5a, 0x31, + 0x85, 0xab, 0xab, 0xa0, 0x3e, 0x3a, 0xdf, 0x0e, 0xcf, 0x06, 0x97, 0xe2, + 0x04, 0x57, 0x3a, 0x6f, 0xde, 0x15, 0x7f, 0x8b, 0x72, 0x40, 0x2c, 0xc9, + 0xf0, 0xa8, 0x73, 0x73, 0x3c, 0x1b, 0x5d, 0x85, 0x85, 0x15, 0x7e, 0x7a, + 0x52, 0x07, 0x4d, 0xa3, 0xac, 0x30, 0xac, 0x65, 0xb3, 0x5b, 0xd0, 0x81, + 0xe1, 0x42, 0x38, 0xb8, 0x30, 0x9d, 0x50, 0xe6, 0x6e, 0x71, 0x8d, 0x01, + 0xc2, 0x44, 0xd7, 0x52, 0xb9, 0xdb, 0x84, 0x2a, 0xdf, 0xc4, 0x1c, 0xf3, + 0xfb, 0xb3, 0x9d, 0x09, 0x47, 0xab, 0x8b, 0x5c, 0x9c, 0x62, 0xd1, 0xd3, + 0xf0, 0x68, 0x00, 0x4f, 0x42, 0x09, 0x94, 0xe8, 0xcb, 0x56, 0x23, 0x48, + 0xe4, 0x99, 0xfc, 0x23, 0xa5, 0xad, 0x5f, 0x9a, 0x07, 0xcf, 0x99, 0x77, + 0x08, 0x10, 0xd7, 0x76, 0xeb, 0x24, 0x53, 0x0d, 0xd3, 0x25, 0xc0, 0x6f, + 0xcf, 0x57, 0x19, 0x36, 0x2d, 0x69, 0xfa, 0x59, 0xc2, 0x4c, 0x35, 0xa2, + 0xc8, 0x6a, 0x8f, 0xe7, 0x9e, 0x3c, 0x72, 0x12, 0xd3, 0x1a, 0x89, 0xc1, + 0xc8, 0xff, 0x6d, 0xf4, 0x58, 0x36, 0x78, 0xb8, 0x1a, 0xa6, 0x84, 0x6b, + 0x5f, 0xad, 0x10, 0x37, 0xec, 0xe1, 0x1b, 0xe4, 0x0c, 0xa3, 0x45, 0xc9, + 0x0e, 0xa9, 0x7c, 0xc9, 0x5e, 0x1c, 0xb3, 0xfa, 0xd9, 0x8d, 0x44, 0x8a, + 0x6e, 0x45, 0x3b, 0x68, 0x51, 0x5a, 0xb2, 0x64, 0x5b, 0x94, 0x4b, 0x9a, + 0xd9, 0xa1, 0x94, 0xc0, 0xff, 0xe5, 0x89, 0x75, 0x4a, 0x63, 0xa0, 0x6b, + 0x9b, 0x6a, 0x96, 0xb8, 0x8b, 0xbe, 0x6e, 0x10, 0x3e, 0x6e, 0xf9, 0x27, + 0xdc, 0x10, 0x5a, 0xc0, 0x5e, 0x51, 0x0a, 0x25, 0x11, 0x6e, 0xf4, 0x91, + 0x4e, 0xb1, 0x4b, 0x3d, 0xcc, 0x62, 0x92, 0x54, 0xb1, 0x96, 0xbb, 0x68, + 0xe2, 0x1f, 0x1c, 0x2a, 0x33, 0xb7, 0xf0, 0xc8, 0x7e, 0x47, 0xfd, 0x76, + 0x95, 0x41, 0x1b, 0xcc, 0x70, 0x1d, 0x40, 0xfc, 0x16, 0x91, 0xf1, 0xa9, + 0xc1, 0x76, 0xd1, 0x85, 0xa0, 0x95, 0xf2, 0xdb, 0x76, 0xb8, 0x8c, 0xf2, + 0x18, 0x62, 0x9f, 0x9e, 0xe2, 0xff, 0x84, 0x3c, 0x3f, 0xdc, 0x75, 0x3b, + 0x49, 0x6b, 0xd4, 0xd9, 0xa6, 0x17, 0x86, 0x53, 0x26, 0x59, 0x78, 0x12, + 0x40, 0x96, 0x88, 0x82, 0xae, 0xdf, 0x84, 0x26, 0xfc, 0xac, 0x50, 0x28, + 0xc1, 0xdd, 0x87, 0x9e, 0xfa, 0x52, 0xda, 0x12, 0x89, 0x83, 0x49, 0x16, + 0x67, 0xf4, 0xc3, 0x25, 0x48, 0x82, 0x64, 0xb4, 0x1b, 0x83, 0xff, 0xc3, + 0x0f, 0xac, 0x5b, 0xde, 0x07, 0x80, 0x77, 0x3c, 0xcd, 0x4e, 0x17, 0xeb, + 0x5c, 0x01, 0x73, 0x46, 0xc8, 0xce, 0xb3, 0xba, 0xb1, 0xf5, 0x8e, 0xc6, + 0xf7, 0x87, 0xd3, 0x8e, 0x6e, 0x2d, 0x20, 0xad, 0xda, 0x7a, 0xbd, 0xb2, + 0x22, 0xb0, 0xcc, 0xef, 0x38, 0x11, 0xe9, 0x52, 0x38, 0x09, 0x5d, 0x63, + 0xfc, 0xd9, 0xce, 0xfc, 0xc5, 0x12, 0x83, 0x1a, 0x49, 0xb5, 0xb0, 0x19, + 0x86, 0x05, 0x04, 0xed, 0xb0, 0x8e, 0xe4, 0x80, 0x37, 0xf4, 0x74, 0x38, + 0x85, 0x3e, 0xc5, 0x99, 0x57, 0xed, 0xfb, 0xee, 0x52, 0x35, 0x6d, 0x69, + 0x64, 0xe9, 0xc0, 0xfe, 0x35, 0xa3, 0xcd, 0x18, 0x4e, 0xe4, 0x94, 0xe4, + 0xf3, 0x66, 0xe2, 0x76, 0x89, 0xf0, 0xe9, 0xcf, 0xce, 0x3b, 0xc3, 0xcd, + 0x8b, 0x7a, 0x1d, 0x36, 0x9c, 0x05, 0xb8, 0x87, 0xd2, 0x13, 0xe6, 0x13, + 0xec, 0xdc, 0x73, 0x2b, 0x90, 0x21, 0x03, 0x24, 0x8a, 0xe5, 0xf9, 0x30, + 0x6f, 0xd9, 0xa1, 0x4c, 0xea, 0xd9, 0xf2, 0x97, 0xfa, 0x2b, 0x0c, 0x51, + 0xd0, 0x63, 0x83, 0x09, 0x57, 0xdf, 0x48, 0xa8, 0x91, 0x83, 0x9d, 0xc9, + 0xe4, 0xa8, 0xee, 0x11, 0xed, 0x03, 0xa4, 0xab, 0x45, 0x4b, 0x45, 0x97, + 0xd0, 0x9c, 0x19, 0xe1, 0xef, 0x72, 0xec, 0x56, 0xdf, 0x9c, 0xb4, 0xcc, + 0xb4, 0x42, 0x5a, 0x85, 0xcb, 0x3e, 0xfe, 0x3c, 0xdc, 0xbf, 0x39, 0xf3, + 0xdb, 0xb0, 0x10, 0xf9, 0x31, 0xa7, 0x17, 0xf6, 0x23, 0xe4, 0xa7, 0xaf, + 0xab, 0x0d, 0xc1, 0x85, 0x18, 0xa3, 0x18, 0xb8, 0x5b, 0x24, 0x85, 0xb4, + 0xcc, 0xca, 0x93, 0x10, 0x60, 0x1b, 0x92, 0x97, 0x09, 0x3c, 0x92, 0x4f, + 0x27, 0x20, 0x04, 0x1d, 0x49, 0x9a, 0x2c, 0xf2, 0xf1, 0xd3, 0x89, 0x96, + 0x49, 0xe0, 0x44, 0x5c, 0x21, 0x20, 0xf0, 0xec, 0x49, 0xc8, 0xcf, 0x7b, + 0x78, 0x38, 0xaf, 0x0a, 0x63, 0x7a, 0x97, 0x70, 0x73, 0xcc, 0x8e, 0x10, + 0x3a, 0xea, 0xfb, 0x23, 0xe2, 0x01, 0x03, 0x67, 0x05, 0x60, 0xe2, 0xf3, + 0x94, 0x91, 0x6d, 0x1e, 0x26, 0xd0, 0xff, 0x12, 0x21, 0x81, 0xd6, 0xd0, + 0x84, 0x3c, 0x28, 0x9a, 0xbe, 0xdc, 0xce, 0xc4, 0x5c, 0xe1, 0xcd, 0x9e, + 0xaf, 0xce, 0x1a, 0x60, 0x67, 0xf8, 0xbf, 0xb5, 0x60, 0x6d, 0x64, 0x2a, + 0x02, 0xa1, 0xe1, 0x43, 0x52, 0x08, 0xbf, 0xd3, 0x2e, 0xfc, 0xeb, 0x9a, + 0x0d, 0xb2, 0x31, 0xea, 0xf4, 0xf1, 0x86, 0x5c, 0x4a, 0x0f, 0x10, 0x29, + 0x9f, 0x39, 0x25, 0x7a, 0xf9, 0x47, 0xa5, 0x88, 0x3b, 0x46, 0xe9, 0xe7, + 0x7f, 0xff, 0xb9, 0x09, 0x4d, 0x55, 0x6f, 0x81, 0x9b, 0xea, 0x2b, 0x10, + 0xca, 0x6d, 0x0b, 0x0e, 0xda, 0x69, 0x69, 0x87, 0x51, 0x00, 0x1a, 0xd2, + 0x34, 0xa8, 0x2d, 0x9f, 0xc3, 0x14, 0x51, 0x97, 0x99, 0xa3, 0x55, 0x31, + 0x02, 0x89, 0x6f, 0x72, 0xb5, 0x3a, 0xcc, 0x2d, 0xd3, 0x25, 0xb2, 0xfa, + 0xf2, 0x03, 0xc9, 0x4d, 0x78, 0x8b, 0xed, 0x02, 0x05, 0x5f, 0x21, 0x17, + 0x07, 0x41, 0xed, 0x53, 0x61, 0xa4, 0xe5, 0x7c, 0x84, 0x78, 0xfb, 0xde, + 0xde, 0xe0, 0x09, 0x2f, 0xcb, 0xc2, 0x47, 0xdd, 0x64, 0x41, 0x6c, 0xe5, + 0x35, 0xb0, 0xb1, 0x14, 0x81, 0x85, 0xb5, 0xe4, 0xa1, 0xaf, 0x3f, 0xe5, + 0x5a, 0x85, 0x4e, 0x38, 0x83, 0x03, 0x98, 0x1b, 0xb3, 0x7c, 0xb7, 0xf8, + 0x3d, 0x7d, 0x23, 0xf7, 0xa0, 0x22, 0xe4, 0x69, 0x37, 0xe9, 0xf0, 0x19, + 0xed, 0xdb, 0xc3, 0x7d, 0x65, 0x98, 0x1d, 0xe8, 0x3a, 0x33, 0xfa, 0x4f, + 0x95, 0xa9, 0x91, 0x03, 0xfd, 0x5c, 0x41, 0x7c, 0x27, 0x8b, 0xe3, 0xf8, + 0x48, 0x2b, 0xa0, 0x13, 0x68, 0x97, 0x5f, 0x33, 0x90, 0x80, 0xac, 0x19, + 0x68, 0x4b, 0x45, 0x88, 0x22, 0x55, 0xab, 0x77, 0x6c, 0x1d, 0x61, 0x23, + 0x31, 0xdd, 0xd7, 0x60, 0xda, 0x9e, 0x52, 0xc1, 0x29, 0xe7, 0xbd, 0xcb, + 0x36, 0xed, 0xa0, 0x83, 0x6e, 0xbc, 0x28, 0x11 +}; +unsigned int test_data_len = 5000; + +unsigned char test_data_enc[] = { + 0x33, 0x73, 0x47, 0x61, 0x66, 0x4d, 0x62, 0x62, 0x32, 0x6a, 0x31, 0x33, + 0x78, 0x54, 0x66, 0x33, 0x4c, 0x50, 0x45, 0x56, 0x52, 0x2b, 0x52, 0x6a, + 0x35, 0x57, 0x68, 0x69, 0x6a, 0x6d, 0x77, 0x4a, 0x76, 0x64, 0x64, 0x30, + 0x2f, 0x48, 0x4d, 0x41, 0x36, 0x49, 0x4c, 0x43, 0x66, 0x48, 0x4d, 0x62, + 0x4a, 0x75, 0x56, 0x7a, 0x61, 0x2f, 0x66, 0x4d, 0x46, 0x66, 0x62, 0x43, + 0x49, 0x59, 0x38, 0x2b, 0x4b, 0x4e, 0x6d, 0x79, 0x6c, 0x71, 0x2b, 0x57, + 0x37, 0x2f, 0x37, 0x4e, 0x0a, 0x4f, 0x6c, 0x56, 0x6f, 0x78, 0x71, 0x72, + 0x6e, 0x2b, 0x6a, 0x59, 0x30, 0x4e, 0x4b, 0x6d, 0x6e, 0x32, 0x52, 0x38, + 0x51, 0x68, 0x5a, 0x6a, 0x56, 0x53, 0x6e, 0x75, 0x49, 0x42, 0x4c, 0x70, + 0x73, 0x4e, 0x74, 0x74, 0x70, 0x4d, 0x62, 0x30, 0x47, 0x63, 0x50, 0x73, + 0x47, 0x4f, 0x6b, 0x74, 0x50, 0x77, 0x68, 0x48, 0x4b, 0x58, 0x54, 0x6f, + 0x52, 0x44, 0x54, 0x6c, 0x41, 0x47, 0x4b, 0x64, 0x61, 0x30, 0x6e, 0x2b, + 0x46, 0x53, 0x73, 0x38, 0x2b, 0x6e, 0x77, 0x49, 0x6b, 0x0a, 0x42, 0x35, + 0x74, 0x6e, 0x48, 0x67, 0x6c, 0x55, 0x7a, 0x36, 0x75, 0x31, 0x47, 0x4b, + 0x72, 0x54, 0x78, 0x37, 0x31, 0x49, 0x31, 0x52, 0x66, 0x6d, 0x46, 0x70, + 0x4f, 0x4e, 0x4c, 0x6f, 0x54, 0x41, 0x6c, 0x33, 0x47, 0x30, 0x61, 0x71, + 0x34, 0x75, 0x43, 0x77, 0x77, 0x45, 0x72, 0x61, 0x34, 0x6f, 0x54, 0x6d, + 0x4d, 0x69, 0x6d, 0x31, 0x4c, 0x39, 0x6e, 0x76, 0x4f, 0x73, 0x56, 0x49, + 0x32, 0x71, 0x35, 0x42, 0x56, 0x6f, 0x4a, 0x57, 0x73, 0x2b, 0x42, 0x39, + 0x59, 0x4b, 0x0a, 0x46, 0x59, 0x38, 0x33, 0x6f, 0x4c, 0x47, 0x2f, 0x30, + 0x43, 0x54, 0x2f, 0x57, 0x48, 0x50, 0x57, 0x7a, 0x63, 0x72, 0x43, 0x4d, + 0x6a, 0x53, 0x30, 0x43, 0x59, 0x33, 0x34, 0x2b, 0x4b, 0x47, 0x70, 0x75, + 0x73, 0x7a, 0x65, 0x47, 0x33, 0x6c, 0x69, 0x31, 0x30, 0x66, 0x50, 0x4d, + 0x6b, 0x69, 0x38, 0x77, 0x57, 0x62, 0x31, 0x68, 0x2f, 0x6a, 0x4e, 0x6f, + 0x46, 0x72, 0x75, 0x54, 0x34, 0x76, 0x78, 0x61, 0x50, 0x6a, 0x30, 0x59, + 0x78, 0x6c, 0x4d, 0x34, 0x44, 0x77, 0x37, 0x0a, 0x47, 0x6d, 0x6d, 0x50, + 0x39, 0x68, 0x66, 0x69, 0x4f, 0x47, 0x78, 0x54, 0x6d, 0x35, 0x42, 0x7a, + 0x48, 0x39, 0x5a, 0x64, 0x66, 0x66, 0x71, 0x33, 0x67, 0x49, 0x50, 0x6f, + 0x65, 0x72, 0x32, 0x45, 0x43, 0x76, 0x2f, 0x66, 0x41, 0x75, 0x34, 0x70, + 0x64, 0x57, 0x34, 0x6c, 0x6e, 0x54, 0x65, 0x51, 0x59, 0x6c, 0x4e, 0x61, + 0x69, 0x4c, 0x6d, 0x4f, 0x57, 0x76, 0x70, 0x66, 0x62, 0x42, 0x2f, 0x74, + 0x6d, 0x6b, 0x74, 0x70, 0x44, 0x74, 0x4a, 0x68, 0x30, 0x78, 0x64, 0x58, + 0x0a, 0x44, 0x46, 0x49, 0x79, 0x51, 0x34, 0x4e, 0x71, 0x4f, 0x30, 0x46, + 0x44, 0x70, 0x4c, 0x36, 0x35, 0x76, 0x64, 0x58, 0x6e, 0x35, 0x62, 0x49, + 0x57, 0x57, 0x62, 0x71, 0x77, 0x39, 0x62, 0x7a, 0x69, 0x57, 0x33, 0x6d, + 0x57, 0x30, 0x71, 0x43, 0x6a, 0x43, 0x48, 0x61, 0x6f, 0x75, 0x2f, 0x2f, + 0x4c, 0x38, 0x68, 0x56, 0x6d, 0x62, 0x45, 0x6d, 0x62, 0x79, 0x38, 0x57, + 0x4e, 0x73, 0x73, 0x62, 0x71, 0x71, 0x68, 0x63, 0x4a, 0x47, 0x78, 0x79, + 0x48, 0x75, 0x57, 0x66, 0x48, 0x0a, 0x68, 0x63, 0x45, 0x34, 0x35, 0x69, + 0x7a, 0x54, 0x43, 0x5a, 0x66, 0x34, 0x34, 0x4e, 0x4b, 0x78, 0x59, 0x6e, + 0x4c, 0x38, 0x65, 0x58, 0x63, 0x31, 0x75, 0x32, 0x35, 0x55, 0x33, 0x4e, + 0x2b, 0x62, 0x7a, 0x30, 0x62, 0x62, 0x73, 0x72, 0x76, 0x35, 0x75, 0x58, + 0x79, 0x6f, 0x36, 0x77, 0x45, 0x75, 0x4e, 0x37, 0x54, 0x39, 0x50, 0x71, + 0x47, 0x43, 0x61, 0x7a, 0x45, 0x59, 0x63, 0x6a, 0x70, 0x56, 0x66, 0x73, + 0x6d, 0x35, 0x79, 0x42, 0x76, 0x63, 0x32, 0x61, 0x41, 0x57, 0x0a, 0x54, + 0x50, 0x31, 0x74, 0x2f, 0x76, 0x42, 0x71, 0x5a, 0x6f, 0x69, 0x35, 0x49, + 0x47, 0x36, 0x31, 0x54, 0x37, 0x7a, 0x62, 0x6c, 0x4c, 0x73, 0x41, 0x53, + 0x71, 0x4d, 0x2f, 0x65, 0x63, 0x44, 0x30, 0x47, 0x4a, 0x4f, 0x68, 0x4c, + 0x65, 0x79, 0x75, 0x58, 0x6b, 0x4c, 0x4b, 0x46, 0x51, 0x46, 0x41, 0x31, + 0x31, 0x6d, 0x51, 0x44, 0x70, 0x49, 0x7a, 0x6d, 0x49, 0x2f, 0x67, 0x61, + 0x4f, 0x54, 0x71, 0x6a, 0x6a, 0x64, 0x77, 0x50, 0x30, 0x71, 0x44, 0x4a, + 0x77, 0x6a, 0x77, 0x0a, 0x78, 0x7a, 0x6b, 0x50, 0x48, 0x43, 0x47, 0x33, + 0x61, 0x79, 0x2b, 0x65, 0x63, 0x79, 0x45, 0x6a, 0x46, 0x68, 0x58, 0x64, + 0x78, 0x4c, 0x37, 0x76, 0x4e, 0x65, 0x72, 0x59, 0x58, 0x71, 0x32, 0x44, + 0x71, 0x52, 0x50, 0x72, 0x51, 0x4a, 0x52, 0x33, 0x6e, 0x39, 0x76, 0x63, + 0x6c, 0x31, 0x51, 0x42, 0x46, 0x56, 0x67, 0x4a, 0x6a, 0x53, 0x45, 0x63, + 0x34, 0x44, 0x72, 0x45, 0x76, 0x58, 0x55, 0x62, 0x37, 0x34, 0x71, 0x31, + 0x65, 0x4b, 0x6f, 0x6a, 0x65, 0x57, 0x6e, 0x4d, 0x0a, 0x46, 0x55, 0x50, + 0x36, 0x5a, 0x66, 0x56, 0x71, 0x79, 0x69, 0x4e, 0x43, 0x66, 0x6f, 0x34, + 0x5a, 0x2b, 0x77, 0x56, 0x44, 0x72, 0x6b, 0x79, 0x4b, 0x35, 0x74, 0x73, + 0x46, 0x77, 0x62, 0x37, 0x56, 0x4d, 0x57, 0x47, 0x72, 0x31, 0x49, 0x36, + 0x4a, 0x49, 0x65, 0x49, 0x62, 0x71, 0x4d, 0x32, 0x67, 0x39, 0x5a, 0x37, + 0x52, 0x41, 0x44, 0x77, 0x46, 0x74, 0x6b, 0x4b, 0x36, 0x55, 0x34, 0x74, + 0x53, 0x61, 0x33, 0x57, 0x5a, 0x64, 0x6a, 0x45, 0x4a, 0x66, 0x35, 0x32, + 0x6c, 0x0a, 0x6f, 0x2b, 0x51, 0x76, 0x52, 0x59, 0x31, 0x2b, 0x4d, 0x74, + 0x41, 0x7a, 0x30, 0x36, 0x54, 0x53, 0x41, 0x57, 0x64, 0x31, 0x43, 0x50, + 0x64, 0x70, 0x6a, 0x70, 0x33, 0x73, 0x59, 0x33, 0x47, 0x6f, 0x50, 0x4d, + 0x77, 0x73, 0x46, 0x53, 0x51, 0x2b, 0x5a, 0x73, 0x30, 0x6b, 0x37, 0x6e, + 0x69, 0x38, 0x59, 0x45, 0x7a, 0x55, 0x53, 0x38, 0x46, 0x51, 0x52, 0x4c, + 0x36, 0x30, 0x59, 0x4c, 0x6b, 0x69, 0x47, 0x78, 0x49, 0x7a, 0x4e, 0x42, + 0x75, 0x70, 0x42, 0x4a, 0x38, 0x42, 0x0a, 0x61, 0x39, 0x30, 0x66, 0x54, + 0x47, 0x53, 0x59, 0x42, 0x62, 0x68, 0x2f, 0x73, 0x30, 0x48, 0x52, 0x37, + 0x74, 0x6a, 0x76, 0x74, 0x6d, 0x45, 0x33, 0x49, 0x6a, 0x6d, 0x6c, 0x46, + 0x67, 0x36, 0x64, 0x6b, 0x33, 0x52, 0x76, 0x4d, 0x76, 0x43, 0x78, 0x45, + 0x77, 0x42, 0x34, 0x4a, 0x5a, 0x61, 0x51, 0x7a, 0x34, 0x2f, 0x68, 0x47, + 0x71, 0x43, 0x42, 0x78, 0x5a, 0x59, 0x61, 0x6e, 0x49, 0x6d, 0x55, 0x78, + 0x38, 0x4e, 0x4d, 0x37, 0x4f, 0x57, 0x6c, 0x73, 0x6b, 0x31, 0x73, 0x0a, + 0x44, 0x34, 0x30, 0x4a, 0x4e, 0x49, 0x35, 0x55, 0x77, 0x37, 0x74, 0x52, + 0x74, 0x7a, 0x36, 0x43, 0x32, 0x6c, 0x38, 0x68, 0x6a, 0x2f, 0x4e, 0x6f, + 0x67, 0x6a, 0x50, 0x4c, 0x5a, 0x48, 0x47, 0x63, 0x33, 0x36, 0x76, 0x36, + 0x74, 0x46, 0x66, 0x5a, 0x42, 0x33, 0x69, 0x69, 0x36, 0x4b, 0x61, 0x36, + 0x6a, 0x45, 0x67, 0x76, 0x73, 0x35, 0x59, 0x63, 0x48, 0x61, 0x51, 0x63, + 0x34, 0x42, 0x56, 0x75, 0x78, 0x49, 0x44, 0x58, 0x54, 0x58, 0x6a, 0x4f, + 0x6d, 0x6e, 0x63, 0x71, 0x0a, 0x6b, 0x4f, 0x54, 0x65, 0x5a, 0x6f, 0x68, + 0x55, 0x32, 0x68, 0x51, 0x2f, 0x41, 0x6a, 0x42, 0x6e, 0x49, 0x35, 0x52, + 0x32, 0x77, 0x79, 0x6a, 0x6b, 0x47, 0x37, 0x38, 0x33, 0x45, 0x77, 0x2f, + 0x4a, 0x71, 0x64, 0x31, 0x31, 0x59, 0x30, 0x45, 0x48, 0x66, 0x4b, 0x33, + 0x61, 0x73, 0x6d, 0x4b, 0x63, 0x72, 0x78, 0x31, 0x4c, 0x52, 0x6e, 0x45, + 0x57, 0x79, 0x4c, 0x51, 0x45, 0x59, 0x71, 0x4d, 0x63, 0x42, 0x74, 0x31, + 0x59, 0x4f, 0x72, 0x69, 0x44, 0x53, 0x78, 0x79, 0x6f, 0x0a, 0x65, 0x36, + 0x69, 0x63, 0x4e, 0x68, 0x6f, 0x42, 0x49, 0x35, 0x6b, 0x51, 0x39, 0x68, + 0x30, 0x65, 0x4c, 0x6f, 0x44, 0x6b, 0x52, 0x6f, 0x6f, 0x77, 0x51, 0x73, + 0x4a, 0x49, 0x47, 0x48, 0x41, 0x71, 0x59, 0x46, 0x4c, 0x41, 0x56, 0x63, + 0x44, 0x76, 0x4b, 0x69, 0x31, 0x45, 0x58, 0x75, 0x70, 0x33, 0x64, 0x49, + 0x48, 0x65, 0x37, 0x58, 0x52, 0x49, 0x72, 0x43, 0x66, 0x35, 0x58, 0x66, + 0x2b, 0x79, 0x71, 0x39, 0x6c, 0x72, 0x41, 0x31, 0x71, 0x66, 0x61, 0x6e, + 0x31, 0x37, 0x0a, 0x42, 0x61, 0x31, 0x32, 0x55, 0x5a, 0x7a, 0x42, 0x52, + 0x6f, 0x61, 0x62, 0x65, 0x33, 0x32, 0x51, 0x56, 0x78, 0x51, 0x31, 0x2b, + 0x4b, 0x53, 0x32, 0x74, 0x38, 0x30, 0x5a, 0x43, 0x6f, 0x59, 0x33, 0x61, + 0x73, 0x50, 0x70, 0x36, 0x33, 0x68, 0x33, 0x54, 0x51, 0x59, 0x4b, 0x72, + 0x51, 0x72, 0x73, 0x32, 0x32, 0x37, 0x6c, 0x33, 0x46, 0x69, 0x36, 0x5a, + 0x62, 0x38, 0x42, 0x64, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x67, 0x6b, 0x6c, + 0x5a, 0x45, 0x55, 0x52, 0x31, 0x4a, 0x33, 0x0a, 0x73, 0x51, 0x49, 0x5a, + 0x65, 0x58, 0x69, 0x76, 0x63, 0x7a, 0x65, 0x4d, 0x37, 0x51, 0x64, 0x75, + 0x5a, 0x50, 0x37, 0x65, 0x4b, 0x53, 0x30, 0x70, 0x6c, 0x55, 0x37, 0x49, + 0x45, 0x6d, 0x57, 0x4d, 0x6b, 0x33, 0x2b, 0x6e, 0x33, 0x6f, 0x67, 0x44, + 0x75, 0x52, 0x52, 0x65, 0x77, 0x6f, 0x79, 0x58, 0x69, 0x4f, 0x51, 0x77, + 0x4f, 0x73, 0x67, 0x41, 0x55, 0x69, 0x5a, 0x68, 0x6d, 0x49, 0x72, 0x63, + 0x57, 0x52, 0x76, 0x4a, 0x6d, 0x48, 0x58, 0x78, 0x76, 0x38, 0x42, 0x35, + 0x0a, 0x34, 0x47, 0x55, 0x70, 0x30, 0x73, 0x5a, 0x52, 0x4d, 0x32, 0x65, + 0x76, 0x44, 0x38, 0x73, 0x61, 0x69, 0x63, 0x37, 0x35, 0x4a, 0x79, 0x30, + 0x6a, 0x77, 0x31, 0x59, 0x48, 0x74, 0x72, 0x6c, 0x30, 0x43, 0x70, 0x44, + 0x4d, 0x52, 0x31, 0x50, 0x50, 0x64, 0x36, 0x65, 0x64, 0x41, 0x38, 0x5a, + 0x7a, 0x7a, 0x6a, 0x37, 0x46, 0x57, 0x2f, 0x7a, 0x49, 0x61, 0x68, 0x67, + 0x4a, 0x72, 0x43, 0x64, 0x6d, 0x47, 0x48, 0x71, 0x36, 0x6e, 0x6a, 0x33, + 0x52, 0x43, 0x74, 0x33, 0x43, 0x0a, 0x48, 0x6b, 0x41, 0x67, 0x38, 0x51, + 0x56, 0x6d, 0x75, 0x30, 0x79, 0x67, 0x4b, 0x39, 0x43, 0x4c, 0x55, 0x38, + 0x73, 0x31, 0x52, 0x61, 0x4d, 0x4f, 0x64, 0x59, 0x76, 0x71, 0x4a, 0x38, + 0x79, 0x79, 0x6f, 0x39, 0x64, 0x39, 0x72, 0x32, 0x44, 0x4c, 0x59, 0x71, + 0x73, 0x73, 0x4a, 0x4a, 0x4d, 0x70, 0x70, 0x33, 0x48, 0x74, 0x5a, 0x69, + 0x61, 0x59, 0x72, 0x38, 0x6c, 0x72, 0x66, 0x56, 0x66, 0x45, 0x54, 0x37, + 0x64, 0x49, 0x67, 0x51, 0x77, 0x61, 0x77, 0x33, 0x37, 0x65, 0x0a, 0x4d, + 0x2f, 0x38, 0x53, 0x37, 0x4f, 0x6c, 0x73, 0x4c, 0x38, 0x31, 0x6e, 0x46, + 0x6f, 0x42, 0x6e, 0x49, 0x57, 0x73, 0x4a, 0x6a, 0x52, 0x75, 0x6b, 0x30, + 0x4f, 0x78, 0x6a, 0x42, 0x38, 0x49, 0x34, 0x55, 0x4d, 0x31, 0x36, 0x77, + 0x2b, 0x56, 0x44, 0x48, 0x64, 0x41, 0x69, 0x68, 0x6b, 0x2b, 0x6a, 0x68, + 0x41, 0x65, 0x79, 0x77, 0x33, 0x32, 0x4f, 0x74, 0x4c, 0x45, 0x64, 0x34, + 0x48, 0x4d, 0x62, 0x2b, 0x57, 0x2f, 0x4a, 0x59, 0x4b, 0x5a, 0x34, 0x4e, + 0x47, 0x42, 0x6d, 0x0a, 0x30, 0x55, 0x63, 0x6d, 0x65, 0x42, 0x45, 0x6b, + 0x4f, 0x53, 0x63, 0x7a, 0x72, 0x6a, 0x69, 0x57, 0x6c, 0x33, 0x77, 0x55, + 0x66, 0x63, 0x56, 0x30, 0x31, 0x4b, 0x2b, 0x7a, 0x66, 0x53, 0x68, 0x68, + 0x35, 0x53, 0x48, 0x41, 0x75, 0x74, 0x7a, 0x50, 0x56, 0x62, 0x6f, 0x71, + 0x62, 0x38, 0x77, 0x70, 0x6c, 0x6c, 0x37, 0x4b, 0x4e, 0x58, 0x79, 0x38, + 0x6b, 0x2f, 0x43, 0x6f, 0x2b, 0x41, 0x6e, 0x42, 0x70, 0x66, 0x47, 0x79, + 0x42, 0x57, 0x53, 0x68, 0x2b, 0x45, 0x4e, 0x69, 0x0a, 0x36, 0x73, 0x34, + 0x71, 0x77, 0x70, 0x58, 0x4d, 0x45, 0x51, 0x76, 0x32, 0x2f, 0x32, 0x5a, + 0x51, 0x38, 0x50, 0x37, 0x52, 0x6c, 0x61, 0x58, 0x52, 0x69, 0x70, 0x55, + 0x41, 0x61, 0x30, 0x6f, 0x63, 0x46, 0x4e, 0x31, 0x39, 0x39, 0x70, 0x63, + 0x48, 0x76, 0x6a, 0x74, 0x39, 0x57, 0x45, 0x34, 0x4a, 0x37, 0x5a, 0x73, + 0x54, 0x62, 0x73, 0x72, 0x4b, 0x2b, 0x57, 0x59, 0x50, 0x77, 0x79, 0x72, + 0x74, 0x30, 0x65, 0x63, 0x2b, 0x55, 0x67, 0x7a, 0x65, 0x44, 0x65, 0x4d, + 0x43, 0x0a, 0x54, 0x53, 0x6d, 0x73, 0x72, 0x70, 0x2b, 0x34, 0x73, 0x55, + 0x59, 0x38, 0x70, 0x4b, 0x30, 0x6e, 0x64, 0x7a, 0x6c, 0x43, 0x78, 0x77, + 0x6b, 0x4b, 0x45, 0x70, 0x48, 0x39, 0x50, 0x74, 0x51, 0x41, 0x45, 0x35, + 0x76, 0x57, 0x35, 0x38, 0x69, 0x49, 0x4e, 0x58, 0x74, 0x6c, 0x4a, 0x70, + 0x52, 0x30, 0x57, 0x52, 0x71, 0x66, 0x77, 0x54, 0x71, 0x6b, 0x53, 0x69, + 0x76, 0x77, 0x71, 0x6e, 0x37, 0x4a, 0x66, 0x49, 0x2b, 0x2f, 0x46, 0x54, + 0x4b, 0x39, 0x6a, 0x62, 0x4f, 0x6b, 0x0a, 0x6a, 0x68, 0x38, 0x56, 0x48, + 0x55, 0x76, 0x61, 0x39, 0x43, 0x43, 0x6c, 0x7a, 0x41, 0x6e, 0x44, 0x47, + 0x42, 0x68, 0x2b, 0x79, 0x37, 0x4d, 0x34, 0x56, 0x67, 0x64, 0x6e, 0x64, + 0x56, 0x31, 0x54, 0x33, 0x6f, 0x2f, 0x4a, 0x52, 0x61, 0x79, 0x65, 0x73, + 0x71, 0x6c, 0x48, 0x73, 0x47, 0x47, 0x48, 0x6f, 0x44, 0x6d, 0x50, 0x68, + 0x74, 0x36, 0x6a, 0x77, 0x38, 0x68, 0x32, 0x6e, 0x4d, 0x4a, 0x31, 0x41, + 0x6f, 0x46, 0x38, 0x7a, 0x79, 0x43, 0x59, 0x78, 0x77, 0x58, 0x39, 0x0a, + 0x70, 0x69, 0x38, 0x6f, 0x32, 0x35, 0x61, 0x6b, 0x72, 0x51, 0x58, 0x58, + 0x73, 0x6c, 0x58, 0x76, 0x4f, 0x36, 0x4d, 0x77, 0x65, 0x6a, 0x49, 0x30, + 0x54, 0x6d, 0x7a, 0x54, 0x59, 0x35, 0x79, 0x46, 0x69, 0x4b, 0x4f, 0x61, + 0x46, 0x4e, 0x74, 0x74, 0x70, 0x61, 0x71, 0x69, 0x52, 0x54, 0x37, 0x4b, + 0x6c, 0x5a, 0x5a, 0x64, 0x4a, 0x74, 0x43, 0x4c, 0x48, 0x76, 0x4d, 0x61, + 0x50, 0x2b, 0x48, 0x4b, 0x4a, 0x41, 0x6e, 0x42, 0x6d, 0x68, 0x71, 0x37, + 0x75, 0x6f, 0x52, 0x77, 0x0a, 0x47, 0x35, 0x73, 0x77, 0x33, 0x44, 0x4d, + 0x57, 0x74, 0x52, 0x63, 0x33, 0x6b, 0x48, 0x67, 0x57, 0x4c, 0x41, 0x6b, + 0x6b, 0x54, 0x74, 0x79, 0x44, 0x56, 0x52, 0x50, 0x6f, 0x47, 0x55, 0x6e, + 0x36, 0x75, 0x42, 0x6d, 0x4f, 0x67, 0x42, 0x6a, 0x6e, 0x69, 0x61, 0x66, + 0x68, 0x69, 0x44, 0x45, 0x55, 0x31, 0x63, 0x62, 0x66, 0x35, 0x31, 0x36, + 0x56, 0x6e, 0x6b, 0x67, 0x6b, 0x33, 0x51, 0x6b, 0x6f, 0x30, 0x62, 0x76, + 0x67, 0x59, 0x62, 0x73, 0x71, 0x64, 0x72, 0x2f, 0x6c, 0x0a, 0x4b, 0x43, + 0x45, 0x4f, 0x62, 0x32, 0x79, 0x57, 0x75, 0x2f, 0x41, 0x6c, 0x5a, 0x76, + 0x36, 0x79, 0x49, 0x67, 0x64, 0x33, 0x39, 0x52, 0x45, 0x2b, 0x70, 0x78, + 0x30, 0x53, 0x56, 0x51, 0x4e, 0x49, 0x79, 0x61, 0x36, 0x30, 0x68, 0x6b, + 0x54, 0x78, 0x4e, 0x2b, 0x61, 0x53, 0x79, 0x45, 0x33, 0x47, 0x74, 0x4b, + 0x6b, 0x53, 0x78, 0x75, 0x67, 0x51, 0x53, 0x4a, 0x48, 0x71, 0x34, 0x7a, + 0x68, 0x41, 0x68, 0x69, 0x64, 0x44, 0x48, 0x64, 0x38, 0x30, 0x75, 0x33, + 0x70, 0x6b, 0x0a, 0x38, 0x48, 0x34, 0x41, 0x65, 0x53, 0x51, 0x37, 0x61, + 0x78, 0x59, 0x72, 0x48, 0x5a, 0x53, 0x31, 0x78, 0x65, 0x63, 0x57, 0x59, + 0x71, 0x77, 0x51, 0x75, 0x75, 0x43, 0x44, 0x66, 0x74, 0x64, 0x41, 0x30, + 0x6d, 0x38, 0x38, 0x53, 0x53, 0x4a, 0x50, 0x4e, 0x49, 0x4a, 0x56, 0x31, + 0x72, 0x46, 0x57, 0x53, 0x6f, 0x32, 0x50, 0x4e, 0x49, 0x4a, 0x6d, 0x6b, + 0x6c, 0x6a, 0x78, 0x41, 0x57, 0x63, 0x4e, 0x72, 0x4e, 0x74, 0x62, 0x79, + 0x37, 0x7a, 0x6e, 0x31, 0x32, 0x68, 0x43, 0x0a, 0x74, 0x30, 0x63, 0x38, + 0x59, 0x34, 0x77, 0x7a, 0x6c, 0x44, 0x62, 0x36, 0x57, 0x67, 0x77, 0x64, + 0x65, 0x6b, 0x59, 0x6d, 0x62, 0x4c, 0x51, 0x53, 0x41, 0x59, 0x6d, 0x72, + 0x4e, 0x6e, 0x67, 0x46, 0x64, 0x64, 0x70, 0x6a, 0x39, 0x4f, 0x59, 0x67, + 0x4e, 0x32, 0x35, 0x52, 0x36, 0x6e, 0x71, 0x6c, 0x33, 0x64, 0x37, 0x49, + 0x64, 0x47, 0x59, 0x6e, 0x42, 0x56, 0x61, 0x62, 0x76, 0x77, 0x55, 0x78, + 0x64, 0x77, 0x2b, 0x54, 0x74, 0x78, 0x57, 0x34, 0x49, 0x42, 0x4f, 0x44, + 0x0a, 0x43, 0x2b, 0x4c, 0x6d, 0x4e, 0x6a, 0x36, 0x4a, 0x38, 0x44, 0x76, + 0x6a, 0x57, 0x37, 0x2b, 0x4f, 0x75, 0x44, 0x4e, 0x65, 0x51, 0x38, 0x6e, + 0x42, 0x33, 0x5a, 0x72, 0x4e, 0x6d, 0x31, 0x70, 0x59, 0x4c, 0x6d, 0x35, + 0x51, 0x31, 0x42, 0x4e, 0x6b, 0x42, 0x30, 0x5a, 0x2b, 0x67, 0x34, 0x41, + 0x7a, 0x51, 0x39, 0x4f, 0x6e, 0x48, 0x67, 0x63, 0x73, 0x72, 0x77, 0x50, + 0x56, 0x48, 0x33, 0x32, 0x56, 0x39, 0x48, 0x41, 0x49, 0x71, 0x36, 0x6b, + 0x32, 0x2f, 0x2f, 0x4c, 0x46, 0x0a, 0x76, 0x49, 0x4a, 0x65, 0x64, 0x59, + 0x72, 0x51, 0x4d, 0x76, 0x76, 0x30, 0x4e, 0x45, 0x52, 0x43, 0x51, 0x6e, + 0x62, 0x4f, 0x4a, 0x30, 0x4b, 0x54, 0x4b, 0x56, 0x51, 0x68, 0x46, 0x43, + 0x6f, 0x76, 0x6b, 0x39, 0x67, 0x71, 0x36, 0x50, 0x68, 0x45, 0x37, 0x45, + 0x79, 0x4c, 0x32, 0x2b, 0x6e, 0x63, 0x4f, 0x44, 0x58, 0x4b, 0x75, 0x44, + 0x53, 0x66, 0x37, 0x44, 0x49, 0x6b, 0x32, 0x6b, 0x56, 0x76, 0x64, 0x45, + 0x31, 0x43, 0x6f, 0x35, 0x77, 0x59, 0x37, 0x70, 0x45, 0x6c, 0x0a, 0x45, + 0x61, 0x36, 0x38, 0x6c, 0x45, 0x67, 0x4f, 0x6d, 0x6b, 0x39, 0x62, 0x59, + 0x45, 0x46, 0x32, 0x47, 0x67, 0x61, 0x75, 0x47, 0x67, 0x39, 0x58, 0x49, + 0x2b, 0x6a, 0x4e, 0x41, 0x4d, 0x62, 0x43, 0x67, 0x36, 0x49, 0x32, 0x6b, + 0x45, 0x33, 0x78, 0x34, 0x33, 0x37, 0x61, 0x39, 0x76, 0x38, 0x32, 0x4e, + 0x78, 0x42, 0x34, 0x34, 0x6c, 0x39, 0x5a, 0x66, 0x41, 0x66, 0x70, 0x35, + 0x6a, 0x78, 0x36, 0x50, 0x4c, 0x2b, 0x4a, 0x67, 0x4d, 0x34, 0x48, 0x79, + 0x72, 0x7a, 0x75, 0x0a, 0x56, 0x41, 0x6b, 0x53, 0x6f, 0x51, 0x38, 0x30, + 0x34, 0x39, 0x36, 0x4f, 0x6c, 0x74, 0x2f, 0x6c, 0x4e, 0x6d, 0x69, 0x30, + 0x4f, 0x6d, 0x31, 0x52, 0x6c, 0x70, 0x73, 0x51, 0x32, 0x33, 0x34, 0x78, + 0x49, 0x74, 0x4a, 0x67, 0x50, 0x69, 0x39, 0x6a, 0x75, 0x45, 0x42, 0x57, + 0x54, 0x44, 0x32, 0x75, 0x75, 0x6a, 0x73, 0x47, 0x5a, 0x6a, 0x48, 0x49, + 0x70, 0x79, 0x76, 0x71, 0x6f, 0x63, 0x53, 0x4d, 0x67, 0x46, 0x2f, 0x4d, + 0x68, 0x63, 0x54, 0x55, 0x78, 0x58, 0x65, 0x7a, 0x0a, 0x4d, 0x42, 0x2f, + 0x2b, 0x35, 0x68, 0x6c, 0x4b, 0x6c, 0x55, 0x46, 0x58, 0x58, 0x4c, 0x52, + 0x7a, 0x58, 0x58, 0x68, 0x48, 0x41, 0x69, 0x69, 0x52, 0x5a, 0x7a, 0x72, + 0x51, 0x68, 0x69, 0x4f, 0x70, 0x64, 0x42, 0x41, 0x56, 0x65, 0x58, 0x45, + 0x32, 0x62, 0x66, 0x53, 0x7a, 0x69, 0x62, 0x4e, 0x33, 0x70, 0x66, 0x42, + 0x66, 0x4e, 0x34, 0x6e, 0x44, 0x37, 0x4d, 0x2b, 0x41, 0x4b, 0x77, 0x75, + 0x5a, 0x30, 0x2b, 0x55, 0x5a, 0x49, 0x35, 0x53, 0x46, 0x48, 0x77, 0x63, + 0x39, 0x0a, 0x47, 0x54, 0x70, 0x67, 0x71, 0x6e, 0x48, 0x37, 0x38, 0x52, + 0x63, 0x39, 0x32, 0x51, 0x64, 0x43, 0x6b, 0x76, 0x58, 0x46, 0x73, 0x6c, + 0x4e, 0x51, 0x66, 0x41, 0x42, 0x46, 0x74, 0x51, 0x57, 0x68, 0x2b, 0x41, + 0x4b, 0x52, 0x62, 0x70, 0x34, 0x76, 0x57, 0x30, 0x4a, 0x49, 0x41, 0x52, + 0x4a, 0x54, 0x65, 0x62, 0x34, 0x76, 0x47, 0x41, 0x36, 0x67, 0x6a, 0x53, + 0x49, 0x62, 0x2f, 0x56, 0x45, 0x7a, 0x56, 0x68, 0x59, 0x76, 0x4c, 0x6a, + 0x68, 0x31, 0x58, 0x38, 0x31, 0x59, 0x0a, 0x6f, 0x51, 0x77, 0x6e, 0x4e, + 0x51, 0x77, 0x6e, 0x62, 0x66, 0x70, 0x58, 0x6d, 0x52, 0x54, 0x75, 0x34, + 0x63, 0x74, 0x53, 0x31, 0x2b, 0x34, 0x50, 0x4a, 0x50, 0x41, 0x79, 0x38, + 0x32, 0x2b, 0x43, 0x59, 0x35, 0x6d, 0x6a, 0x31, 0x39, 0x65, 0x43, 0x2f, + 0x38, 0x4c, 0x5a, 0x5a, 0x6d, 0x6b, 0x6e, 0x63, 0x79, 0x51, 0x33, 0x72, + 0x50, 0x38, 0x68, 0x6c, 0x30, 0x72, 0x35, 0x75, 0x6e, 0x55, 0x74, 0x69, + 0x55, 0x6b, 0x31, 0x53, 0x67, 0x63, 0x5a, 0x31, 0x34, 0x50, 0x42, 0x0a, + 0x69, 0x57, 0x64, 0x71, 0x56, 0x33, 0x72, 0x34, 0x4b, 0x47, 0x4c, 0x54, + 0x70, 0x69, 0x61, 0x4e, 0x68, 0x65, 0x61, 0x77, 0x6b, 0x52, 0x44, 0x30, + 0x76, 0x57, 0x56, 0x61, 0x6e, 0x6d, 0x49, 0x77, 0x42, 0x31, 0x31, 0x7a, + 0x76, 0x53, 0x6d, 0x76, 0x61, 0x4c, 0x2b, 0x4e, 0x62, 0x36, 0x75, 0x72, + 0x2b, 0x54, 0x36, 0x4f, 0x61, 0x75, 0x54, 0x37, 0x44, 0x37, 0x6e, 0x4a, + 0x36, 0x65, 0x69, 0x2b, 0x73, 0x57, 0x36, 0x42, 0x78, 0x37, 0x65, 0x76, + 0x78, 0x2f, 0x66, 0x45, 0x0a, 0x42, 0x79, 0x77, 0x56, 0x72, 0x37, 0x51, + 0x51, 0x39, 0x58, 0x67, 0x50, 0x55, 0x68, 0x30, 0x73, 0x31, 0x4c, 0x63, + 0x49, 0x79, 0x62, 0x71, 0x61, 0x2b, 0x6b, 0x61, 0x47, 0x46, 0x6e, 0x71, + 0x4e, 0x49, 0x62, 0x61, 0x78, 0x74, 0x64, 0x53, 0x4b, 0x7a, 0x42, 0x59, + 0x71, 0x46, 0x2b, 0x76, 0x4e, 0x73, 0x37, 0x43, 0x77, 0x34, 0x58, 0x55, + 0x4a, 0x46, 0x57, 0x58, 0x59, 0x62, 0x48, 0x50, 0x38, 0x37, 0x53, 0x38, + 0x6b, 0x75, 0x2f, 0x75, 0x38, 0x71, 0x76, 0x54, 0x31, 0x0a, 0x4c, 0x76, + 0x6b, 0x4c, 0x76, 0x72, 0x68, 0x4a, 0x66, 0x66, 0x53, 0x46, 0x72, 0x69, + 0x71, 0x34, 0x42, 0x6a, 0x4e, 0x7a, 0x58, 0x7a, 0x42, 0x69, 0x32, 0x38, + 0x43, 0x7a, 0x49, 0x65, 0x74, 0x4c, 0x4d, 0x77, 0x68, 0x53, 0x6b, 0x64, + 0x79, 0x64, 0x38, 0x58, 0x41, 0x43, 0x52, 0x34, 0x51, 0x61, 0x70, 0x64, + 0x32, 0x63, 0x61, 0x59, 0x2f, 0x78, 0x6c, 0x35, 0x4c, 0x59, 0x76, 0x69, + 0x4c, 0x79, 0x6b, 0x51, 0x37, 0x4b, 0x52, 0x73, 0x45, 0x68, 0x6e, 0x35, + 0x4f, 0x35, 0x0a, 0x69, 0x62, 0x65, 0x37, 0x69, 0x42, 0x43, 0x6a, 0x65, + 0x4b, 0x64, 0x42, 0x36, 0x68, 0x4e, 0x2f, 0x61, 0x6d, 0x4c, 0x45, 0x55, + 0x6b, 0x2f, 0x79, 0x6a, 0x42, 0x62, 0x77, 0x4d, 0x67, 0x68, 0x73, 0x57, + 0x4e, 0x69, 0x35, 0x6e, 0x51, 0x4a, 0x6f, 0x57, 0x53, 0x59, 0x76, 0x73, + 0x58, 0x42, 0x73, 0x77, 0x59, 0x79, 0x38, 0x6f, 0x33, 0x34, 0x50, 0x66, + 0x4c, 0x4a, 0x50, 0x78, 0x54, 0x37, 0x76, 0x37, 0x4b, 0x48, 0x47, 0x69, + 0x6a, 0x55, 0x5a, 0x7a, 0x43, 0x54, 0x63, 0x0a, 0x76, 0x69, 0x51, 0x77, + 0x6a, 0x50, 0x49, 0x61, 0x69, 0x49, 0x33, 0x6d, 0x65, 0x74, 0x44, 0x46, + 0x46, 0x7a, 0x77, 0x64, 0x35, 0x72, 0x54, 0x66, 0x59, 0x75, 0x7a, 0x38, + 0x46, 0x4c, 0x4d, 0x76, 0x41, 0x39, 0x62, 0x49, 0x63, 0x30, 0x4d, 0x53, + 0x46, 0x55, 0x52, 0x53, 0x36, 0x38, 0x6b, 0x71, 0x65, 0x32, 0x77, 0x2b, + 0x67, 0x6c, 0x4b, 0x76, 0x4c, 0x2f, 0x69, 0x6f, 0x31, 0x63, 0x7a, 0x48, + 0x6a, 0x2f, 0x32, 0x39, 0x74, 0x37, 0x37, 0x53, 0x6c, 0x47, 0x6f, 0x42, + 0x0a, 0x66, 0x4b, 0x37, 0x78, 0x4b, 0x71, 0x73, 0x4d, 0x77, 0x6e, 0x70, + 0x69, 0x65, 0x6c, 0x64, 0x7a, 0x4c, 0x6d, 0x77, 0x63, 0x4a, 0x52, 0x66, + 0x59, 0x52, 0x35, 0x4b, 0x62, 0x37, 0x4d, 0x31, 0x7a, 0x57, 0x41, 0x79, + 0x62, 0x54, 0x58, 0x6d, 0x58, 0x45, 0x4b, 0x64, 0x48, 0x34, 0x7a, 0x4f, + 0x36, 0x2b, 0x4a, 0x33, 0x73, 0x53, 0x73, 0x37, 0x33, 0x71, 0x33, 0x69, + 0x61, 0x58, 0x6c, 0x46, 0x6a, 0x47, 0x74, 0x56, 0x48, 0x45, 0x42, 0x38, + 0x70, 0x62, 0x56, 0x51, 0x47, 0x0a, 0x75, 0x62, 0x6e, 0x59, 0x31, 0x57, + 0x43, 0x49, 0x77, 0x34, 0x53, 0x57, 0x43, 0x52, 0x6a, 0x57, 0x49, 0x4b, + 0x58, 0x61, 0x4b, 0x35, 0x33, 0x4b, 0x36, 0x32, 0x6c, 0x55, 0x55, 0x4b, + 0x36, 0x58, 0x41, 0x6b, 0x77, 0x55, 0x68, 0x59, 0x6c, 0x47, 0x54, 0x76, + 0x77, 0x4d, 0x63, 0x58, 0x65, 0x49, 0x73, 0x77, 0x7a, 0x38, 0x55, 0x50, + 0x2f, 0x31, 0x71, 0x59, 0x39, 0x66, 0x36, 0x52, 0x30, 0x48, 0x37, 0x66, + 0x62, 0x64, 0x34, 0x4f, 0x76, 0x42, 0x53, 0x69, 0x58, 0x48, 0x0a, 0x79, + 0x6e, 0x73, 0x51, 0x6a, 0x35, 0x77, 0x52, 0x38, 0x79, 0x50, 0x6d, 0x49, + 0x4f, 0x49, 0x54, 0x4e, 0x4f, 0x4b, 0x49, 0x56, 0x48, 0x65, 0x37, 0x6d, + 0x6a, 0x65, 0x6c, 0x52, 0x39, 0x34, 0x77, 0x6f, 0x42, 0x37, 0x5a, 0x69, + 0x48, 0x4e, 0x4d, 0x42, 0x63, 0x35, 0x59, 0x36, 0x7a, 0x4b, 0x48, 0x5a, + 0x31, 0x70, 0x58, 0x77, 0x6a, 0x67, 0x4f, 0x78, 0x67, 0x43, 0x6b, 0x4e, + 0x34, 0x32, 0x4a, 0x66, 0x36, 0x6d, 0x36, 0x43, 0x5a, 0x39, 0x41, 0x64, + 0x47, 0x48, 0x6c, 0x0a, 0x59, 0x54, 0x72, 0x75, 0x74, 0x48, 0x55, 0x57, + 0x45, 0x35, 0x36, 0x59, 0x47, 0x35, 0x2b, 0x53, 0x46, 0x4e, 0x41, 0x4a, + 0x6e, 0x7a, 0x50, 0x44, 0x4b, 0x64, 0x71, 0x73, 0x57, 0x7a, 0x32, 0x73, + 0x39, 0x58, 0x4f, 0x4a, 0x39, 0x36, 0x41, 0x68, 0x71, 0x2f, 0x45, 0x37, + 0x6c, 0x66, 0x38, 0x6b, 0x64, 0x71, 0x62, 0x6d, 0x42, 0x75, 0x7a, 0x2b, + 0x7a, 0x6c, 0x65, 0x34, 0x61, 0x46, 0x31, 0x7a, 0x70, 0x61, 0x6b, 0x41, + 0x37, 0x57, 0x62, 0x58, 0x42, 0x59, 0x73, 0x6f, 0x0a, 0x2f, 0x2f, 0x47, + 0x52, 0x5a, 0x79, 0x48, 0x68, 0x35, 0x38, 0x31, 0x6c, 0x49, 0x43, 0x4a, + 0x4f, 0x58, 0x52, 0x74, 0x37, 0x4c, 0x5a, 0x30, 0x74, 0x79, 0x62, 0x58, + 0x75, 0x72, 0x31, 0x57, 0x67, 0x47, 0x50, 0x58, 0x58, 0x32, 0x42, 0x37, + 0x77, 0x4f, 0x75, 0x59, 0x6e, 0x31, 0x42, 0x71, 0x54, 0x4f, 0x62, 0x73, + 0x5a, 0x4c, 0x61, 0x37, 0x77, 0x38, 0x4f, 0x34, 0x30, 0x45, 0x76, 0x78, + 0x49, 0x73, 0x4a, 0x66, 0x4f, 0x66, 0x46, 0x4c, 0x64, 0x39, 0x79, 0x71, + 0x62, 0x0a, 0x46, 0x62, 0x54, 0x31, 0x38, 0x78, 0x4d, 0x57, 0x4c, 0x51, + 0x38, 0x77, 0x76, 0x33, 0x76, 0x66, 0x79, 0x6b, 0x54, 0x55, 0x52, 0x69, + 0x64, 0x48, 0x7a, 0x54, 0x79, 0x2f, 0x31, 0x68, 0x76, 0x45, 0x4a, 0x45, + 0x73, 0x65, 0x39, 0x56, 0x42, 0x56, 0x7a, 0x59, 0x53, 0x46, 0x63, 0x55, + 0x62, 0x55, 0x72, 0x47, 0x2b, 0x2f, 0x4c, 0x49, 0x43, 0x34, 0x6a, 0x6c, + 0x54, 0x78, 0x44, 0x64, 0x67, 0x48, 0x64, 0x37, 0x79, 0x74, 0x68, 0x4a, + 0x37, 0x4e, 0x77, 0x4c, 0x68, 0x68, 0x0a, 0x63, 0x77, 0x68, 0x42, 0x2f, + 0x55, 0x2b, 0x7a, 0x34, 0x39, 0x78, 0x62, 0x50, 0x76, 0x37, 0x6c, 0x76, + 0x66, 0x54, 0x4c, 0x71, 0x34, 0x55, 0x61, 0x48, 0x55, 0x34, 0x37, 0x71, + 0x51, 0x37, 0x64, 0x2f, 0x34, 0x73, 0x48, 0x7a, 0x31, 0x73, 0x79, 0x4b, + 0x37, 0x6c, 0x4d, 0x4c, 0x44, 0x37, 0x70, 0x51, 0x31, 0x30, 0x79, 0x61, + 0x61, 0x4c, 0x4a, 0x73, 0x45, 0x38, 0x55, 0x42, 0x79, 0x69, 0x67, 0x4c, + 0x71, 0x56, 0x74, 0x45, 0x77, 0x65, 0x57, 0x6b, 0x4c, 0x46, 0x56, 0x0a, + 0x4d, 0x30, 0x4d, 0x6a, 0x55, 0x35, 0x31, 0x72, 0x69, 0x72, 0x57, 0x70, + 0x52, 0x75, 0x62, 0x72, 0x47, 0x64, 0x53, 0x46, 0x73, 0x58, 0x44, 0x6c, + 0x31, 0x4e, 0x31, 0x57, 0x53, 0x67, 0x65, 0x6f, 0x30, 0x5a, 0x75, 0x75, + 0x37, 0x41, 0x4a, 0x64, 0x74, 0x42, 0x43, 0x68, 0x64, 0x31, 0x62, 0x6d, + 0x53, 0x2f, 0x39, 0x56, 0x39, 0x48, 0x43, 0x69, 0x42, 0x46, 0x79, 0x33, + 0x71, 0x42, 0x43, 0x2b, 0x33, 0x4b, 0x79, 0x34, 0x6f, 0x4e, 0x4d, 0x6b, + 0x6c, 0x4c, 0x46, 0x6f, 0x0a, 0x54, 0x6f, 0x58, 0x77, 0x33, 0x32, 0x63, + 0x43, 0x31, 0x30, 0x34, 0x39, 0x63, 0x49, 0x69, 0x47, 0x35, 0x68, 0x37, + 0x6b, 0x34, 0x54, 0x30, 0x66, 0x42, 0x48, 0x75, 0x75, 0x46, 0x78, 0x42, + 0x7a, 0x71, 0x4e, 0x31, 0x67, 0x34, 0x45, 0x67, 0x70, 0x76, 0x54, 0x69, + 0x6f, 0x52, 0x51, 0x6f, 0x54, 0x62, 0x59, 0x6a, 0x6e, 0x6c, 0x70, 0x4a, + 0x50, 0x6a, 0x68, 0x75, 0x78, 0x51, 0x38, 0x42, 0x32, 0x78, 0x51, 0x77, + 0x38, 0x34, 0x39, 0x6a, 0x78, 0x34, 0x6f, 0x44, 0x44, 0x0a, 0x63, 0x72, + 0x51, 0x64, 0x66, 0x33, 0x6b, 0x4c, 0x50, 0x72, 0x6f, 0x38, 0x69, 0x2f, + 0x48, 0x51, 0x42, 0x67, 0x55, 0x38, 0x67, 0x7a, 0x50, 0x6d, 0x69, 0x41, + 0x6f, 0x51, 0x59, 0x4f, 0x52, 0x41, 0x56, 0x6d, 0x68, 0x47, 0x37, 0x45, + 0x4f, 0x38, 0x4b, 0x5a, 0x74, 0x38, 0x4c, 0x72, 0x76, 0x52, 0x77, 0x49, + 0x49, 0x51, 0x4a, 0x76, 0x70, 0x5a, 0x64, 0x6f, 0x50, 0x4b, 0x6b, 0x38, + 0x39, 0x43, 0x68, 0x48, 0x73, 0x4e, 0x48, 0x7a, 0x4a, 0x6c, 0x35, 0x71, + 0x77, 0x52, 0x0a, 0x4e, 0x32, 0x66, 0x41, 0x73, 0x65, 0x52, 0x30, 0x79, + 0x69, 0x4b, 0x50, 0x30, 0x64, 0x4a, 0x56, 0x50, 0x7a, 0x4d, 0x51, 0x4c, + 0x5a, 0x36, 0x6a, 0x43, 0x73, 0x30, 0x75, 0x57, 0x68, 0x6e, 0x72, 0x75, + 0x56, 0x50, 0x57, 0x43, 0x65, 0x4e, 0x4d, 0x79, 0x6b, 0x41, 0x47, 0x74, + 0x39, 0x34, 0x6d, 0x6b, 0x4b, 0x76, 0x6a, 0x78, 0x6b, 0x6b, 0x55, 0x62, + 0x62, 0x39, 0x5a, 0x53, 0x37, 0x63, 0x39, 0x5a, 0x4f, 0x5a, 0x71, 0x77, + 0x42, 0x76, 0x6f, 0x57, 0x67, 0x6e, 0x54, 0x0a, 0x42, 0x7a, 0x6d, 0x71, + 0x61, 0x54, 0x58, 0x79, 0x77, 0x43, 0x33, 0x68, 0x69, 0x38, 0x43, 0x30, + 0x4c, 0x55, 0x59, 0x30, 0x58, 0x65, 0x73, 0x65, 0x57, 0x77, 0x6c, 0x70, + 0x4e, 0x49, 0x2f, 0x6b, 0x37, 0x55, 0x42, 0x4d, 0x39, 0x63, 0x45, 0x6f, + 0x70, 0x44, 0x46, 0x46, 0x38, 0x2b, 0x63, 0x52, 0x6a, 0x67, 0x4a, 0x63, + 0x31, 0x30, 0x64, 0x4e, 0x41, 0x6f, 0x51, 0x52, 0x76, 0x38, 0x65, 0x36, + 0x30, 0x57, 0x74, 0x73, 0x6d, 0x58, 0x45, 0x35, 0x4c, 0x56, 0x4a, 0x37, + 0x0a, 0x66, 0x4e, 0x57, 0x64, 0x54, 0x69, 0x7a, 0x47, 0x56, 0x6e, 0x4c, + 0x7a, 0x63, 0x6d, 0x47, 0x38, 0x78, 0x45, 0x52, 0x4e, 0x50, 0x30, 0x7a, + 0x5a, 0x4d, 0x55, 0x58, 0x4e, 0x6e, 0x2f, 0x58, 0x34, 0x7a, 0x46, 0x75, + 0x39, 0x51, 0x75, 0x6a, 0x44, 0x6e, 0x6e, 0x59, 0x75, 0x65, 0x35, 0x6c, + 0x50, 0x45, 0x4f, 0x6f, 0x69, 0x72, 0x59, 0x46, 0x43, 0x53, 0x65, 0x4e, + 0x70, 0x71, 0x58, 0x62, 0x53, 0x51, 0x75, 0x79, 0x75, 0x61, 0x59, 0x45, + 0x63, 0x6d, 0x79, 0x57, 0x72, 0x0a, 0x79, 0x75, 0x31, 0x63, 0x56, 0x6f, + 0x51, 0x72, 0x37, 0x76, 0x77, 0x53, 0x78, 0x57, 0x57, 0x2f, 0x66, 0x62, + 0x49, 0x71, 0x5a, 0x56, 0x61, 0x76, 0x39, 0x77, 0x4b, 0x62, 0x64, 0x48, + 0x38, 0x54, 0x56, 0x76, 0x56, 0x52, 0x68, 0x4e, 0x6b, 0x43, 0x36, 0x79, + 0x4f, 0x6f, 0x70, 0x55, 0x48, 0x4b, 0x36, 0x72, 0x62, 0x4d, 0x63, 0x37, + 0x4e, 0x6e, 0x43, 0x37, 0x4e, 0x76, 0x48, 0x73, 0x34, 0x49, 0x7a, 0x30, + 0x75, 0x33, 0x72, 0x57, 0x31, 0x4b, 0x52, 0x41, 0x53, 0x55, 0x0a, 0x46, + 0x56, 0x6b, 0x64, 0x42, 0x4d, 0x38, 0x72, 0x52, 0x5a, 0x4d, 0x70, 0x50, + 0x75, 0x59, 0x66, 0x34, 0x32, 0x6d, 0x42, 0x67, 0x56, 0x59, 0x63, 0x59, + 0x65, 0x58, 0x4c, 0x32, 0x42, 0x4f, 0x58, 0x6a, 0x76, 0x49, 0x42, 0x4c, + 0x37, 0x5a, 0x42, 0x48, 0x2f, 0x6f, 0x6f, 0x66, 0x35, 0x4c, 0x49, 0x55, + 0x6a, 0x68, 0x38, 0x4b, 0x68, 0x2b, 0x4a, 0x42, 0x38, 0x2f, 0x31, 0x79, + 0x42, 0x31, 0x58, 0x67, 0x61, 0x4d, 0x61, 0x53, 0x4e, 0x68, 0x2b, 0x32, + 0x38, 0x4d, 0x66, 0x0a, 0x75, 0x38, 0x7a, 0x79, 0x79, 0x42, 0x65, 0x70, + 0x72, 0x37, 0x63, 0x4c, 0x76, 0x57, 0x37, 0x77, 0x7a, 0x5a, 0x59, 0x69, + 0x41, 0x4e, 0x6f, 0x51, 0x4f, 0x64, 0x4c, 0x46, 0x77, 0x35, 0x4b, 0x63, + 0x77, 0x47, 0x45, 0x69, 0x51, 0x35, 0x30, 0x58, 0x44, 0x79, 0x49, 0x33, + 0x49, 0x75, 0x46, 0x72, 0x30, 0x67, 0x58, 0x58, 0x38, 0x74, 0x76, 0x73, + 0x50, 0x35, 0x6e, 0x6e, 0x68, 0x6b, 0x55, 0x61, 0x54, 0x76, 0x63, 0x7a, + 0x37, 0x2f, 0x45, 0x52, 0x72, 0x62, 0x64, 0x79, 0x0a, 0x6c, 0x58, 0x4e, + 0x34, 0x55, 0x69, 0x79, 0x44, 0x62, 0x78, 0x6b, 0x4e, 0x6e, 0x76, 0x6f, + 0x67, 0x61, 0x6f, 0x4b, 0x2b, 0x6e, 0x33, 0x72, 0x6c, 0x52, 0x79, 0x6e, + 0x32, 0x2f, 0x62, 0x2f, 0x56, 0x50, 0x53, 0x2b, 0x4a, 0x72, 0x4e, 0x4f, + 0x75, 0x72, 0x52, 0x55, 0x68, 0x37, 0x58, 0x49, 0x34, 0x4a, 0x59, 0x35, + 0x6f, 0x32, 0x50, 0x42, 0x79, 0x31, 0x74, 0x34, 0x77, 0x59, 0x45, 0x49, + 0x64, 0x49, 0x42, 0x4d, 0x70, 0x2b, 0x47, 0x78, 0x51, 0x34, 0x67, 0x61, + 0x6d, 0x0a, 0x72, 0x74, 0x77, 0x62, 0x4e, 0x49, 0x77, 0x2b, 0x34, 0x74, + 0x69, 0x4b, 0x43, 0x5a, 0x71, 0x5a, 0x65, 0x72, 0x44, 0x35, 0x4f, 0x4c, + 0x44, 0x31, 0x61, 0x4a, 0x66, 0x39, 0x54, 0x5a, 0x7a, 0x39, 0x6f, 0x5a, + 0x64, 0x58, 0x2f, 0x48, 0x6d, 0x4e, 0x52, 0x38, 0x6f, 0x72, 0x75, 0x6d, + 0x68, 0x43, 0x2f, 0x68, 0x71, 0x45, 0x31, 0x4a, 0x4f, 0x5a, 0x55, 0x59, + 0x2f, 0x6a, 0x73, 0x58, 0x61, 0x47, 0x30, 0x43, 0x52, 0x6d, 0x47, 0x49, + 0x6a, 0x37, 0x47, 0x42, 0x64, 0x47, 0x0a, 0x4d, 0x50, 0x6c, 0x4e, 0x35, + 0x48, 0x70, 0x46, 0x55, 0x6e, 0x6a, 0x75, 0x6f, 0x55, 0x47, 0x6c, 0x31, + 0x6c, 0x31, 0x55, 0x4f, 0x64, 0x32, 0x36, 0x4d, 0x56, 0x79, 0x53, 0x7a, + 0x4d, 0x58, 0x6f, 0x79, 0x36, 0x78, 0x61, 0x76, 0x7a, 0x62, 0x65, 0x35, + 0x72, 0x35, 0x63, 0x37, 0x36, 0x4d, 0x6b, 0x52, 0x69, 0x4f, 0x53, 0x30, + 0x70, 0x62, 0x6f, 0x69, 0x34, 0x6d, 0x75, 0x41, 0x64, 0x37, 0x38, 0x34, + 0x39, 0x36, 0x79, 0x42, 0x4b, 0x73, 0x6e, 0x67, 0x75, 0x7a, 0x55, 0x0a, + 0x33, 0x77, 0x2b, 0x33, 0x6f, 0x31, 0x32, 0x35, 0x59, 0x54, 0x64, 0x67, + 0x66, 0x4c, 0x46, 0x4e, 0x55, 0x65, 0x7a, 0x48, 0x76, 0x76, 0x4d, 0x41, + 0x6f, 0x74, 0x73, 0x42, 0x51, 0x67, 0x4a, 0x46, 0x64, 0x78, 0x4c, 0x68, + 0x77, 0x53, 0x4c, 0x59, 0x49, 0x5a, 0x47, 0x51, 0x45, 0x6b, 0x46, 0x67, + 0x52, 0x66, 0x31, 0x71, 0x4c, 0x58, 0x6b, 0x62, 0x54, 0x73, 0x73, 0x7a, + 0x78, 0x41, 0x39, 0x2b, 0x57, 0x37, 0x50, 0x73, 0x45, 0x79, 0x4b, 0x74, + 0x65, 0x56, 0x2b, 0x4a, 0x0a, 0x48, 0x4f, 0x76, 0x4c, 0x67, 0x67, 0x70, + 0x74, 0x76, 0x47, 0x7a, 0x71, 0x42, 0x6e, 0x30, 0x39, 0x36, 0x6b, 0x6a, + 0x59, 0x59, 0x68, 0x38, 0x64, 0x43, 0x65, 0x61, 0x72, 0x61, 0x62, 0x32, + 0x49, 0x54, 0x32, 0x67, 0x2b, 0x4e, 0x49, 0x44, 0x50, 0x44, 0x42, 0x55, + 0x67, 0x58, 0x61, 0x35, 0x31, 0x61, 0x38, 0x58, 0x76, 0x5a, 0x76, 0x78, + 0x6e, 0x72, 0x49, 0x56, 0x36, 0x4d, 0x4b, 0x79, 0x34, 0x59, 0x66, 0x78, + 0x4c, 0x53, 0x4b, 0x54, 0x4c, 0x61, 0x35, 0x67, 0x43, 0x0a, 0x50, 0x46, + 0x62, 0x2f, 0x73, 0x4c, 0x74, 0x5a, 0x51, 0x51, 0x44, 0x55, 0x61, 0x79, + 0x48, 0x76, 0x4d, 0x6f, 0x59, 0x6c, 0x6e, 0x66, 0x4c, 0x45, 0x6d, 0x44, + 0x6a, 0x71, 0x49, 0x44, 0x6d, 0x66, 0x6c, 0x36, 0x37, 0x68, 0x59, 0x2f, + 0x5a, 0x65, 0x4c, 0x54, 0x6f, 0x4e, 0x74, 0x76, 0x59, 0x42, 0x37, 0x49, + 0x79, 0x48, 0x6a, 0x55, 0x55, 0x41, 0x6f, 0x4b, 0x50, 0x36, 0x36, 0x50, + 0x5a, 0x67, 0x71, 0x75, 0x6d, 0x72, 0x2f, 0x2f, 0x78, 0x73, 0x67, 0x73, + 0x79, 0x4b, 0x0a, 0x56, 0x34, 0x49, 0x6a, 0x38, 0x79, 0x61, 0x41, 0x2b, + 0x36, 0x78, 0x43, 0x77, 0x63, 0x6a, 0x6f, 0x6d, 0x53, 0x48, 0x7a, 0x2f, + 0x32, 0x45, 0x43, 0x74, 0x72, 0x64, 0x5a, 0x46, 0x4e, 0x4b, 0x79, 0x57, + 0x36, 0x35, 0x2b, 0x70, 0x76, 0x44, 0x74, 0x64, 0x64, 0x7a, 0x6a, 0x50, + 0x79, 0x6e, 0x74, 0x53, 0x43, 0x6b, 0x72, 0x66, 0x4e, 0x74, 0x51, 0x68, + 0x56, 0x2b, 0x70, 0x62, 0x34, 0x77, 0x4b, 0x39, 0x51, 0x34, 0x70, 0x4d, + 0x63, 0x4e, 0x38, 0x73, 0x75, 0x44, 0x78, 0x0a, 0x66, 0x78, 0x4f, 0x70, + 0x45, 0x34, 0x74, 0x4e, 0x2b, 0x77, 0x61, 0x56, 0x4d, 0x6d, 0x48, 0x52, + 0x31, 0x57, 0x4c, 0x46, 0x54, 0x37, 0x47, 0x6c, 0x7a, 0x36, 0x35, 0x47, + 0x68, 0x2f, 0x57, 0x35, 0x2b, 0x55, 0x4e, 0x73, 0x6c, 0x56, 0x31, 0x35, + 0x48, 0x6d, 0x7a, 0x73, 0x58, 0x4a, 0x71, 0x48, 0x4a, 0x78, 0x6f, 0x41, + 0x34, 0x56, 0x4e, 0x38, 0x6e, 0x4b, 0x69, 0x72, 0x70, 0x42, 0x6f, 0x31, + 0x59, 0x32, 0x42, 0x47, 0x6c, 0x66, 0x50, 0x42, 0x6f, 0x71, 0x56, 0x6c, + 0x0a, 0x2b, 0x4e, 0x50, 0x64, 0x75, 0x6a, 0x39, 0x4f, 0x45, 0x74, 0x4b, + 0x72, 0x75, 0x71, 0x38, 0x69, 0x4b, 0x2b, 0x64, 0x55, 0x59, 0x61, 0x74, + 0x64, 0x36, 0x4c, 0x61, 0x69, 0x2b, 0x51, 0x49, 0x57, 0x79, 0x44, 0x47, + 0x42, 0x70, 0x4b, 0x56, 0x36, 0x63, 0x2b, 0x70, 0x42, 0x45, 0x33, 0x39, + 0x45, 0x42, 0x6f, 0x6b, 0x34, 0x30, 0x78, 0x32, 0x71, 0x75, 0x55, 0x76, + 0x55, 0x59, 0x62, 0x44, 0x79, 0x47, 0x57, 0x59, 0x62, 0x6f, 0x42, 0x57, + 0x2b, 0x72, 0x4c, 0x4b, 0x54, 0x0a, 0x58, 0x45, 0x6c, 0x72, 0x50, 0x49, + 0x6d, 0x74, 0x47, 0x52, 0x6e, 0x31, 0x46, 0x6b, 0x62, 0x58, 0x68, 0x6e, + 0x64, 0x4b, 0x78, 0x31, 0x58, 0x50, 0x65, 0x70, 0x75, 0x30, 0x70, 0x59, + 0x72, 0x64, 0x7a, 0x31, 0x58, 0x6d, 0x77, 0x49, 0x74, 0x5a, 0x53, 0x6c, + 0x66, 0x52, 0x46, 0x48, 0x59, 0x4c, 0x35, 0x61, 0x57, 0x38, 0x38, 0x37, + 0x51, 0x4b, 0x6b, 0x39, 0x38, 0x53, 0x52, 0x4e, 0x6e, 0x34, 0x56, 0x35, + 0x32, 0x5a, 0x77, 0x44, 0x6e, 0x67, 0x71, 0x36, 0x66, 0x50, 0x0a, 0x35, + 0x61, 0x62, 0x55, 0x32, 0x63, 0x2f, 0x77, 0x78, 0x67, 0x77, 0x56, 0x49, + 0x77, 0x77, 0x2f, 0x74, 0x64, 0x33, 0x4a, 0x61, 0x36, 0x77, 0x47, 0x44, + 0x42, 0x49, 0x63, 0x4d, 0x68, 0x4d, 0x75, 0x53, 0x7a, 0x42, 0x39, 0x48, + 0x6c, 0x6f, 0x69, 0x65, 0x6d, 0x71, 0x62, 0x43, 0x62, 0x73, 0x4d, 0x2f, + 0x53, 0x63, 0x43, 0x79, 0x54, 0x30, 0x73, 0x47, 0x2f, 0x61, 0x4b, 0x76, + 0x35, 0x6c, 0x4c, 0x65, 0x36, 0x62, 0x39, 0x59, 0x45, 0x50, 0x39, 0x66, + 0x6d, 0x45, 0x4f, 0x0a, 0x78, 0x6d, 0x75, 0x4e, 0x6f, 0x6a, 0x59, 0x47, + 0x36, 0x76, 0x4e, 0x79, 0x43, 0x78, 0x48, 0x52, 0x4c, 0x39, 0x59, 0x4a, + 0x41, 0x41, 0x2f, 0x58, 0x6d, 0x4e, 0x64, 0x32, 0x43, 0x4b, 0x59, 0x42, + 0x45, 0x79, 0x56, 0x62, 0x4e, 0x44, 0x4e, 0x50, 0x65, 0x43, 0x4a, 0x67, + 0x66, 0x35, 0x31, 0x6f, 0x4d, 0x62, 0x77, 0x30, 0x61, 0x72, 0x65, 0x38, + 0x58, 0x6b, 0x66, 0x62, 0x56, 0x36, 0x34, 0x49, 0x45, 0x44, 0x43, 0x45, + 0x4b, 0x2f, 0x56, 0x6a, 0x68, 0x59, 0x57, 0x51, 0x0a, 0x75, 0x42, 0x53, + 0x6c, 0x54, 0x56, 0x6b, 0x46, 0x6b, 0x58, 0x57, 0x67, 0x32, 0x31, 0x41, + 0x45, 0x67, 0x74, 0x78, 0x79, 0x56, 0x7a, 0x78, 0x6c, 0x31, 0x6e, 0x56, + 0x69, 0x41, 0x6a, 0x74, 0x6e, 0x31, 0x72, 0x38, 0x59, 0x72, 0x73, 0x45, + 0x48, 0x33, 0x74, 0x51, 0x73, 0x47, 0x32, 0x64, 0x34, 0x48, 0x32, 0x65, + 0x44, 0x4c, 0x69, 0x36, 0x49, 0x39, 0x7a, 0x79, 0x48, 0x77, 0x6d, 0x70, + 0x56, 0x4b, 0x33, 0x51, 0x79, 0x66, 0x71, 0x42, 0x47, 0x66, 0x63, 0x74, + 0x64, 0x0a, 0x64, 0x78, 0x5a, 0x46, 0x6f, 0x74, 0x6e, 0x4a, 0x2b, 0x73, + 0x73, 0x6c, 0x37, 0x34, 0x31, 0x33, 0x30, 0x4f, 0x6d, 0x63, 0x67, 0x59, + 0x74, 0x35, 0x6d, 0x70, 0x35, 0x57, 0x4c, 0x2f, 0x4b, 0x4f, 0x58, 0x41, + 0x4c, 0x63, 0x55, 0x64, 0x34, 0x45, 0x59, 0x50, 0x49, 0x58, 0x57, 0x66, + 0x71, 0x6a, 0x4e, 0x77, 0x6d, 0x78, 0x4b, 0x75, 0x77, 0x74, 0x6e, 0x50, + 0x50, 0x6e, 0x71, 0x32, 0x67, 0x75, 0x55, 0x46, 0x44, 0x32, 0x42, 0x70, + 0x42, 0x35, 0x77, 0x2f, 0x45, 0x69, 0x0a, 0x65, 0x71, 0x50, 0x32, 0x66, + 0x2f, 0x6b, 0x7a, 0x58, 0x77, 0x79, 0x33, 0x4e, 0x57, 0x42, 0x4d, 0x79, + 0x70, 0x4b, 0x50, 0x4b, 0x79, 0x46, 0x4f, 0x7a, 0x32, 0x7a, 0x6a, 0x52, + 0x30, 0x61, 0x56, 0x41, 0x35, 0x73, 0x78, 0x41, 0x42, 0x2f, 0x6d, 0x77, + 0x38, 0x59, 0x51, 0x4c, 0x55, 0x34, 0x6c, 0x54, 0x73, 0x36, 0x39, 0x2f, + 0x44, 0x35, 0x74, 0x4b, 0x35, 0x55, 0x4a, 0x44, 0x39, 0x46, 0x59, 0x52, + 0x4f, 0x6d, 0x66, 0x57, 0x75, 0x6b, 0x42, 0x61, 0x34, 0x76, 0x4b, 0x0a, + 0x33, 0x39, 0x72, 0x57, 0x52, 0x34, 0x78, 0x30, 0x6b, 0x47, 0x72, 0x78, + 0x47, 0x76, 0x35, 0x35, 0x6b, 0x54, 0x31, 0x6f, 0x6e, 0x56, 0x61, 0x78, + 0x55, 0x30, 0x53, 0x66, 0x66, 0x56, 0x6f, 0x78, 0x68, 0x61, 0x75, 0x72, + 0x6f, 0x44, 0x34, 0x36, 0x33, 0x77, 0x37, 0x50, 0x42, 0x70, 0x66, 0x69, + 0x42, 0x46, 0x63, 0x36, 0x62, 0x39, 0x34, 0x56, 0x66, 0x34, 0x74, 0x79, + 0x51, 0x43, 0x7a, 0x4a, 0x38, 0x4b, 0x68, 0x7a, 0x63, 0x7a, 0x77, 0x62, + 0x58, 0x59, 0x57, 0x46, 0x0a, 0x46, 0x58, 0x35, 0x36, 0x55, 0x67, 0x64, + 0x4e, 0x6f, 0x36, 0x77, 0x77, 0x72, 0x47, 0x57, 0x7a, 0x57, 0x39, 0x43, + 0x42, 0x34, 0x55, 0x49, 0x34, 0x75, 0x44, 0x43, 0x64, 0x55, 0x4f, 0x5a, + 0x75, 0x63, 0x59, 0x30, 0x42, 0x77, 0x6b, 0x54, 0x58, 0x55, 0x72, 0x6e, + 0x62, 0x68, 0x43, 0x72, 0x66, 0x78, 0x42, 0x7a, 0x7a, 0x2b, 0x37, 0x4f, + 0x64, 0x43, 0x55, 0x65, 0x72, 0x69, 0x31, 0x79, 0x63, 0x59, 0x74, 0x48, + 0x54, 0x38, 0x47, 0x67, 0x41, 0x54, 0x30, 0x49, 0x4a, 0x0a, 0x6c, 0x4f, + 0x6a, 0x4c, 0x56, 0x69, 0x4e, 0x49, 0x35, 0x4a, 0x6e, 0x38, 0x49, 0x36, + 0x57, 0x74, 0x58, 0x35, 0x6f, 0x48, 0x7a, 0x35, 0x6c, 0x33, 0x43, 0x42, + 0x44, 0x58, 0x64, 0x75, 0x73, 0x6b, 0x55, 0x77, 0x33, 0x54, 0x4a, 0x63, + 0x42, 0x76, 0x7a, 0x31, 0x63, 0x5a, 0x4e, 0x69, 0x31, 0x70, 0x2b, 0x6c, + 0x6e, 0x43, 0x54, 0x44, 0x57, 0x69, 0x79, 0x47, 0x71, 0x50, 0x35, 0x35, + 0x34, 0x38, 0x63, 0x68, 0x4c, 0x54, 0x47, 0x6f, 0x6e, 0x42, 0x79, 0x50, + 0x39, 0x74, 0x0a, 0x39, 0x46, 0x67, 0x32, 0x65, 0x4c, 0x67, 0x61, 0x70, + 0x6f, 0x52, 0x72, 0x58, 0x36, 0x30, 0x51, 0x4e, 0x2b, 0x7a, 0x68, 0x47, + 0x2b, 0x51, 0x4d, 0x6f, 0x30, 0x58, 0x4a, 0x44, 0x71, 0x6c, 0x38, 0x79, + 0x56, 0x34, 0x63, 0x73, 0x2f, 0x72, 0x5a, 0x6a, 0x55, 0x53, 0x4b, 0x62, + 0x6b, 0x55, 0x37, 0x61, 0x46, 0x46, 0x61, 0x73, 0x6d, 0x52, 0x62, 0x6c, + 0x45, 0x75, 0x61, 0x32, 0x61, 0x47, 0x55, 0x77, 0x50, 0x2f, 0x6c, 0x69, + 0x58, 0x56, 0x4b, 0x59, 0x36, 0x42, 0x72, 0x0a, 0x6d, 0x32, 0x71, 0x57, + 0x75, 0x49, 0x75, 0x2b, 0x62, 0x68, 0x41, 0x2b, 0x62, 0x76, 0x6b, 0x6e, + 0x33, 0x42, 0x42, 0x61, 0x77, 0x46, 0x35, 0x52, 0x43, 0x69, 0x55, 0x52, + 0x62, 0x76, 0x53, 0x52, 0x54, 0x72, 0x46, 0x4c, 0x50, 0x63, 0x78, 0x69, + 0x6b, 0x6c, 0x53, 0x78, 0x6c, 0x72, 0x74, 0x6f, 0x34, 0x68, 0x38, 0x63, + 0x4b, 0x6a, 0x4f, 0x33, 0x38, 0x4d, 0x68, 0x2b, 0x52, 0x2f, 0x31, 0x32, + 0x6c, 0x55, 0x45, 0x62, 0x7a, 0x48, 0x41, 0x64, 0x51, 0x50, 0x77, 0x57, + 0x0a, 0x6b, 0x66, 0x47, 0x70, 0x77, 0x58, 0x62, 0x52, 0x68, 0x61, 0x43, + 0x56, 0x38, 0x74, 0x74, 0x32, 0x75, 0x49, 0x7a, 0x79, 0x47, 0x47, 0x4b, + 0x66, 0x6e, 0x75, 0x4c, 0x2f, 0x68, 0x44, 0x77, 0x2f, 0x33, 0x48, 0x55, + 0x37, 0x53, 0x57, 0x76, 0x55, 0x32, 0x61, 0x59, 0x58, 0x68, 0x6c, 0x4d, + 0x6d, 0x57, 0x58, 0x67, 0x53, 0x51, 0x4a, 0x61, 0x49, 0x67, 0x71, 0x37, + 0x66, 0x68, 0x43, 0x62, 0x38, 0x72, 0x46, 0x41, 0x6f, 0x77, 0x64, 0x32, + 0x48, 0x6e, 0x76, 0x70, 0x53, 0x0a, 0x32, 0x68, 0x4b, 0x4a, 0x67, 0x30, + 0x6b, 0x57, 0x5a, 0x2f, 0x54, 0x44, 0x4a, 0x55, 0x69, 0x43, 0x5a, 0x4c, + 0x51, 0x62, 0x67, 0x2f, 0x2f, 0x44, 0x44, 0x36, 0x78, 0x62, 0x33, 0x67, + 0x65, 0x41, 0x64, 0x7a, 0x7a, 0x4e, 0x54, 0x68, 0x66, 0x72, 0x58, 0x41, + 0x46, 0x7a, 0x52, 0x73, 0x6a, 0x4f, 0x73, 0x37, 0x71, 0x78, 0x39, 0x59, + 0x37, 0x47, 0x39, 0x34, 0x66, 0x54, 0x6a, 0x6d, 0x34, 0x74, 0x49, 0x4b, + 0x33, 0x61, 0x65, 0x72, 0x32, 0x79, 0x49, 0x72, 0x44, 0x4d, 0x0a, 0x37, + 0x7a, 0x67, 0x52, 0x36, 0x56, 0x49, 0x34, 0x43, 0x56, 0x31, 0x6a, 0x2f, + 0x4e, 0x6e, 0x4f, 0x2f, 0x4d, 0x55, 0x53, 0x67, 0x78, 0x70, 0x4a, 0x74, + 0x62, 0x41, 0x5a, 0x68, 0x67, 0x55, 0x45, 0x37, 0x62, 0x43, 0x4f, 0x35, + 0x49, 0x41, 0x33, 0x39, 0x48, 0x51, 0x34, 0x68, 0x54, 0x37, 0x46, 0x6d, + 0x56, 0x66, 0x74, 0x2b, 0x2b, 0x35, 0x53, 0x4e, 0x57, 0x31, 0x70, 0x5a, + 0x4f, 0x6e, 0x41, 0x2f, 0x6a, 0x57, 0x6a, 0x7a, 0x52, 0x68, 0x4f, 0x35, + 0x4a, 0x54, 0x6b, 0x0a, 0x38, 0x32, 0x62, 0x69, 0x64, 0x6f, 0x6e, 0x77, + 0x36, 0x63, 0x2f, 0x4f, 0x4f, 0x38, 0x50, 0x4e, 0x69, 0x33, 0x6f, 0x64, + 0x4e, 0x70, 0x77, 0x46, 0x75, 0x49, 0x66, 0x53, 0x45, 0x2b, 0x59, 0x54, + 0x37, 0x4e, 0x78, 0x7a, 0x4b, 0x35, 0x41, 0x68, 0x41, 0x79, 0x53, 0x4b, + 0x35, 0x66, 0x6b, 0x77, 0x62, 0x39, 0x6d, 0x68, 0x54, 0x4f, 0x72, 0x5a, + 0x38, 0x70, 0x66, 0x36, 0x4b, 0x77, 0x78, 0x52, 0x30, 0x47, 0x4f, 0x44, + 0x43, 0x56, 0x66, 0x66, 0x53, 0x4b, 0x69, 0x52, 0x0a, 0x67, 0x35, 0x33, + 0x4a, 0x35, 0x4b, 0x6a, 0x75, 0x45, 0x65, 0x30, 0x44, 0x70, 0x4b, 0x74, + 0x46, 0x53, 0x30, 0x57, 0x58, 0x30, 0x4a, 0x77, 0x5a, 0x34, 0x65, 0x39, + 0x79, 0x37, 0x46, 0x62, 0x66, 0x6e, 0x4c, 0x54, 0x4d, 0x74, 0x45, 0x4a, + 0x61, 0x68, 0x63, 0x73, 0x2b, 0x2f, 0x6a, 0x7a, 0x63, 0x76, 0x7a, 0x6e, + 0x7a, 0x32, 0x37, 0x41, 0x51, 0x2b, 0x54, 0x47, 0x6e, 0x46, 0x2f, 0x59, + 0x6a, 0x35, 0x4b, 0x65, 0x76, 0x71, 0x77, 0x33, 0x42, 0x68, 0x52, 0x69, + 0x6a, 0x0a, 0x47, 0x4c, 0x68, 0x62, 0x4a, 0x49, 0x57, 0x30, 0x7a, 0x4d, + 0x71, 0x54, 0x45, 0x47, 0x41, 0x62, 0x6b, 0x70, 0x63, 0x4a, 0x50, 0x4a, + 0x4a, 0x50, 0x4a, 0x79, 0x41, 0x45, 0x48, 0x55, 0x6d, 0x61, 0x4c, 0x50, + 0x4c, 0x78, 0x30, 0x34, 0x6d, 0x57, 0x53, 0x65, 0x42, 0x45, 0x58, 0x43, + 0x45, 0x67, 0x38, 0x4f, 0x78, 0x4a, 0x79, 0x4d, 0x39, 0x37, 0x65, 0x44, + 0x69, 0x76, 0x43, 0x6d, 0x4e, 0x36, 0x6c, 0x33, 0x42, 0x7a, 0x7a, 0x49, + 0x34, 0x51, 0x4f, 0x75, 0x72, 0x37, 0x0a, 0x49, 0x2b, 0x49, 0x42, 0x41, + 0x32, 0x63, 0x46, 0x59, 0x4f, 0x4c, 0x7a, 0x6c, 0x4a, 0x46, 0x74, 0x48, + 0x69, 0x62, 0x51, 0x2f, 0x78, 0x49, 0x68, 0x67, 0x64, 0x62, 0x51, 0x68, + 0x44, 0x77, 0x6f, 0x6d, 0x72, 0x37, 0x63, 0x7a, 0x73, 0x52, 0x63, 0x34, + 0x63, 0x32, 0x65, 0x72, 0x38, 0x34, 0x61, 0x59, 0x47, 0x66, 0x34, 0x76, + 0x37, 0x56, 0x67, 0x62, 0x57, 0x51, 0x71, 0x41, 0x71, 0x48, 0x68, 0x51, + 0x31, 0x49, 0x49, 0x76, 0x39, 0x4d, 0x75, 0x2f, 0x4f, 0x75, 0x61, 0x0a, + 0x44, 0x62, 0x49, 0x78, 0x36, 0x76, 0x54, 0x78, 0x68, 0x6c, 0x78, 0x4b, + 0x44, 0x78, 0x41, 0x70, 0x6e, 0x7a, 0x6b, 0x6c, 0x65, 0x76, 0x6c, 0x48, + 0x70, 0x59, 0x67, 0x37, 0x52, 0x75, 0x6e, 0x6e, 0x66, 0x2f, 0x2b, 0x35, + 0x43, 0x55, 0x31, 0x56, 0x62, 0x34, 0x47, 0x62, 0x36, 0x69, 0x73, 0x51, + 0x79, 0x6d, 0x30, 0x4c, 0x44, 0x74, 0x70, 0x70, 0x61, 0x59, 0x64, 0x52, + 0x41, 0x42, 0x72, 0x53, 0x4e, 0x4b, 0x67, 0x74, 0x6e, 0x38, 0x4d, 0x55, + 0x55, 0x5a, 0x65, 0x5a, 0x0a, 0x6f, 0x31, 0x55, 0x78, 0x41, 0x6f, 0x6c, + 0x76, 0x63, 0x72, 0x55, 0x36, 0x7a, 0x43, 0x33, 0x54, 0x4a, 0x62, 0x4c, + 0x36, 0x38, 0x67, 0x50, 0x4a, 0x54, 0x58, 0x69, 0x4c, 0x37, 0x51, 0x49, + 0x46, 0x58, 0x79, 0x45, 0x58, 0x42, 0x30, 0x48, 0x74, 0x55, 0x32, 0x47, + 0x6b, 0x35, 0x58, 0x79, 0x45, 0x65, 0x50, 0x76, 0x65, 0x33, 0x75, 0x41, + 0x4a, 0x4c, 0x38, 0x76, 0x43, 0x52, 0x39, 0x31, 0x6b, 0x51, 0x57, 0x7a, + 0x6c, 0x4e, 0x62, 0x43, 0x78, 0x46, 0x49, 0x47, 0x46, 0x0a, 0x74, 0x65, + 0x53, 0x68, 0x72, 0x7a, 0x2f, 0x6c, 0x57, 0x6f, 0x56, 0x4f, 0x4f, 0x49, + 0x4d, 0x44, 0x6d, 0x42, 0x75, 0x7a, 0x66, 0x4c, 0x66, 0x34, 0x50, 0x58, + 0x30, 0x6a, 0x39, 0x36, 0x41, 0x69, 0x35, 0x47, 0x6b, 0x33, 0x36, 0x66, + 0x41, 0x5a, 0x37, 0x64, 0x76, 0x44, 0x66, 0x57, 0x57, 0x59, 0x48, 0x65, + 0x67, 0x36, 0x4d, 0x2f, 0x70, 0x50, 0x6c, 0x61, 0x6d, 0x52, 0x41, 0x2f, + 0x31, 0x63, 0x51, 0x58, 0x77, 0x6e, 0x69, 0x2b, 0x50, 0x34, 0x53, 0x43, + 0x75, 0x67, 0x0a, 0x45, 0x32, 0x69, 0x58, 0x58, 0x7a, 0x4f, 0x51, 0x67, + 0x4b, 0x77, 0x5a, 0x61, 0x45, 0x74, 0x46, 0x69, 0x43, 0x4a, 0x56, 0x71, + 0x33, 0x64, 0x73, 0x48, 0x57, 0x45, 0x6a, 0x4d, 0x64, 0x33, 0x58, 0x59, + 0x4e, 0x71, 0x65, 0x55, 0x73, 0x45, 0x70, 0x35, 0x37, 0x33, 0x4c, 0x4e, + 0x75, 0x32, 0x67, 0x67, 0x32, 0x36, 0x38, 0x4b, 0x42, 0x45, 0x3d, 0x0a +}; +unsigned int test_data_enc_len = 6756; + +unsigned cpl = 76; +int main(int argc, char **argv) { + // Test encoding... + printf("Test encoding...\n"); + unsigned len = Base64EncodeSize(test_data_len, cpl); + printf("Predicted size: %u\n", len); + char *data = (char*)malloc(len); + len = Base64Encode(data, (const char*)&test_data[0], test_data_len, cpl); + if (len != test_data_enc_len || memcmp(data, (const char*)&test_data_enc[0], len) != 0) { + printf("input size: %u\n", test_data_len); + printf("output size: %u\n", len); + printf("expected output size: %u\n", test_data_enc_len); + printf("Encoding differs...\n"); + return 1; + } + free(data); + printf("Pass\n"); + + printf("Test decoding...\n"); + len = Base64DecodeSize(test_data_enc_len); + printf("Predicted size: %u\n", len); + data = (char*)malloc(len); + len = Base64Decode(data, (const char*)&test_data_enc[0], test_data_enc_len); + if (len != test_data_len || memcmp(data, (const char*)&test_data[0], len) != 0) { + printf("input size: %u\n", test_data_enc_len); + printf("output size: %u\n", len); + printf("expected size: %u\n", test_data_len); + printf("Decoding differs...\n"); + return 1; + } + free(data); + printf("Pass\n"); + return 0; +} diff --git a/src/hos_libvariant/src/test/test_bundleemitter.cc b/src/hos_libvariant/src/test/test_bundleemitter.cc new file mode 100644 index 00000000..7305e0f2 --- /dev/null +++ b/src/hos_libvariant/src/test/test_bundleemitter.cc @@ -0,0 +1,95 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include "TestAssert.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace libvariant; +using namespace std; + +void TestOne() { + cout << "Testing basic functionality" << endl; + Variant v = Variant::MapType; + v["foo"] = 12.33456; + v["bar"] = 873453; + v["boo"] = false; + v["null"] = Variant::NullType; + v["true"] = true; + v["moo"] = "test one two three blah blah blah"; + v["loo"].Append(1).Append(2).Append(3); + const char payload[] = "fp9q8ywtrvapwn98nc4yargcfuiahwer8ytqv9p4tcp98y3crhlei4t8hpse985ytvlseuhrotceyiruth"; + v["payload.data"] = Blob::CreateReferenced((char*)payload, sizeof(payload)); + std::vector buff; + buff.resize(8192); + unsigned len = SerializeBundle(&buff[0], buff.size(), v); + buff.resize(len); + ASSERT((buff.size() - strlen(&buff[0]) - 1) == sizeof(payload)); + ASSERT(memcmp(payload, &buff[strlen(&buff[0]) + 1], sizeof(payload)) == 0); + fwrite(&buff[0], 1, buff.size(), stdout); + printf("\n"); + Variant val = DeserializeBundle(&buff[0], buff.size()); + ASSERT(val["bar"] == v["bar"]); + ASSERT(val["moo"] == v["moo"]); + ASSERT(val["loo"] == v["loo"]); + ASSERT(val["boo"].AsInt() == 0); // bundles don't preserve boolean type information +} + +void TestErrorPaths() { + cout << "Testing error paths" << endl; + std::ostringstream oss; + Emitter e = BundleHdrEmitter(CreateEmitterOutput(oss.rdbuf())); + + // Test error paths + e.BeginDocument(); + try { + e.BeginDocument(); + abort(); + } catch (const std::runtime_error &) {} + e.BeginMap(); + try { + e.BeginMap(); + abort(); + } catch (const std::runtime_error &) {} + try { + e.BeginList(); + abort(); + } catch (const std::runtime_error &) {} + try { + e.EndList(); + abort(); + } catch (const std::runtime_error &) {} + try { + e.Emit("key").Emit((ConstBlobPtr)Blob::CreateCopy((void*)0,0)); + abort(); + } catch (const std::runtime_error &) {} + e.Emit(true); + e.EndMap(); + try { + e.EndMap(); + abort(); + } catch (const std::runtime_error &) {} + try { + e.Emit("abc"); + abort(); + } catch (const std::runtime_error &) {} + e.EndDocument(); + try { + e.EndDocument(); + abort(); + } catch (const std::runtime_error &) {} +} + +int main(int argc, char **argv) { + TestOne(); + TestErrorPaths(); + return 0; +} diff --git a/src/hos_libvariant/src/test/test_bundlehdr.cc b/src/hos_libvariant/src/test/test_bundlehdr.cc new file mode 100644 index 00000000..35f31363 --- /dev/null +++ b/src/hos_libvariant/src/test/test_bundlehdr.cc @@ -0,0 +1,49 @@ +/** \file + * \author John Bridgman + * \brief + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace libvariant; + +const char example_bundle[] = +"bundle.version: 0.0\n" +"keyone: value\n" +"listkey: value1|value2|value3\n" +"doodle: 1234 # comments!\n" +"foo: 0.234245\n" +"singlelist: blah|\n" +"emptylist: |\n" +"\n\n\n\n\0"; + +const char expected[] = "{ \"keyone\": \"value\"," +"\"listkey\": [ \"value1\", \"value2\", \"value3\" ], \"doodle\": 1234, \"foo\": 0.234245," +"\"singlelist\": [ \"blah\" ], \"emptylist\": [] }"; + +int main(int argc, char **argv) { + std::istringstream iss(std::string(&example_bundle[0], strlen(&example_bundle[0])+1)); + Parser parser = BundleHdrParser(CreateParserInputFile(iss.rdbuf())); + + Variant v = ParseVariant(parser); + Variant ex = DeserializeJSON(expected); + if (v != ex) { + puts(""); + SerializeJSON(stdout, v); + puts(""); + SerializeJSON(stdout, ex); + puts(""); + return 1; + } + Emitter emitter = BundleHdrEmitter(CreateEmitterOutput(stdout)); + emitter << v; + return 0; +} diff --git a/src/hos_libvariant/src/test/test_bundleparser.cc b/src/hos_libvariant/src/test/test_bundleparser.cc new file mode 100644 index 00000000..25ec8e47 --- /dev/null +++ b/src/hos_libvariant/src/test/test_bundleparser.cc @@ -0,0 +1,93 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include "TestAssert.h" +#include +#include +#include +#include +#include + +using namespace libvariant; +using namespace std; + +const char bundle_str[] = +"bundle.version: 0.0\n" +"id: 1\n" +"payload.length: 40\n" +"\0" +"1234567890" +"1234567890" +"1234567890" +"1234567890" +"bundle.version: 0.0\n" +"id: 2 # comments\n" +"payload.length: 40\n" +"#comments\n" +"\0" +"\000\00\00\00" +"\001\00\00\00" +"\002\00\00\00" +"\003\00\00\00" +"\004\00\00\00" +"\005\00\00\00" +"\006\00\00\00" +"\007\00\00\00" +"\010\00\00\00" +"\011\00\00\00" +"bundle.version: 0.0\n" +"id: 3\n" +"payload.length: 70\n" +"erroniouskey\n" +"\n\n\n\n\n" +"\0" +"1234567890" +"blakdsflks" +"sdkjhasdfs" +"347iuhafgj" +"347aguhfdh" +"iouq5478q7" +"8oq34guily" +; + +std::ostream &operator<<(std::ostream &os, Variant v) { +#ifdef ENABLE_YAML + SerializeYAML(os.rdbuf(), v); +#endif + return os; +} + +int main(int argc, char **argv) { + // Need the -1 there because of the \0 at the end of the string (it looks like an empty bundle at the end...) + shared_ptr input = CreateParserInput(&bundle_str[0], sizeof(bundle_str) - 1); + + Variant v = DeserializeWithPayload(input, SERIALIZE_BUNDLEHDR); + cout << v; + cout << endl << "Payload size: " << v["payload.data"].Size() << endl; + ASSERT(v["id"].AsUnsigned() == 1); + ASSERT(v["payload.data"].Size() == 40); + ASSERT(memcmp("1234567890123456789012345678901234567890", v["payload.data"].AsBlob()->GetPtr(0), 40) == 0); + + v = DeserializeWithPayload(input, SERIALIZE_BUNDLEHDR); + cout << v << endl; + ASSERT(v["id"].AsUnsigned() == 2); + ASSERT(v["payload.data"].Size() == 40); + std::vector buf; + for (int i = 0; i < 10; ++i) { buf.push_back(i); } + ASSERT(memcmp(&buf[0], v["payload.data"].AsBlob()->GetPtr(0), 40) == 0); + + v = DeserializeWithPayload(input, SERIALIZE_BUNDLEHDR); + cout << v << endl; + ASSERT(v["payload.data"].Size() == 70); + string orig = "1234567890" "blakdsflks" "sdkjhasdfs" "347iuhafgj" "347aguhfdh" "iouq5478q7" "8oq34guily"; + std::string p((char *)v["payload.data"].AsBlob()->GetPtr(0), 70); + ASSERT(orig == p); + + // Test that the unsafe zero copy does what it is supposed to do + v = DeserializeBundle(&bundle_str[0], sizeof(bundle_str) - 1); + ASSERT(v["payload.data"].AsBlob()->GetPtr(0) != &bundle_str[strlen(&bundle_str[0])+1]); + v = DeserializeBundle(&bundle_str[0], sizeof(bundle_str) - 1, false); + ASSERT(v["payload.data"].AsBlob()->GetPtr(0) == &bundle_str[strlen(&bundle_str[0])+1]); + return 0; +} diff --git a/src/hos_libvariant/src/test/test_empty.cc b/src/hos_libvariant/src/test/test_empty.cc new file mode 100644 index 00000000..ab8a01e4 --- /dev/null +++ b/src/hos_libvariant/src/test/test_empty.cc @@ -0,0 +1,56 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include +#include +#include +using namespace libvariant; +using namespace std; + +int main(int argc, char **argv) { +#ifdef ENABLE_YAML + Emitter emitter = YAMLEmitter(CreateEmitterOutput(std::cout.rdbuf())); +#else + Emitter emitter = JSONEmitter(CreateEmitterOutput(std::cout.rdbuf()), Variant().Set("pretty", true)); +#endif + emitter.BeginList(); + try { + Variant v = DeserializeJSON(""); + emitter << v; + return 1; + } catch (const std::exception &e) { + emitter << "JSON passed"; + } + + try { + Variant v = DeserializeJSON(" "); + emitter << v; + return 1; + } catch (const std::exception &e) { + emitter << "JSON passed"; + } + emitter.Flush(); + +#ifdef ENABLE_YAML + { + Variant v = DeserializeYAML(""); + emitter << v; + emitter.Flush(); + emitter << "YAML passed"; + } +#endif + +#ifdef ENABLE_XML + try { + Variant v = DeserializeXMLPLIST(""); + emitter << v; + return 1; + } catch (const std::exception &e) { + emitter << "XML passed"; + } +#endif + emitter.EndList(); + return 0; +} diff --git a/src/hos_libvariant/src/test/test_extensions.cc b/src/hos_libvariant/src/test/test_extensions.cc new file mode 100644 index 00000000..6752318b --- /dev/null +++ b/src/hos_libvariant/src/test/test_extensions.cc @@ -0,0 +1,678 @@ +//============================================================================= +//! @file VariantExtensions.cc +//! @author Josh Staley staley@arlut.utexas.edu +//! @brief +//============================================================================= + +//=== Includes ================================================================ + +#include +#include +#include + +using namespace std; +using namespace libvariant; + +//=== Function Declarations =================================================== + +bool TestFlattenPath ( bool verbose = false ); +bool TestExpandPath ( bool verbose = false ); +bool TestRDiff ( bool verbose = false ); +bool TestRUpdate ( bool verbose = false ); +bool TestJSONPointer ( bool verbose = false ); +bool TestJSONDiff ( bool verbose = false ); + +//=== Main ==================================================================== + +//----------------------------------------------------------------------------- +int main ( int argc, char * argv [] ) +//----------------------------------------------------------------------------- +{ + //--- Any are will turn verbosity on --- + bool verbose = false; + if ( argc > 1 ) + verbose = true; + + bool testFlattenPath, testExpandPath, testDiff, testRUpdate, testJSONPointer, testJSONDiff; + + try + { + // FlattenPath() + testFlattenPath = TestFlattenPath( verbose ); + if ( testFlattenPath ) + cout << "FlattenPath - PASSED" << endl; + else + cout << "FlattenPath - FAILED" << endl; + + // ExpandPath() + testExpandPath = TestExpandPath( verbose ); + if ( testExpandPath ) + cout << "ExpandPath - PASSED" << endl; + else + cout << "ExpandPath - FAILED" << endl; + + // RDiff() + testDiff = TestRDiff( verbose ); + if ( testDiff ) + cout << "RDiff - PASSED" << endl; + else + cout << "RDiff - FAILED" << endl; + + // RUpdate() + testRUpdate = TestRUpdate( verbose ); + if ( testRUpdate ) + cout << "RUpdate - PASSED" << endl; + else + cout << "RUpdate - FAILED" << endl; + + testJSONPointer = TestJSONPointer( verbose ); + if ( testJSONPointer ) + cout << "JSONPointer - PASSED" << endl; + else + cout << "JSONPointer - FAILED" << endl; + + testJSONDiff = TestJSONDiff( verbose ); + if ( testJSONDiff ) + cout << "JSONDiff - PASSED" << endl; + else + cout << "JSONDiff - FAILED" << endl; + } + catch ( exception & e ) + { + cerr << "# " << e.what() << endl; + return -1; + } + + cout << "Done" << endl; + + bool passed = testFlattenPath && testExpandPath && testDiff && testRUpdate && testJSONPointer && testJSONDiff; + return passed ? 0 : 1; +} + +//=== Functions =============================================================== + +//----------------------------------------------------------------------------- +bool TestFlattenPath ( bool verbose_ ) +//----------------------------------------------------------------------------- +{ + Variant orig, flat, ideal; + + orig = 10; + ideal = 10; + flat = FlattenPath(orig); + if (flat != ideal) { return false; } + + orig = Variant::MapType; + ideal = Variant::MapType; + + orig["1"]["A"] = Variant::NullType; + orig["1"]["B"] = true; + orig["1"]["C"] = 2; + orig["1"]["D"] = -3; + orig["1"]["E"] = 4.0; + orig["1"]["F"] = "five"; + orig["1"]["G"][0] = Variant::NullType; + orig["1"]["G"][1] = true; + orig["1"]["G"][2] = 2; + orig["1"]["G"][3] = -3; + orig["1"]["G"][4] = 4.0; + orig["1"]["G"][5] = "five"; + orig["2"][0] = Variant::NullType; + orig["2"][1] = true; + orig["2"][2] = 2; + orig["2"][3] = -3; + orig["2"][4] = 4.0; + orig["2"][5] = "five"; + orig["2"][6]["a"] = true; + orig["2"][6]["b"] = "test"; + + ideal["1/A"] = Variant::NullType; + ideal["1/B"] = true; + ideal["1/C"] = 2; + ideal["1/D"] = -3; + ideal["1/E"] = 4.0; + ideal["1/F"] = "five"; + ideal["1/G[0]"] = Variant::NullType; + ideal["1/G[1]"] = true; + ideal["1/G[2]"] = 2; + ideal["1/G[3]"] = -3; + ideal["1/G[4]"] = 4.0; + ideal["1/G[5]"] = "five"; + ideal["2[0]"] = Variant::NullType; + ideal["2[1]"] = true; + ideal["2[2]"] = 2; + ideal["2[3]"] = -3; + ideal["2[4]"] = 4.0; + ideal["2[5]"] = "five"; + ideal["2[6]/a"] = true; + ideal["2[6]/b"] = "test"; + + + try { + flat = FlattenPath( orig, 123); + return false; + } catch (const std::exception &) {} + + try + { + flat = FlattenPath( orig ); + } + catch ( exception & e) + { + cout << "# " << e.what() << endl; + return false; + } + + if ( verbose_ ) + { + cout << "--- flat ---" << endl; + SerializeJSON(cout.rdbuf(), flat, true); + cout << endl; + + cout << "--- ideal ---" << endl; + SerializeJSON(cout.rdbuf(), ideal, true); + cout << endl; + } + + return flat == ideal; +} + +//----------------------------------------------------------------------------- +bool TestExpandPath ( bool verbose_ ) +//----------------------------------------------------------------------------- +{ + // TODO - implement tests + return true; +} + +//----------------------------------------------------------------------------- +bool TestRDiff ( bool verbose_ ) +//----------------------------------------------------------------------------- +{ + Variant base, compare, ideal, diff; + + base["1"]["A"] = Variant::NullType; + base["1"]["B"] = true; + base["1"]["C"] = 2; + base["1"]["D"] = -3; + base["1"]["E"] = 4.0; + base["1"]["F"] = "five"; + base["1"]["G"][0] = Variant::NullType; + base["1"]["G"][1] = true; + base["1"]["G"][2] = 2; + base["1"]["G"][3] = -3; + base["1"]["G"][4] = 4.0; + base["1"]["G"][5] = "five"; + base["2"][0] = Variant::NullType; + base["2"][1] = true; + base["2"][2] = 2; + base["2"][3] = -3; + base["2"][4] = 4.0; + base["2"][5] = "five"; + base["2"][6]["a"] = true; + base["2"][6]["b"] = "test"; + base["3"] = 5; + base["5"] = Variant().Set("a", 1).Set("b", 2); + + compare["1"]["B"] = false; + compare["1"]["C"] = -2; + compare["1"]["D"] = 3.0; + compare["1"]["E"] = "four"; + compare["1"]["F"] = 5.0; + compare["1"]["G"][0] = Variant::NullType; + compare["1"]["G"][1] = true; + compare["1"]["G"][2] = 2; + compare["1"]["G"][3] = -3; + compare["1"]["G"][4] = 4.0; + compare["1"]["G"][5] = "five"; + compare["2"][0] = Variant::NullType; + compare["2"][1] = true; + compare["2"][2] = 2; + compare["2"][3] = -3; + compare["2"][4] = 4.0; + compare["2"][5] = "five"; + compare["2"][6]["a"] = false; + compare["2"][6]["b"] = "test"; + compare["3"] = Variant().Set("a", 1); + compare["4"] = Variant().Set("emptymap", Variant::MapType); + compare["5"] = Variant::MapType; + + ideal["1"]["B"] = false; + ideal["1"]["C"] = -2; + ideal["1"]["D"] = 3.0; + ideal["1"]["E"] = "four"; + ideal["1"]["F"] = 5.0; + ideal["2"][0] = Variant::NullType; + ideal["2"][1] = true; + ideal["2"][2] = 2; + ideal["2"][3] = -3; + ideal["2"][4] = 4.0; + ideal["2"][5] = "five"; + ideal["2"][6]["a"] = false; + ideal["2"][6]["b"] = "test"; + ideal["3"] = Variant().Set("a", 1); + ideal["4"] = Variant().Set("emptymap", Variant::MapType); + // ideal["5"] is removed because it's empty + + try + { + diff = RDiff( base, compare ); + } + catch (exception & e) + { + cout << "# " << e.what() << endl; + return false; + } + + if ( verbose_ ) + { + cout << "--- diff ---" << endl; + SerializeJSON(cout.rdbuf(), diff, true); + cout << endl; + + cout << "--- ideal ---" << endl; + SerializeJSON(cout.rdbuf(), ideal, true); + cout << endl; + } + + return diff == ideal; +} + +//----------------------------------------------------------------------------- +bool TestFlattenPathVariantToStringMap ( bool verbose_ ) +//----------------------------------------------------------------------------- +// TODO - Fix this and add to list of tests in main +//----------------------------------------------------------------------------- +{ + Variant orig; + map flatMap, ideal; + + orig["ONE"]["A"] = true; + orig["ONE"]["B"] = 1; + orig["ONE"]["C"] = -2; + orig["ONE"]["D"] = 3; + orig["ONE"]["E"] = "4"; + orig["ONE"]["F"][0] = false; + orig["ONE"]["F"][1] = 1; + orig["ONE"]["F"][2] = -2; + orig["ONE"]["F"][3] = 3; + orig["ONE"]["F"][4] = "4"; + orig["TWO"][0] = true; + orig["TWO"][1] = 1; + orig["TWO"][2] = -2; + orig["TWO"][3] = 3; + orig["TWO"][4] = "4"; + orig["TWO"][5]["a"] = true; + orig["TWO"][5]["b"] = "test"; + + ideal["ONE.A"] = "true"; + ideal["ONE.B"] = "1"; + ideal["ONE.C"] = "-2"; + ideal["ONE.D"] = "3"; + ideal["ONE.E"] = "4"; + ideal["ONE.F"] = "false,1,-2,3,4"; + ideal["TWO.0"] = "true"; + ideal["TWO.1"] = "1"; + ideal["TWO.2"] = "-2"; + ideal["TWO.3"] = "3"; + ideal["TWO.4"] = "4"; + ideal["TWO.5.a"] = "true"; + ideal["TWO.5.b"] = "test"; + + try + { + flatMap = FlattenPathToStrStrMap( orig ); + } + catch (exception& e) + { + cout << "# " << e.what() << endl; + } + + if( verbose_ ) + { + for( map::iterator i(ideal.begin()), e(ideal.end()); i != e; ++i) + { + cout << flatMap[i->first] << " = " << ideal[i->first] << endl; + } + } + + return ideal == flatMap; +} + +//----------------------------------------------------------------------------- +bool TestRUpdate ( bool verbose ) +//----------------------------------------------------------------------------- +{ + Variant base, update, ideal; + + base["1"]["A"] = Variant::NullType; + base["1"]["B"] = true; + base["1"]["C"] = 2; + base["1"]["D"] = -3; + base["1"]["E"] = 4.0; + base["1"]["F"] = "five"; + base["1"]["G"][0] = Variant::NullType; + base["1"]["G"][1] = true; + base["1"]["G"][2] = 2; + base["1"]["G"][3] = -3; + base["1"]["G"][4] = 4.0; + base["1"]["G"][5] = "five"; + base["2"][0] = Variant::NullType; + base["2"][1] = true; + base["2"][2] = 2; + base["2"][3] = -3; + base["2"][4] = 4.0; + base["2"][5] = "five"; + base["2"][6]["a"] = true; + base["2"][6]["b"] = "test"; + base["3"] = 5; + base["5"] = Variant().Set("a", 1).Set("b", 2); + + update["1"]["B"] = false; + update["1"]["C"] = -2; + update["1"]["D"] = 3.0; + update["1"]["E"] = "four"; + update["1"]["F"] = 5.0; + update["2"][0] = Variant::NullType; + update["2"][1] = true; + update["2"][2] = 2; + update["2"][3] = -3; + update["2"][4] = 4.0; + update["2"][5] = "five"; + update["2"][6]["a"] = false; + update["2"][6]["b"] = "test"; + update["3"] = Variant().Set("a", 1); + update["4"] = Variant().Set("emptymap", Variant::MapType); + + ideal["1"]["A"] = Variant::NullType; + ideal["1"]["B"] = false; + ideal["1"]["C"] = -2; + ideal["1"]["D"] = 3.0; + ideal["1"]["E"] = "four"; + ideal["1"]["F"] = 5.0; + ideal["1"]["G"][0] = Variant::NullType; + ideal["1"]["G"][1] = true; + ideal["1"]["G"][2] = 2; + ideal["1"]["G"][3] = -3; + ideal["1"]["G"][4] = 4.0; + ideal["1"]["G"][5] = "five"; + ideal["2"][0] = Variant::NullType; + ideal["2"][1] = true; + ideal["2"][2] = 2; + ideal["2"][3] = -3; + ideal["2"][4] = 4.0; + ideal["2"][5] = "five"; + ideal["2"][6]["a"] = false; + ideal["2"][6]["b"] = "test"; + ideal["3"] = Variant().Set("a", 1); + ideal["4"] = Variant().Set("emptymap", Variant::MapType); + ideal["5"] = Variant().Set("a", 1).Set("b", 2); + + try { + RUpdate(base, update); + } catch (const exception &e) { + cerr << "# " << e.what() << endl; + return false; + } + if ( verbose ) + { + cout << "--- result ---" << endl; + SerializeJSON(cout.rdbuf(), base, true); + cout << endl; + + cout << "--- ideal ---" << endl; + SerializeJSON(cout.rdbuf(), ideal, true); + cout << endl; + } + return base == ideal; +} + + +bool TestJSONPointer(bool verbose) +{ + Variant test_one = DeserializeJSON("{" + "\"foo\": [\"bar\", \"baz\"]," + "\"\": 0," + "\"a/b\": 1," + "\"c%d\": 2," + "\"e^f\": 3," + "\"g|h\": 4," + "\"i\\\\j\": 5," + "\"k\\\"l\": 6," + "\" \": 7," + "\"m~n\": 8" + "}"); + + std::map pointer_path_map; + pointer_path_map[""] = ""; + pointer_path_map["/foo"] = "foo"; + pointer_path_map["/foo/0"] = "/foo[0]"; + pointer_path_map["/"] = "//"; + pointer_path_map["/a~1b"] = "/a\\/b"; + pointer_path_map["/c%d"] = "c%d"; + pointer_path_map["/e^f"] = "e^f"; + pointer_path_map["/g|h"] = "g|h"; + pointer_path_map["/i\\j"] = "i\\\\j"; + pointer_path_map["/k\"l"] = "k\"l"; + pointer_path_map["/ "] = " "; + pointer_path_map["/m~0n"] = "m~n"; + + bool passed = true; + std::map::iterator i, e; + for (i = pointer_path_map.begin(), e = pointer_path_map.end(); i != e; ++i) { + if (verbose) { + cout << "Testing: \"" << i->first << "\" == \"" << i->second << "\""; + } + if (JSONPointerLookup(i->first, test_one) != test_one.GetPath(i->second)) { + passed = false; + if (verbose) { cout << " FAIL!"; } + } + if (verbose) { cout << endl; } + } + return passed; +} + +bool TestJSONDiff(bool verbose) { + +#define PRINT(x) if (verbose) { std::cout << x << std::endl; } else (void)0 + + Variant base = Variant() + .Set("a", Variant().Set("foo", 1)); + Variant expected = base.Copy(); + expected.SetPath("/a/b", 3); + + Variant diff = Variant() + .Set("op", "add") + .Set("path", "/a/b") + .Set("value", 3); + Variant comp = base.Copy(); + PRINT("Testing add /a/b"); + std::pair result = JSONPatch(comp, diff); + if (!result.first) { PRINT("Patch failed: " << result.second); return false; } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + PRINT("Diff: " << SerializeJSON(JSONDiff(base, comp))); + + base = Variant() + .Set("q", Variant().Set("bar", 2)); + comp = base.Copy(); + PRINT("Testing add /q/bar invalid"); + if (JSONPatch(comp, diff).first) { PRINT("Patch suceeded"); return false; } + if (comp != base) { PRINT("Expected: " << SerializeJSON(base) << "\nGot: " << SerializeJSON(comp)); return false; } + + PRINT("Diff: " << SerializeJSON(JSONDiff(base, comp))); + + base = Variant() + .Set("list", Variant().Append(1).Append(2)) + .Set("a", Variant().Set("foo", 1)); + expected = base.Copy() + .Set("list", Variant().Append(1).Append(3).Append(2)); + diff = Variant() + .Set("op", "add") + .Set("path", "/list/1") + .Set("value", 3); + comp = base.Copy(); + PRINT("Testing add list"); + result = JSONPatch(comp, diff); + if (!result.first) { PRINT("Patch failed: " << result.second); return false; } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + PRINT("Diff: " << SerializeJSON(JSONDiff(base, comp))); + + expected = base.Copy(); + expected.At("list").Append(3); + + diff = Variant() + .Set("op", "add") + .Set("path", "/list/-") + .Set("value", 3); + comp = base.Copy(); + PRINT("Testing append list"); + result = JSONPatch(comp, diff); + if (!result.first) { PRINT("Patch failed: " << result.second); return false; } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + PRINT("Diff: " << SerializeJSON(JSONDiff(base, comp))); + + expected = base.Copy(); + base.SetPath("a/bar", 4); + diff = Variant() + .Set("op", "remove") + .Set("path", "/a/bar"); + comp = base.Copy(); + PRINT("Testing remove map"); + result = JSONPatch(comp, diff); + if (!result.first) { PRINT("Patch failed: " << result.second); return false; } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + PRINT("Diff: " << SerializeJSON(JSONDiff(base, comp))); + + diff = Variant() + .Set("op", "remove") + .Set("path", "/a/mar"); + expected = base.Copy(); + comp = base.Copy(); + PRINT("Testing remove not present"); + if (JSONPatch(comp, diff).first) { PRINT("Patch succeeded"); return false; } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + PRINT("Diff: " << SerializeJSON(JSONDiff(base, comp))); + + diff = Variant() + .Set("op", "remove") + .Set("path", "/c/mar"); + comp = base.Copy(); + PRINT("Testing invalid remove"); + if (JSONPatch(comp, diff).first) { PRINT("Patch succeeded"); return false; } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + PRINT("Diff: " << SerializeJSON(JSONDiff(base, comp))); + + diff = Variant() + .Set("op", "replace") + .Set("path", "/list/0") + .Set("value", 42); + comp = base.Copy(); + expected = comp.Copy(); + expected.SetPath("/list[0]", 42); + PRINT("Testing replace list element"); + result = JSONPatch(comp, diff); + if (!result.first) { PRINT("Patch failed: " << result.second); return false; } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + PRINT("Diff: " << SerializeJSON(JSONDiff(base, comp))); + + diff = Variant() + .Set("op", "replace") + .Set("path", "/a/foo") + .Set("value", 42); + comp = base.Copy(); + expected = comp.Copy(); + expected.SetPath("/a/foo", 42); + PRINT("Testing replace map element"); + result = JSONPatch(comp, diff); + if (!result.first) { PRINT("Patch failed: " << result.second); return false; } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + PRINT("Diff: " << SerializeJSON(JSONDiff(base, comp))); + + diff = Variant() + .Set("op", "replace") + .Set("path", "/a/moo") + .Set("value", 42); + comp = base.Copy(); + expected = comp.Copy(); + PRINT("Testing replace not present"); + if (JSONPatch(comp, diff).first) { PRINT("Patch succeeded"); } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + PRINT("Diff: " << SerializeJSON(JSONDiff(base, comp))); + + diff = Variant() + .Set("op", "replace") + .Set("path", "/a/foo") + .Set("value", 42); + comp = base.Copy(); + expected = comp.Copy(); + expected.SetPath("/a/foo", 42); + PRINT("Testing replace map element"); + result = JSONPatch(comp, diff); + if (!result.first) { PRINT("Patch failed: " << result.second); return false; } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + PRINT("Diff: " << SerializeJSON(JSONDiff(base, comp))); + + diff = Variant() + .Set("op", "move") + .Set("path", "/a/moo") + .Set("from", "/a/foo"); + comp = base.Copy(); + expected = comp.Copy(); + expected.SetPath("/a/moo", expected.GetPath("/a/foo")); + expected.ErasePath("/a/foo"); + PRINT("Testing move map element"); + result = JSONPatch(comp, diff); + if (!result.first) { PRINT("Patch failed: " << result.second); return false; } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + PRINT("Diff: " << SerializeJSON(JSONDiff(base, comp))); + + diff = Variant() + .Set("op", "copy") + .Set("path", "/a/moo") + .Set("from", "/a/foo"); + comp = base.Copy(); + expected = comp.Copy(); + expected.SetPath("/a/moo", expected.GetPath("/a/foo")); + PRINT("Testing copy map element"); + result = JSONPatch(comp, diff); + if (!result.first) { PRINT("Patch failed: " << result.second); return false; } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + PRINT("Diff: " << SerializeJSON(JSONDiff(base, comp))); + + diff = Variant() + .Set("op", "test") + .Set("path", "/a/foo") + .Set("value", 1); + comp = base.Copy(); + expected = comp.Copy(); + PRINT("Testing test map element"); + result = JSONPatch(comp, diff); + if (!result.first) { PRINT("Patch failed: " << result.second); return false; } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + diff = Variant() + .Append( Variant().Set("op", "add").Set("path", "/a/foo").Set("value", 2) ) + .Append( Variant().Set("op", "test").Set("path", "/a/foo").Set("value", 1) ) + ; + comp = base.Copy(); + expected = base.Copy(); + PRINT("Testing test map element, failing patch"); + if (JSONPatch(comp, diff).first) { PRINT("Patch succeeded"); } + if (comp != expected) { PRINT("Expected: " << SerializeJSON(expected) << "\nGot: " << SerializeJSON(comp)); return false; } + + return true; +} + +//============================================================================= diff --git a/src/hos_libvariant/src/test/test_guess.cc b/src/hos_libvariant/src/test/test_guess.cc new file mode 100644 index 00000000..2732569e --- /dev/null +++ b/src/hos_libvariant/src/test/test_guess.cc @@ -0,0 +1,48 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include "TestAssert.h" +#include +#include +#include + +using namespace libvariant; +using namespace std; + +int main(int argc, char **argv) { + Variant v = Variant::MapType; + v["key1"] = 1; + v["blah"] = "murmur"; + v["foo"] = 1.2356; + v["bar"] = 49834; + const char *l[] = { "lisp", "erlang", "haskel", "python", "lua", "c", "c++", "java", "c#", "tcl", 0}; + for (const char **c = &l[0]; *c; c += 1) { v["l"].Append(*c); } + Variant v2; +#ifdef ENABLE_YAML + printf("As yaml\n"); + string yaml = SerializeYAML(v); + printf("%s\n", yaml.c_str()); + v2 = DeserializeGuess(yaml); + ASSERT(v2 == v); + + string empty = " #blah\nnull "; + v2 = DeserializeGuess(empty); + ASSERT(v2 == Variant::NullType); +#endif +#ifdef ENABLE_XML + printf("As xml plist\n"); + string xmlplist = SerializeXMLPLIST(v); + printf("%s\n", xmlplist.c_str()); + v2 = DeserializeGuess(xmlplist); + ASSERT(v2 == v); +#endif + printf("As JSON\n"); + string json = SerializeJSON(v); + printf("%s\n", json.c_str()); + v2 = DeserializeGuess(json); + ASSERT(v2 == v); + + return 0; +} diff --git a/src/hos_libvariant/src/test/test_json_parser.cc b/src/hos_libvariant/src/test/test_json_parser.cc new file mode 100644 index 00000000..fbc300e2 --- /dev/null +++ b/src/hos_libvariant/src/test/test_json_parser.cc @@ -0,0 +1,55 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include +#include +#include "TestCommon.h" + +using namespace libvariant; + +static const char *input_document = "\n\n\n\n{\n" +"\"string\": \"value\",\n" +"\"int10\": 1234,\n" +"\"truth\": true,\n" +"\"float\": [ 0.1, 0.12, 1.0e-2 ],\n" +"\"strnum\": \"12345\"\n," +"\"maxuint64\": 18446744073709551615\n" +"}\n"; + +void ExpectedEvents(Emitter e) { + e.BeginDocument(); + e.BeginMap(); + e.Emit("string"), + e.Emit("value"), + e.Emit("int10"), + e.Emit(intmax_t(1234ll)), + e.Emit("truth"), + e.Emit(true), + e.Emit("float"), + e.BeginList(); + e.Emit(0.1), + e.Emit(.12), + e.Emit(1.0e-2), + e.EndList(); + e.Emit("strnum"), + e.Emit("12345"), + e.Emit("maxuint64"), + e.Emit((uintmax_t)std::numeric_limits::max()), + e.EndMap(); + e.EndDocument(); +} + +int main(int argc, char **argv) { + Parser parser = JSONParser(CreateParserInput(input_document)); + shared_ptr expected(new EventBuffer); + ExpectedEvents(Emitter(expected)); + shared_ptr result(new EventBuffer); + + result->Fill(parser); + + if (!ErrorCheckEventBuffer(expected, result)) { + return 1; + } + return 0; +} diff --git a/src/hos_libvariant/src/test/test_loadall.cc b/src/hos_libvariant/src/test/test_loadall.cc new file mode 100644 index 00000000..dece4aef --- /dev/null +++ b/src/hos_libvariant/src/test/test_loadall.cc @@ -0,0 +1,33 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include +#include + +using namespace libvariant; + +const char test_string[] = "---\n" +"key1: value1\n" +"sublist: [ 1,2 ,3, 4]\n" +"...\n" +"---\n" +"second document\n" +"...\n" +"---\n" +"- a\n- b\n- c\n" +"...\n" +"--- last document\n"; + +int main(int argc, char **argv) { + + LoadAllIterator iter = DeserializeYAMLAll(test_string); + LoadAllIterator end; + while (iter != end) { + Variant v = *iter; + SerializeYAML(stdout, v); + ++iter; + } + return 0; +} diff --git a/src/hos_libvariant/src/test/test_memoryoutput.cc b/src/hos_libvariant/src/test/test_memoryoutput.cc new file mode 100644 index 00000000..a418dda8 --- /dev/null +++ b/src/hos_libvariant/src/test/test_memoryoutput.cc @@ -0,0 +1,29 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include +#include +using namespace libvariant; + +int main(int argc, char **argv) { + Variant v; + v["a key"] = "some value"; + v["another key"] = 1234u; + std::vector buffer(8192); + printf("JSON\n"); + unsigned len = SerializeJSON(&buffer[0], buffer.size(), v); + fwrite(&buffer[0], len, 1, stdout); +#ifdef ENABLE_YAML + printf("\nYAML\n"); + len = SerializeYAML(&buffer[0], buffer.size(), v); + fwrite(&buffer[0], len, 1, stdout); +#endif +#ifdef ENABLE_XML + printf("\nPLIST\n"); + len = SerializeXMLPLIST(&buffer[0], buffer.size(), v); + fwrite(&buffer[0], len, 1, stdout); +#endif + return 0; +} diff --git a/src/hos_libvariant/src/test/test_numerics.cc b/src/hos_libvariant/src/test/test_numerics.cc new file mode 100644 index 00000000..b8735059 --- /dev/null +++ b/src/hos_libvariant/src/test/test_numerics.cc @@ -0,0 +1,327 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include "TestAssert.h" +#include +#include +#include +#include +#include +#include +#include +using namespace libvariant; +using namespace std; + +ostream &operator<<(ostream &os, const type_info &t) { + const char *name = t.name(); + int status = -1; + char *dem = 0; + dem = abi::__cxa_demangle(name, 0, 0, &status); + if (status == 0) { + os << dem; + free(dem); + } else { + os << name; + } + return os; +} + +ostream &operator<<(ostream &os, const Variant &v) { + Serialize(os.rdbuf(), v, SERIALIZE_JSON); + return os; +} + +template +void assignCheck(T check) +{ + T a = check; + Variant b = a; + a = variant_cast(b); + if (a != check) { + ostringstream oss; + oss << "Assignment of " << check << " with type " << typeid(T) << " returned " << a; + throw runtime_error(oss.str()); + } + cout << "."; +} + +template +T my_modulus(T r, T l) { return r % l; } +template<> float my_modulus(float r, float l) { return fmod(r, l); } +template<> double my_modulus(double r, double l) { return fmod(r, l); } +template<> long double my_modulus(long double r, long double l) { return fmod(r, l); } + +template +void TestOperations(Variant::Type_t type) { + Variant val = Variant(); + ASSERT(val.IsNull()); + for (T i = 0; i < 1000; i += 10) { + val = Variant(i); + ASSERT(val.As() == i); + ASSERT(val.GetType() == type); + } + + Variant zero = T(0); + Variant one = T(1); + Variant two = T(2); + ASSERT(one + one == two); + ASSERT(one == T(1)); + ASSERT(two == T(2)); + ASSERT(two - one == one); + ASSERT(one == T(1)); + ASSERT(two == T(2)); + ASSERT(one - one == zero); + ASSERT(zero == T(0)); + ASSERT(one == T(1)); + ASSERT(two == T(2)); + ASSERT(zero == zero); + ASSERT(one / two == T(1)/T(2)); + ASSERT(one == T(1)); + ASSERT(two == T(2)); + ASSERT(two * two == T(2) * T(2)); + ASSERT(one == T(1)); + ASSERT(two == T(2)); + ASSERT((two + one) % two == my_modulus((T(2) + T(1)), T(2))); + ASSERT(one == T(1)); + ASSERT(two == T(2)); + // Test doesn't make sense if unsigned + if (!two.IsUnsigned()) { + ASSERT(-two == -T(2)); + } + ASSERT(two == T(2)); + val = two; + ASSERT(one == --val); + ASSERT(one == val); + val = two; + ASSERT(two == val--); + ASSERT(one == val); + val = one; + ASSERT(two == ++val); + ASSERT(two == val); + val = one; + ASSERT(one == val++); + ASSERT(two == val); +} + + +int main(int argc, char **argv) { + assignCheck(true); + assignCheck(false); + // max integer shall be preserved + assignCheck(numeric_limits::max()); + // min integer shall be preserved + assignCheck(numeric_limits::min()); + // max unsigned integer shall be preserved + assignCheck(numeric_limits::max()); + + + // float precision shall be preserved + float ff[] = { __FLT_EPSILON__, __FLT_MIN__, __FLT_MAX__ }; + float f; + for (uint32_t i=0; i(); + if (f!=ff[i]) { + ostringstream oss; + oss << "Float precision test" << v.As() << " != " << ff[i]; + throw runtime_error(oss.str()); + } + } + + // double precision shall be preserved + double dd[] = { __DBL_EPSILON__, __DBL_MIN__, __DBL_MAX__ }; + double d; + for (uint32_t i=0; i() << " != " << dd[i]; + throw runtime_error(oss.str()); + } + } + + // long double precision shall be preserved + long double ldd[] = { __LDBL_EPSILON__, __LDBL_MIN__, __LDBL_MAX__ }; + long double ld; + for (uint32_t i=0; i() << " != " << dd[i]; + throw runtime_error(oss.str()); + } + } + + cout << endl; + cout << "Math tests." << endl; + Variant v = 5; + Variant o = v + 5; + cout << o << endl; + ASSERT(o.AsInt() == 10); + o = v - 2; + cout << o << endl; + ASSERT(o.AsInt() == 3); + o = 7; + o /= 3; + cout << o << endl; + ASSERT(o.AsInt() == 2); + ASSERT(o.IsInt()); + v = 0.1; + cout << o << "/" << v << " = "; + o = o / v; + cout << o << endl; + ASSERT(o.IsFloat()); + o %= 9; + cout << o << endl; + o = 2; + v = o++; + cout << o << " " << v << endl; + ASSERT(v.AsInt() == 2); + ASSERT(o.AsInt() == 3); + --o; + v = o--; + ASSERT(v.AsInt() == 2); + ASSERT(o.AsInt() == 1); + Variant::Type_t extlist[] = { Variant::NullType, Variant::MapType, Variant::ListType, + Variant::StringType, Variant::BlobType, Variant::BoolType }; + + cout << "Verify that numerics throw on non-numeric types." << endl; + for (uint32_t i=0; i(Variant::IntegerType); + TestOperations(Variant::UnsignedType); + TestOperations(Variant::IntegerType); + TestOperations(Variant::UnsignedType); + TestOperations(Variant::IntegerType); + TestOperations(Variant::UnsignedType); + TestOperations(Variant::FloatType); + TestOperations(Variant::FloatType); + TestOperations(Variant::FloatType); + + cout << "Verifying numeric up convert." << endl; + + // T + T == T + { + Variant one(int(1)); + Variant two = one + one; + cout << one.GetType() << " + " << one.GetType() << " = " << two.GetType() << endl; + ASSERT(two == 2); + ASSERT(two.IsInt()); + } + { + Variant one(unsigned(1)); + Variant two = one + one; + cout << one.GetType() << " + " << one.GetType() << " = " << two.GetType() << endl; + ASSERT(two == 2u); + ASSERT(two.IsUnsigned()); + } + { + Variant one(double(1)); + Variant two = one + one; + cout << one.GetType() << " + " << one.GetType() << " = " << two.GetType() << endl; + ASSERT(two == 2.0); + ASSERT(two.IsFloat()); + } + // anything + float == float + { + Variant i_one(int(1)); + Variant f_one(float(1)); + Variant two = i_one + f_one; + cout << i_one.GetType() << " + " << f_one.GetType() << " = " << two.GetType() << endl; + ASSERT(two == 2.0); + ASSERT(two.IsFloat()); + } + { + Variant u_one(unsigned(1)); + Variant f_one(float(1)); + Variant two = u_one + f_one; + cout << u_one.GetType() << " + " << f_one.GetType() << " = " << two.GetType() << endl; + ASSERT(two == 2.0); + ASSERT(two.IsFloat()); + } + + // int + unsigned == unsigned + { + Variant u_one(unsigned(1)); + Variant i_one(int(1)); + Variant two = u_one + i_one; + cout << u_one.GetType() << " + " << i_one.GetType() << " = " << two.GetType() << endl; + ASSERT(two == 2u); + ASSERT(two.IsUnsigned()); + two = i_one + u_one; + cout << i_one.GetType() << " + " << u_one.GetType() << " = " << two.GetType() << endl; + ASSERT(two == 2u); + ASSERT(two.IsUnsigned()); + } + + cout << "PASS" << endl; + return 0; +} diff --git a/src/hos_libvariant/src/test/test_path.cc b/src/hos_libvariant/src/test/test_path.cc new file mode 100644 index 00000000..7893157d --- /dev/null +++ b/src/hos_libvariant/src/test/test_path.cc @@ -0,0 +1,230 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include "TestAssert.h" +#include +#include +#include +#include + +using namespace libvariant; +using namespace std; + +// { +// "key1": [ 1, 2, 3, { "blork": true } ], +// "key2": { +// "subkey": [ "a", { "furple": 1 }, 2 ], +// "sub/key2": true +// } +// } +// +// Then all paths enumerated are: +// Path Value +// "/" Identity +// "/key1" [ 1, 2, 3, { "blork": true } ], +// "/key1[0]" 1 +// "/key1[1]" 2 +// "/key1[2]" 3 +// "/key1[3]" { "blork": true } +// "/key1[3]/blork" true +// "/key2" { "subkey": [ "a", { "furple": 1 }, 2 ], "sub/key2": true } +// "/key2/subkey" [ "a", { "furple": 1 }, 2 ] +// "/key2/subkey[0]" "a" +// "/key2/subkey[1]" { "furple": 1 } +// "/key2/subkey[1]/furple" 1 +// "/key2/subkey[2]" 2 +// "/key2/sub\/key2" true +void TestOne() { + + Variant v = Variant::MapType; + Variant l = Variant::ListType; + l[0] = 1; l[1] = 2; l[2] = 3; + l[3] = Variant::MapType; + l[3]["blork"] = true; + v["key1"] = l; + Variant sub = Variant::MapType; + l = Variant::ListType; + l[0] = "a"; + l[1] = Variant::MapType; + l[1]["furple"] = 1; + l[2] = 2; + sub["subkey"] = l; + sub["sub/key"] = true; + v["key2"] = sub; + + ASSERT(v.GetPath("/") == v); + ASSERT(v.GetPath("") == v); + ASSERT(v.GetPath("/key1") == v["key1"]); + ASSERT(v.GetPath("/key1[0]") == v["key1"][0]); + ASSERT(v.GetPath("/key1[1]") == v["key1"][1]); + ASSERT(v.GetPath("/key1[2]") == v["key1"][2]); + ASSERT(v.GetPath("/key1[3]") == v["key1"][3]); + ASSERT(v.GetPath("/key1[3]/blork") == v["key1"][3]["blork"]); + ASSERT(v.GetPath("/key2") == v["key2"]); + ASSERT(v.GetPath("/key2/subkey") == v["key2"]["subkey"]); + ASSERT(v.GetPath("/key2/subkey[0]") == v["key2"]["subkey"][0]); + ASSERT(v.GetPath("/key2/subkey[1]") == v["key2"]["subkey"][1]); + ASSERT(v.GetPath("/key2/subkey[1]/furple") == v["key2"]["subkey"][1]["furple"]); + ASSERT(v.GetPath("/key2/subkey[2]") == v["key2"]["subkey"][2]); + ASSERT(v.GetPath("/key2/sub\\/key") == v["key2"]["sub/key"]); + + ASSERT(v.GetPath("/key1/") == v["key1"]); + ASSERT(v.GetPath("/key1[0]/") == v["key1"][0]); + ASSERT(v.GetPath("/key1[1]/") == v["key1"][1]); + ASSERT(v.GetPath("/key1[2]/") == v["key1"][2]); + ASSERT(v.GetPath("/key1[3]/") == v["key1"][3]); + ASSERT(v.GetPath("/key1[3]/blork/") == v["key1"][3]["blork"]); + ASSERT(v.GetPath("/key2/") == v["key2"]); + ASSERT(v.GetPath("/key2/subkey/") == v["key2"]["subkey"]); + ASSERT(v.GetPath("/key2/subkey[0]/") == v["key2"]["subkey"][0]); + ASSERT(v.GetPath("/key2/subkey[1]/") == v["key2"]["subkey"][1]); + ASSERT(v.GetPath("/key2/subkey[1]/furple/") == v["key2"]["subkey"][1]["furple"]); + ASSERT(v.GetPath("/key2/subkey[2]/") == v["key2"]["subkey"][2]); + ASSERT(v.GetPath("/key2/sub\\/key/") == v["key2"]["sub/key"]); + + ASSERT(!v.HasPath("/nothing")); + + ASSERT(v.GetPath("key1/") == v["key1"]); + ASSERT(v.GetPath("key1[0]/") == v["key1"][0]); + ASSERT(v.GetPath("key1[1]/") == v["key1"][1]); + ASSERT(v.GetPath("key1[2]/") == v["key1"][2]); + ASSERT(v.GetPath("key1[3]/") == v["key1"][3]); + ASSERT(v.GetPath("key1[3]/blork/") == v["key1"][3]["blork"]); + ASSERT(v.GetPath("key2/") == v["key2"]); + ASSERT(v.GetPath("key2/subkey/") == v["key2"]["subkey"]); + ASSERT(v.GetPath("key2/subkey[0]/") == v["key2"]["subkey"][0]); + ASSERT(v.GetPath("key2/subkey[1]/") == v["key2"]["subkey"][1]); + ASSERT(v.GetPath("key2/subkey[1]/furple/") == v["key2"]["subkey"][1]["furple"]); + ASSERT(v.GetPath("key2/subkey[2]/") == v["key2"]["subkey"][2]); + ASSERT(v.GetPath("key2/sub\\/key/") == v["key2"]["sub/key"]); + + + ASSERT(v.AtPath("key1/") == v["key1"]); + ASSERT(v.AtPath("key1[0]/") == v["key1"][0]); + ASSERT(v.AtPath("key1[1]/") == v["key1"][1]); + ASSERT(v.AtPath("key1[2]/") == v["key1"][2]); + ASSERT(v.AtPath("key1[3]/") == v["key1"][3]); + ASSERT(v.AtPath("key1[3]/blork/") == v["key1"][3]["blork"]); + ASSERT(v.AtPath("key2/") == v["key2"]); + ASSERT(v.AtPath("key2/subkey/") == v["key2"]["subkey"]); + ASSERT(v.AtPath("key2/subkey[0]/") == v["key2"]["subkey"][0]); + ASSERT(v.AtPath("key2/subkey[1]/") == v["key2"]["subkey"][1]); + ASSERT(v.AtPath("key2/subkey[1]/furple/") == v["key2"]["subkey"][1]["furple"]); + ASSERT(v.AtPath("key2/subkey[2]/") == v["key2"]["subkey"][2]); + ASSERT(v.AtPath("key2/sub\\/key/") == v["key2"]["sub/key"]); + + Variant o; + o["foo"] = v; + VariantRef p = o["foo"]; + ASSERT(p.AtPath("key1/") == v["key1"]); + ASSERT(p.GetPath("key1/") == v["key1"]); + ASSERT(!p.HasPath("/nothing")); + + try { + Variant v2; + v2 = v.AtPath("/nothing"); + VariantPrint(v2); + VariantPrint(v); + abort(); + } catch (const std::runtime_error &) {} + + try { + Variant v2 = v.AtPath("/nothing"); + VariantPrint(v2); + VariantPrint(v); + abort(); + } catch (const std::runtime_error &) {} + + try { + Variant v2 = v.AtPath("/key1/nothing"); + VariantPrint(v2); + abort(); + } catch (const std::runtime_error &) {} + + Variant v2; + v2.AtPath("abc/rxy") = 123; + VariantPrint(v2); + + Variant s; + s.SetPath("/key1[0]", 1) + .SetPath("/key1[1]", 2) + .SetPath("/key1[2]", 3) + .SetPath("/key1[3]/blork", true) + .SetPath("/key2/subkey[0]", "a") + .SetPath("/key2/subkey[1]/furple", 1) + .SetPath("/key2/subkey[2]", 2) + .SetPath("/key2/sub\\/key", true); + ASSERT(v == s); + + s.SetPath("/a/b/c", true); + ASSERT(s["a"]["b"]["c"].IsTrue()); + s.SetPath("/a/b/c", false); + ASSERT(s["a"]["b"]["c"].IsFalse()); + s.SetPath("/a/c[0]", 1); + ASSERT(s["a"]["c"][0].AsInt() == 1); + try { + s.SetPath("/a/c/c", 123); + abort(); + } catch (const std::runtime_error &) {} + try { + s.SetPath("/a/b/d[abc]", 1); + abort(); + } catch (const std::runtime_error &) {} +} + +void TestTwo() { + Variant l = Variant::ListType; + l.Append("a"); + l.Append("b"); + l.Append(Variant::MapType); + l[2]["a"] = 1; + l[2]["b"] = Variant::MapType; + l[2]["b"]["c"] = 3u; + ASSERT(l.GetPath("[0]") == "a"); + ASSERT(l.GetPath("[1]") == "b"); + ASSERT(l.GetPath("[2]/a") == 1); + ASSERT(l.GetPath("[2]/b/c") == 3u); + ASSERT(l.GetPath("[2]/b/c").IsUnsigned()); + ASSERT(l.GetPath("[3]/a", 4) == 4); + ASSERT(l.Contains(3) == false); + + Variant s; + s.SetPath("[0]", "a") + .SetPath("[1]", "b") + .SetPath("[2]/a", 1) + .SetPath("[2]/b/c", 3u); + ASSERT(l == s); + s.SetPath("[3]/a/b/c", 123); + ASSERT(s[3]["a"]["b"]["c"].AsInt() == 123); + try { + s.SetPath("/a/b/c", 123); + ASSERT(false); + } catch (const std::runtime_error &) {} + try { + s.GetPath("[a]"); + ASSERT(false); + } catch (const std::runtime_error &) {} +} + +int main(int argc, char **argv) { + TestOne(); + TestTwo(); + + Variant v; + Variant b = v.AtPath("abc/123", Variant::MapType); + ASSERT(b.IsMap()); + b["def"] = 123; + ASSERT(v["abc"].AtPath("123/def") == 123); + ASSERT(v["abc"].At("456", "foo") == "foo"); + ASSERT(v["abc"]["456"] == "foo"); + ASSERT(v["abc"].AtPath("123/rst", "abc") == "abc"); + ASSERT(b["rst"] == "abc"); + b = v.At("list", Variant::ListType); + ASSERT(b.IsList()); + ASSERT(v.AtPath("list[1]", "123") == "123"); + ASSERT(v.AtPath("list[0]/abc", "abc") == "abc"); + VariantPrint(v); + return 0; +} diff --git a/src/hos_libvariant/src/test/test_payload.cc b/src/hos_libvariant/src/test/test_payload.cc new file mode 100644 index 00000000..2a6ca825 --- /dev/null +++ b/src/hos_libvariant/src/test/test_payload.cc @@ -0,0 +1,121 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include "TestAssert.h" +#include +#include +#include +#include +#include + +using namespace libvariant; +using namespace std; + +#define TESTPAYLOAD \ +"1234567890"\ +"1234567890"\ +"1234567890"\ +"1234567890"\ +"1234567890"\ +"1234567890"\ +"1234567890"\ +"1234567890"\ +"1234567890"\ +"1234567890" + +#define TESTPAYLOAD_LEN 100 +#define TESTPAYLOAD_LEN_STR "100" + +const char test_input[] = +"{\"payload\": { \"length\": " TESTPAYLOAD_LEN_STR " }, \"abc\": 123 }" +"\n\n\n\n\n" +"\0" +TESTPAYLOAD + +"{\"payload\": { \"length\": " TESTPAYLOAD_LEN_STR ", \"data\": null }, \"abc\": 123 }" +"\n\n\n\n\n" +"\n\n\n\n\n" +"\0" +TESTPAYLOAD +"{ \"abc\": 123 }" +"\0" +"{ \"payload\": { \"length\": " TESTPAYLOAD_LEN_STR "} }" +"\n\n\n\n\n" +"\n\n\n\n\n" +"\n\n\n\n\n" +"\0" +TESTPAYLOAD +"{ \"payload\": { \"length\": 0 } }" +; + +void TestParse() { + shared_ptr input(CreateParserInput(&test_input[0], sizeof(test_input) - 1)); + const char *datapath = "/payload/data"; + const char *lenpath = "/payload/length"; + Variant params = Variant().Set("length_path", lenpath).Set("data_path", datapath); + + Variant v = DeserializeWithPayload(input, SERIALIZE_JSON, params); + ASSERT(v.GetPath(lenpath) == 100); + ASSERT(v.GetPath("abc") == 123); + BlobPtr b = v.GetPath(datapath).AsBlob(); + ASSERT(b->GetNumBuffers() == 1); + ASSERT(memcmp(b->GetPtr(0), TESTPAYLOAD, TESTPAYLOAD_LEN) == 0); + + v = DeserializeWithPayload(input, SERIALIZE_JSON, params); + ASSERT(v.GetPath(lenpath) == 100); + ASSERT(v.GetPath("abc") == 123); + b = v.GetPath(datapath).AsBlob(); + ASSERT(b->GetNumBuffers() == 1); + ASSERT(memcmp(b->GetPtr(0), TESTPAYLOAD, TESTPAYLOAD_LEN) == 0); + + v = DeserializeWithPayload(input, SERIALIZE_JSON, params); + ASSERT(v.HasPath(datapath) == false); + ASSERT(v.GetPath("abc") == 123); + ASSERT(v.HasPath(lenpath) == false); + + v = DeserializeWithPayload(input, SERIALIZE_JSON, Variant(params.Copy()).Set("data_path", "other/data")); + ASSERT(v.GetPath(lenpath) == 100); + b = v.GetPath("other/data").AsBlob(); + ASSERT(b->GetNumBuffers() == 1); + ASSERT(memcmp(b->GetPtr(0), TESTPAYLOAD, TESTPAYLOAD_LEN) == 0); + + v = DeserializeWithPayload(input, SERIALIZE_JSON, params); + ASSERT(v.GetPath(lenpath) == 0); + ASSERT(v.HasPath(datapath) == false); +} + +void TestEmit() { + + Variant params; + params.Set("length_path", "payload/length").Set("data_path", "other/data"); + Variant v; + BlobPtr b = Blob::CreateCopy(TESTPAYLOAD, TESTPAYLOAD_LEN); + v.SetPath("other/data", b); + SerializeWithPayload(cout.rdbuf(), v, SERIALIZE_JSON, params); + cout << "\n--------------------------------------------------------------------------------\n"; + params.Set("ignore_payload", true); + SerializeWithPayload(cout.rdbuf(), v, SERIALIZE_JSON, params); + cout << "\n--------------------------------------------------------------------------------\n"; + params.Set("ignore_payload", false); + params.Set("payload_length", 5); + SerializeWithPayload(cout.rdbuf(), v, SERIALIZE_JSON, params); + cout << "\n--------------------------------------------------------------------------------\n"; + params.Set("ignore_payload", true); + params.Set("payload_length", 5); + SerializeWithPayload(cout.rdbuf(), v, SERIALIZE_JSON, params); + cout << "\n\n"; +} + +int main(int argc, char **argv) { +try{ + TestParse(); + TestEmit(); + cout << endl; +} catch (const std::exception &e) { + cerr << e.what() << endl; + exit(1); +} + return 0; +} diff --git a/src/hos_libvariant/src/test/test_roundtrip.cc b/src/hos_libvariant/src/test/test_roundtrip.cc new file mode 100644 index 00000000..cc6667d2 --- /dev/null +++ b/src/hos_libvariant/src/test/test_roundtrip.cc @@ -0,0 +1,90 @@ +#include +#include +#include +using namespace libvariant; +using namespace std; + +#include + +int DoTest(SerializeType stype) { + Variant v1; + v1["bool_true"] = true; + v1["bool_false"] = false; + v1["long_double_max"] = numeric_limits::max(); + v1["long_double_min"] = numeric_limits::min(); + v1["double_max"] = numeric_limits::max(); + v1["double_min"] = numeric_limits::min(); + v1["int_max"] = numeric_limits::max(); + v1["int_min"] = numeric_limits::min(); + v1["uint_max"] = numeric_limits::max(); + v1["uint_min"] = numeric_limits::min(); + + string s = Serialize(v1, stype); + Variant v2 = Deserialize(s, stype); + + int result = 0; + + if (variant_cast(v2["bool_true"]) != true) { + cerr << "bool true failed" << endl; + result++; + } + if (variant_cast(v2["bool_false"]) != false) { + cerr << "bool false failed" << endl; + result++; + } + +#if 0 + // long double doesn't roundtrip! + + if (variant_cast(v2["long_double_max"]) != numeric_limits::max()) { + cerr << "long double max failed" << endl; + result++; + } + if (variant_cast(v2["long_double_min"]) != numeric_limits::min()) { + cerr << "long double min failed" << endl; + result++; + } +#endif + + if (variant_cast(v2["double_max"]) != numeric_limits::max()) { + cerr << "double max failed" << endl; + result++; + } + if (variant_cast(v2["double_min"]) != numeric_limits::min()) { + cerr << "double min failed" << endl; + result++; + } + + if (variant_cast(v2["int_max"]) != numeric_limits::max()) { + cerr << "intmax_t max failed" << endl; + result++; + } + if (variant_cast(v2["int_min"]) != numeric_limits::min()) { + cerr << "intmax_t min failed" << endl; + result++; + } + + if (variant_cast(v2["uint_max"]) != numeric_limits::max()) { + cerr << "uintmax_t max failed" << endl; + result++; + } + if (variant_cast(v2["uint_min"]) != numeric_limits::min()) { + cerr << "uintmax_t min failed" << endl; + result++; + } + + return result; +} + +int main(int argv, char** argc) { + int result = 0; + result += DoTest(SERIALIZE_JSON); +#if ENABLE_YAML + result += DoTest(SERIALIZE_YAML); +#endif +#if ENABLE_XML + result += DoTest(SERIALIZE_XMLPLIST); +#endif + result += DoTest(SERIALIZE_BUNDLEHDR); + return result; +} diff --git a/src/hos_libvariant/src/test/test_schema.cc b/src/hos_libvariant/src/test/test_schema.cc new file mode 100644 index 00000000..8285e452 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema.cc @@ -0,0 +1,410 @@ +/** \file + * \author John Bridgman + * \brief + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace libvariant; +using namespace std; + +int TestNormalise() { + int ret = 0; + cout << "Test Normalise\n"; + + cout << "normalise - untouched immediate $ref "; + Variant schema; + schema["items"]["$ref"] = "#"; + SchemaLoader::NormSchema(schema, ""); + if (schema["items"]["$ref"] == "#") { + cout << "PASS" << endl; + } else { + cout << "!!! FAIL !!!" << endl; + ++ret; + abort(); + } + + cout << "normalise - id as base "; + schema = Variant::NullType; + schema["id"] = "baseUrl"; + schema["items"]["$ref"] = "#"; + SchemaLoader::NormSchema(schema, ""); + if (schema["items"]["$ref"] == "baseUrl#") { + cout << "PASS" << endl; + } else { + cout << "!!! FAIL !!!" << endl; + ++ret; + abort(); + } + + cout << "normalise - id relative to parent "; + schema = Variant::NullType; + schema["id"] = "http://example.com/schema"; + schema["items"]["id"] = "otherSchema"; + schema["items"]["items"]["$ref"] = "#"; + SchemaLoader::NormSchema(schema, ""); + if (schema["items"]["id"] == "http://example.com/otherSchema" + && schema["items"]["items"]["$ref"] == "http://example.com/otherSchema#" + ) { + cout << "PASS" << endl; + } else { + cout << "!!! FAIL !!!" << endl; + ++ret; + abort(); + } + + cout << "normalise - do not touch contents of \"enum\" "; + + schema = Variant::NullType; + schema["id"] = "http://example.com/schema"; + schema["items"]["id"] = "otherSchema"; + schema["items"]["enum"][0]["$ref"] = "#"; + SchemaLoader::NormSchema(schema, ""); + + if (schema["items"]["enum"][0]["$ref"] == "#") { + cout << "PASS" << endl; + } else { + cout << "!!! FAIL !!!" << endl; + ++ret; + abort(); + } + + cout << "Only normalise id and $ref if they are strings "; + schema = Variant::NullType; + schema["properties"]["id"]["type"] = "integer"; + schema["properties"]["$ref"]["type"] = "integer"; + Variant data; + data["id"] = "test"; + data["$ref"] = "test"; + SchemaLoader::NormSchema(schema, ""); + if (!SchemaValidate(schema, data).Error()) { + cout << " !!! FAIL !!! " << endl; + ++ret; + abort(); + } else { + cout << " PASS " << endl; + } + + return ret; +} + +bool TestMissingHandler(SchemaLoader *sb, const std::string &uri, SchemaLoader::LoaderError &error, void *m) { + vector &missing = *(vector*)(m); + cout << endl; + cout << "Validator missing schema: \"" << uri << "\"" << endl; + missing.push_back(uri); + return true; +} + +int TestFile(const std::string &testfile) { + int ret = 0; + cout << "Processing file " << testfile << endl; + cout << "-------------------------------------\n"; + cout.flush(); + Variant tests = DeserializeJSONFile(testfile.c_str()); + for (Variant::ListIterator i(tests.ListBegin()), e(tests.ListEnd()); i != e; ++i) { + std::string name = i->At("name").AsString(); + Variant data = i->At("data"); + Variant schema = i->At("schema"); + bool fail = i->Get("fail", false).AsBool(); + bool exception = i->Get("exception", false).AsBool(); + cout << "Running " << (fail ? "negative " : "") << "test \"" << name << "\" "; + cout.flush(); + SchemaLoader loader; + std::vector missing; + loader.SetMissingHandler(&TestMissingHandler, &missing); + SchemaResult result; + try { + result = SchemaValidate(schema, data, &loader); + } catch (const std::exception &e) { + if (exception) { + cout << " PASS with exception\n"; + cout << e.what() << endl; + continue; + } + cout << "\n!!!!FAIL!!!!\n"; + cout << e.what() << endl; + ++ret; + abort(); + } + if (exception) { + cout << "\n!!!!FAIL!!!!\n"; + cout << "Excepted SchemaValidate to throw!\n"; + ++ret; + abort(); + } + + for (unsigned k = 0; k < missing.size(); ++k) { + bool found = false; + Variant m = i->Get("missing", Variant::ListType); + for (Variant::ListIterator j(m.ListBegin()), e(m.ListEnd()); j != e && !found; ++j) { + if (*j == missing[k]) { + found = true; + } + } + if (!found) { + cout << "\n!!!!FAIL!!!!\n"; + cout << "Unexpected missing schema: \"" << missing[k] << "\"\n"; + ++ret; + abort(); + } + } + + if (fail && !result.Error()) { + cout << "\n!!!!!FAIL!!!!!\n"; + cout << result; + ++ret; + abort(); + } else if (!fail && result.Error()) { + cout << "\n!!!!!FAIL!!!!!\n"; + cout << result; + ++ret; + abort(); + } else { + cout << " PASS"; + if (result.Error()) { + cout << endl << result; + } + } + cout << endl; + } + cout << endl; + return ret; +} + +int TestDirectory(const std::string &dirname) { + int ret = 0; + DIR *dir = opendir(dirname.c_str()); + if (!dir) { return 1; } + cout << "\nProcessing " << dirname << " for tests." << endl; + cout << "=========================================\n"; + dirent *ep; + while ((ep = readdir(dir))) { + string fname = ep->d_name; + if (fname == ".") continue; + if (fname == "..") continue; + if (ep->d_type == DT_REG) { + if (fname.find(".") < fname.size() && fname.substr(fname.rfind(".")) == ".test") { + ret += TestFile(dirname + "/" + fname); + } + } + if (ep->d_type == DT_DIR) { + ret += TestDirectory(dirname + "/" + fname); + } + } + cout << endl; + closedir(dir); + return ret; +} + +int TestSchemaLoader() { + cout << "Test advanced schema loader\n"; + int ret = 0; + Variant data = DeserializeGuessFile(TEST_SCHEMA_DATA "/simple-test.json"); + Variant faildata = DeserializeGuessFile(TEST_SCHEMA_DATA "/simple-test-fail.json"); + try { + AdvSchemaLoader loader; + SchemaResult result = SchemaValidate("simple-test-schema.json", data, &loader); + cout << "Look up of schema without path succeeded."; + abort(); + ++ret; + } catch (const std::exception &e) {} + cout << endl; + + { + AdvSchemaLoader loader; + cout << "Testing absolute path.\n"; + SchemaResult result = SchemaValidate(TEST_SCHEMA_DATA "/simple-test-schema.json", data, &loader); + SchemaResult failresult = SchemaValidate(TEST_SCHEMA_DATA "/simple-test-schema.json", faildata, &loader); + if (result.Error()) { + cout << result << endl; + ++ret; + } + if (!failresult.Error()) { + cout << "!!! Negative test failed\n"; + ++ret; + } else { + //cout << failresult << endl; + } + } + cout << endl; + + { + AdvSchemaLoader loader; + cout << "Testing advanced schema loader, loading a file through the path.\n"; + loader.AddPath(TEST_SCHEMA_DATA); + SchemaResult result = SchemaValidate("simple-test-schema.json", data, &loader); + SchemaResult failresult = SchemaValidate("simple-test-schema.json", faildata, &loader); + if (result.Error()) { + cout << result << endl; + ++ret; + } + if (!failresult.Error()) { + cout << "!!! Negative test failed\n"; + ++ret; + } else { + //cout << failresult << endl; + } + } + cout << endl; + + { + AdvSchemaLoader loader; + cout << "Testing file:// absolute path\n"; + SchemaResult result = SchemaValidate("file://" TEST_SCHEMA_DATA "/simple-test-schema.json", data, &loader); + SchemaResult failresult = SchemaValidate("file://" TEST_SCHEMA_DATA "/simple-test-schema.json", faildata, &loader); + if (result.Error()) { + cout << result << endl; + ++ret; + } + if (!failresult.Error()) { + cout << "!!! Negative test failed\n"; + ++ret; + abort(); + } else { + //cout << failresult << endl; + } + } + cout << endl; + + { + AdvSchemaLoader loader; + cout << "Testing file:// relative path\n"; + loader.AddPath(TEST_SCHEMA_DATA); + SchemaResult result = SchemaValidate("file://" "simple-test-schema.json", data, &loader); + SchemaResult failresult = SchemaValidate("file://" "simple-test-schema.json", faildata, &loader); + if (result.Error()) { + cout << result << endl; + ++ret; + } + if (!failresult.Error()) { + cout << "!!! Negative test failed\n"; + ++ret; + abort(); + } else { + //cout << failresult << endl; + } + } + cout << endl; + + try { + AdvSchemaLoader loader; + loader.AddPath(TEST_SCHEMA_DATA); + cout << "Test that missing schema works right...\n"; + SchemaResult result = SchemaValidate("abc-no-such-schema", data, &loader); + cout << "Failed!\n"; + ++ret; + } catch (const std::exception &e) { + cout << "Error:\n" << e.what() << endl; + } + + return ret; +} + +int TestSchemaDefaults() { + cerr << "Testing schema defaults\n"; + int ret = 0; + Variant schema; + schema.SetPath("properties/foo/default", 123) + .SetPath("properties/bar/default", "abc") + .SetPath("default/foo", 456) + .SetPath("default/bar", "def") + .SetPath("properties/list/items/default", false) + .SetPath("definitions/zero/default", 0) + .SetPath("properties/zero/$ref", "#/definitions/zero"); + + + Variant data; + AddSchemaDefaults(schema, data); + if ((data["foo"] != 456 || data["bar"] != "def") && !data.Contains("list")) { + cerr << "Defaults test failed:\n" + "Got: \n"; + Serialize(cerr.rdbuf(), data, SERIALIZE_JSON); + ++ret; + } + data.Erase("foo"); + AddSchemaDefaults(schema, data); + if (data["foo"] != 123 || !data["list"][0].IsFalse() || data["zero"] != 0) { + cerr << "Defaults test failed:\n" + "Got: \n"; + Serialize(cerr.rdbuf(), data, SERIALIZE_JSON); + ++ret; + } + schema.SetPath("properties/alltest/allOf[0]/default", "test"); + AddSchemaDefaults(schema, data); + if (data["alltest"] != "test") { + cerr << "Defaults test failed:\n" + "Got: \n"; + Serialize(cerr.rdbuf(), data, SERIALIZE_JSON); + ++ret; + } + return ret; +} + +int main(int argc, char **argv) { + while (true) { + int c = getopt(argc, argv, "f:"); + if (c == -1) { break; } + switch (c) { + case 'f': + return TestFile(optarg); + default: + break; + } + + } + int i = 0; + int ret = 0; + cout << "Testing SchemaLoader::ResolveURI "; + std::string ruri_file = TEST_SCHEMA_DATA; + ruri_file += "/test_resolveuri.json"; + Variant v = DeserializeJSONFile(ruri_file.c_str()); + while (true) { + std::string ref, base, expected; + ref = v[3*i].AsString(); + base = v[3*i+1].AsString(); + expected = v[3*i+2].AsString(); + if (ref == "" && base == "" && expected == "") { break; } + string res = SchemaLoader::ResolveURI(base, ref); + if (res != expected) { + cout << "\nResolveURI test " << i << " failed\n" + << "ref: \"" << ref << "\"\n" + << "base: \"" << base << "\"\n" + << "result: \"" << res << "\"\n" + << "expected: \"" << expected << "\"" + << endl; + ++ret; + abort(); + } else if (i%5 == 0) { + cout << "."; + cout.flush(); + } + ++i; + } + cout << endl; + + ret += TestNormalise(); + + cout << "Performing schema validation tests" << endl; + ret += TestDirectory(TEST_SCHEMA_DATA); + + ret += TestSchemaLoader(); + + ret += TestSchemaDefaults(); + + cerr << "================================================================================\n"; + if (ret > 0) { + cerr << "FAIL!\n"; + } else { + cerr << "All tests PASS\n"; + } + return ret == 0 ? 0 : 1; +} diff --git a/src/hos_libvariant/src/test/test_schema_data/invalid-schema.test b/src/hos_libvariant/src/test/test_schema_data/invalid-schema.test new file mode 100644 index 00000000..ad8b3443 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/invalid-schema.test @@ -0,0 +1,168 @@ +[ + { + "name": "Invalid anyOf", + "schema": { + "anyOf": { "type": "integer" } + }, + "data": 1234, + "fail": true + }, + { + "name": "Invalid allOf", + "schema": { + "allOf": { "type": "integer" } + }, + "data": 1234, + "fail": true + }, + { + "name": "Invalid oneOf", + "schema": { + "oneOf": { "type": "integer" } + }, + "data": 1234, + "fail": true + }, + { + "name": "Invalid dependencies 1", + "schema": { + "dependencies": 123 + }, + "data": { "a": 1, "b": 2 }, + "fail": true + }, + { + "name": "Invalid dependencies 1", + "schema": { + "dependencies": { "a": 123 } + }, + "data": { "a": 1, "b": 2 }, + "fail": true + }, + { + "name": "Invalid pattern property regex", + "schema": { + "patternProperties": { + "[": {} + } + }, + "data": { + "abc": 123 + }, + "fail": true + }, + { + "name": "Invalid pattern property not an object", + "schema": { + "patternProperties": 123 + }, + "data": { + "abc": 123 + }, + "fail": true + }, + { + "name": "Inavlid properties, not an object", + "schema": { + "properties": 123 + }, + "data": { "abc": 123 }, + "fail": true + }, + { + "name": "uniqueItems not a bool", + "schema": { + "uniqueItems": 123 + }, + "data": [ 1,2,3 ], + "fail": true + }, + { + "name": "minItems not a number", + "schema": { + "minItems": "abc" + }, + "data": [ 1,2,3 ], + "fail": true + }, + { + "name": "maxItems not a number", + "schema": { + "maxItems": "abc" + }, + "data": [ 1,2,3 ], + "fail": true + }, + { + "name": "string pattern not a string", + "schema": { + "pattern": 123 + }, + "data": "abc", + "fail": true + }, + { + "name": "string pattern invalid regex", + "schema": { + "pattern": "[" + }, + "data": "abc", + "fail": true + }, + { + "name": "required keys not a list", + "schema": { + "required": "abc" + }, + "data": { "a": 1, "b": 2 }, + "fail": true + }, + { + "name": "minProperties not a number", + "schema": { + "minProperties": "abc" + }, + "data": { "a": 1, "b": 2 }, + "fail": true + }, + { + "name": "maxProperties not a number", + "schema": { + "maxProperties": "abc" + }, + "data": { "a": 1, "b": 2 }, + "fail": true + }, + { + "name": "minLength not a number", + "schema": { + "minLength": "abc" + }, + "data": "abc", + "fail": true + }, + { + "name": "maxLength not a number", + "schema": { + "maxLength": "abc" + }, + "data": "abc", + "fail": true + }, + { + "name": "minimum not a number", + "schema": { + "minimum": "abc" + }, + "data": 123, + "fail": true + }, + { + "name": "maximum not a number", + "schema": { + "maximum": "abc" + }, + "data": 123, + "fail": true + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/invalid_path.test b/src/hos_libvariant/src/test/test_schema_data/invalid_path.test new file mode 100644 index 00000000..72464395 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/invalid_path.test @@ -0,0 +1,34 @@ +[ + { + "name": "Invalid ref paths - malformed", + "schema": { + "definitions": { + "foo": { + "type": "string" + } + }, + "type": "object", + "properties": { + "foo": { "$ref": "#definitions/foo" } + } + }, + "data": { "foo": "abc" }, + "exception": true + }, + { + "name": "Invalid ref paths - path does not match", + "schema": { + "definitions": { + "foo": { + "type": "string" + } + }, + "type": "object", + "properties": { + "foo": { "$ref": "#/definitions/bar/mar" } + } + }, + "data": { "foo": 123 }, + "exception": true + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/Makefile b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/Makefile new file mode 100644 index 00000000..01e90387 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/Makefile @@ -0,0 +1,7 @@ + +TARGETS := $(patsubst %.json,%.test,$(wildcard *.json)) + +all: $(TARGETS) + +%.test: %.json + python convert.py < $< > $@ diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/README b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/README new file mode 100644 index 00000000..a14cc8fe --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/README @@ -0,0 +1,26 @@ + +The tests in this folder where copied directly from jsonschema by Julian +https://github.com/Julian/jsonschema +https://python-jsonschema.readthedocs.org/ + +Copyright (c) 2013 Julian Berman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalItems.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalItems.json new file mode 100644 index 00000000..521745c8 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalItems.json @@ -0,0 +1,82 @@ +[ + { + "description": "additionalItems as schema", + "schema": { + "items": [{}], + "additionalItems": {"type": "integer"} + }, + "tests": [ + { + "description": "additional items match schema", + "data": [ null, 2, 3, 4 ], + "valid": true + }, + { + "description": "additional items do not match schema", + "data": [ null, 2, 3, "foo" ], + "valid": false + } + ] + }, + { + "description": "items is schema, no additionalItems", + "schema": { + "items": {}, + "additionalItems": false + }, + "tests": [ + { + "description": "all items match schema", + "data": [ 1, 2, 3, 4, 5 ], + "valid": true + } + ] + }, + { + "description": "array of items with no additionalItems", + "schema": { + "items": [{}, {}, {}], + "additionalItems": false + }, + "tests": [ + { + "description": "no additional items present", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "additional items are not permitted", + "data": [ 1, 2, 3, 4 ], + "valid": false + } + ] + }, + { + "description": "additionalItems as false without items", + "schema": {"additionalItems": false}, + "tests": [ + { + "description": + "items defaults to empty schema so everything is valid", + "data": [ 1, 2, 3, 4, 5 ], + "valid": true + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + } + ] + }, + { + "description": "additionalItems are allowed by default", + "schema": {"items": [{"type": "integer"}]}, + "tests": [ + { + "description": "only the first item is validated", + "data": [1, "foo", false], + "valid": true + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalItems.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalItems.test new file mode 100644 index 00000000..abe443c8 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalItems.test @@ -0,0 +1 @@ +[{"fail": false, "data": [null, 2, 3, 4], "name": "additionalItems as schema -- additional items match schema", "schema": {"items": [{}], "additionalItems": {"type": "integer"}}}, {"fail": true, "data": [null, 2, 3, "foo"], "name": "additionalItems as schema -- additional items do not match schema", "schema": {"items": [{}], "additionalItems": {"type": "integer"}}}, {"fail": false, "data": [1, 2, 3, 4, 5], "name": "items is schema, no additionalItems -- all items match schema", "schema": {"items": {}, "additionalItems": false}}, {"fail": false, "data": [1, 2, 3], "name": "array of items with no additionalItems -- no additional items present", "schema": {"items": [{}, {}, {}], "additionalItems": false}}, {"fail": true, "data": [1, 2, 3, 4], "name": "array of items with no additionalItems -- additional items are not permitted", "schema": {"items": [{}, {}, {}], "additionalItems": false}}, {"fail": false, "data": [1, 2, 3, 4, 5], "name": "additionalItems as false without items -- items defaults to empty schema so everything is valid", "schema": {"additionalItems": false}}, {"fail": false, "data": {"foo": "bar"}, "name": "additionalItems as false without items -- ignores non-arrays", "schema": {"additionalItems": false}}, {"fail": false, "data": [1, "foo", false], "name": "additionalItems are allowed by default -- only the first item is validated", "schema": {"items": [{"type": "integer"}]}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalProperties.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalProperties.json new file mode 100644 index 00000000..c997f75d --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalProperties.json @@ -0,0 +1,63 @@ +[ + { + "description": + "additionalProperties being false does not allow other properties", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "additionalProperties": false + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": [1, 2, 3], + "valid": true + } + ] + }, + { + "description": + "additionalProperties allows a schema which should validate", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional valid property is valid", + "data": {"foo" : 1, "bar" : 2, "quux" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : 12}, + "valid": false + } + ] + }, + { + "description": "additionalProperties are allowed by default", + "schema": {"properties": {"foo": {}, "bar": {}}}, + "tests": [ + { + "description": "additional properties are allowed", + "data": {"foo": 1, "bar": 2, "quux": true}, + "valid": true + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalProperties.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalProperties.test new file mode 100644 index 00000000..016cc774 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/additionalProperties.test @@ -0,0 +1 @@ +[{"fail": false, "data": {"foo": 1}, "name": "additionalProperties being false does not allow other properties -- no additional properties is valid", "schema": {"additionalProperties": false, "properties": {"foo": {}, "bar": {}}}}, {"fail": true, "data": {"quux": "boom", "foo": 1, "bar": 2}, "name": "additionalProperties being false does not allow other properties -- an additional property is invalid", "schema": {"additionalProperties": false, "properties": {"foo": {}, "bar": {}}}}, {"fail": false, "data": [1, 2, 3], "name": "additionalProperties being false does not allow other properties -- ignores non-objects", "schema": {"additionalProperties": false, "properties": {"foo": {}, "bar": {}}}}, {"fail": false, "data": {"foo": 1}, "name": "additionalProperties allows a schema which should validate -- no additional properties is valid", "schema": {"additionalProperties": {"type": "boolean"}, "properties": {"foo": {}, "bar": {}}}}, {"fail": false, "data": {"quux": true, "foo": 1, "bar": 2}, "name": "additionalProperties allows a schema which should validate -- an additional valid property is valid", "schema": {"additionalProperties": {"type": "boolean"}, "properties": {"foo": {}, "bar": {}}}}, {"fail": true, "data": {"quux": 12, "foo": 1, "bar": 2}, "name": "additionalProperties allows a schema which should validate -- an additional invalid property is invalid", "schema": {"additionalProperties": {"type": "boolean"}, "properties": {"foo": {}, "bar": {}}}}, {"fail": false, "data": {"quux": true, "foo": 1, "bar": 2}, "name": "additionalProperties are allowed by default -- additional properties are allowed", "schema": {"properties": {"foo": {}, "bar": {}}}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/allOf.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/allOf.json new file mode 100644 index 00000000..bbb5f89e --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/allOf.json @@ -0,0 +1,112 @@ +[ + { + "description": "allOf", + "schema": { + "allOf": [ + { + "properties": { + "bar": {"type": "integer"} + }, + "required": ["bar"] + }, + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "allOf", + "data": {"foo": "baz", "bar": 2}, + "valid": true + }, + { + "description": "mismatch second", + "data": {"foo": "baz"}, + "valid": false + }, + { + "description": "mismatch first", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "wrong type", + "data": {"foo": "baz", "bar": "quux"}, + "valid": false + } + ] + }, + { + "description": "allOf with base schema", + "schema": { + "properties": {"bar": {"type": "integer"}}, + "required": ["bar"], + "allOf" : [ + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + }, + { + "properties": { + "baz": {"type": "null"} + }, + "required": ["baz"] + } + ] + }, + "tests": [ + { + "description": "valid", + "data": {"foo": "quux", "bar": 2, "baz": null}, + "valid": true + }, + { + "description": "mismatch base schema", + "data": {"foo": "quux", "baz": null}, + "valid": false + }, + { + "description": "mismatch first allOf", + "data": {"bar": 2, "baz": null}, + "valid": false + }, + { + "description": "mismatch second allOf", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "mismatch both", + "data": {"bar": 2}, + "valid": false + } + ] + }, + { + "description": "allOf simple types", + "schema": { + "allOf": [ + {"maximum": 30}, + {"minimum": 20} + ] + }, + "tests": [ + { + "description": "valid", + "data": 25, + "valid": true + }, + { + "description": "mismatch one", + "data": 35, + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/allOf.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/allOf.test new file mode 100644 index 00000000..c03b0ddb --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/allOf.test @@ -0,0 +1 @@ +[{"fail": false, "data": {"foo": "baz", "bar": 2}, "name": "allOf -- allOf", "schema": {"allOf": [{"required": ["bar"], "properties": {"bar": {"type": "integer"}}}, {"required": ["foo"], "properties": {"foo": {"type": "string"}}}]}}, {"fail": true, "data": {"foo": "baz"}, "name": "allOf -- mismatch second", "schema": {"allOf": [{"required": ["bar"], "properties": {"bar": {"type": "integer"}}}, {"required": ["foo"], "properties": {"foo": {"type": "string"}}}]}}, {"fail": true, "data": {"bar": 2}, "name": "allOf -- mismatch first", "schema": {"allOf": [{"required": ["bar"], "properties": {"bar": {"type": "integer"}}}, {"required": ["foo"], "properties": {"foo": {"type": "string"}}}]}}, {"fail": true, "data": {"foo": "baz", "bar": "quux"}, "name": "allOf -- wrong type", "schema": {"allOf": [{"required": ["bar"], "properties": {"bar": {"type": "integer"}}}, {"required": ["foo"], "properties": {"foo": {"type": "string"}}}]}}, {"fail": false, "data": {"baz": null, "foo": "quux", "bar": 2}, "name": "allOf with base schema -- valid", "schema": {"required": ["bar"], "properties": {"bar": {"type": "integer"}}, "allOf": [{"required": ["foo"], "properties": {"foo": {"type": "string"}}}, {"required": ["baz"], "properties": {"baz": {"type": "null"}}}]}}, {"fail": true, "data": {"foo": "quux", "baz": null}, "name": "allOf with base schema -- mismatch base schema", "schema": {"required": ["bar"], "properties": {"bar": {"type": "integer"}}, "allOf": [{"required": ["foo"], "properties": {"foo": {"type": "string"}}}, {"required": ["baz"], "properties": {"baz": {"type": "null"}}}]}}, {"fail": true, "data": {"baz": null, "bar": 2}, "name": "allOf with base schema -- mismatch first allOf", "schema": {"required": ["bar"], "properties": {"bar": {"type": "integer"}}, "allOf": [{"required": ["foo"], "properties": {"foo": {"type": "string"}}}, {"required": ["baz"], "properties": {"baz": {"type": "null"}}}]}}, {"fail": true, "data": {"foo": "quux", "bar": 2}, "name": "allOf with base schema -- mismatch second allOf", "schema": {"required": ["bar"], "properties": {"bar": {"type": "integer"}}, "allOf": [{"required": ["foo"], "properties": {"foo": {"type": "string"}}}, {"required": ["baz"], "properties": {"baz": {"type": "null"}}}]}}, {"fail": true, "data": {"bar": 2}, "name": "allOf with base schema -- mismatch both", "schema": {"required": ["bar"], "properties": {"bar": {"type": "integer"}}, "allOf": [{"required": ["foo"], "properties": {"foo": {"type": "string"}}}, {"required": ["baz"], "properties": {"baz": {"type": "null"}}}]}}, {"fail": false, "data": 25, "name": "allOf simple types -- valid", "schema": {"allOf": [{"maximum": 30}, {"minimum": 20}]}}, {"fail": true, "data": 35, "name": "allOf simple types -- mismatch one", "schema": {"allOf": [{"maximum": 30}, {"minimum": 20}]}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/anyOf.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/anyOf.json new file mode 100644 index 00000000..a58714af --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/anyOf.json @@ -0,0 +1,68 @@ +[ + { + "description": "anyOf", + "schema": { + "anyOf": [ + { + "type": "integer" + }, + { + "minimum": 2 + } + ] + }, + "tests": [ + { + "description": "first anyOf valid", + "data": 1, + "valid": true + }, + { + "description": "second anyOf valid", + "data": 2.5, + "valid": true + }, + { + "description": "both anyOf valid", + "data": 3, + "valid": true + }, + { + "description": "neither anyOf valid", + "data": 1.5, + "valid": false + } + ] + }, + { + "description": "anyOf with base schema", + "schema": { + "type": "string", + "anyOf" : [ + { + "maxLength": 2 + }, + { + "minLength": 4 + } + ] + }, + "tests": [ + { + "description": "mismatch base schema", + "data": 3, + "valid": false + }, + { + "description": "one anyOf valid", + "data": "foobar", + "valid": true + }, + { + "description": "both anyOf invalid", + "data": "foo", + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/anyOf.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/anyOf.test new file mode 100644 index 00000000..5d24c4e8 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/anyOf.test @@ -0,0 +1 @@ +[{"fail": false, "data": 1, "name": "anyOf -- first anyOf valid", "schema": {"anyOf": [{"type": "integer"}, {"minimum": 2}]}}, {"fail": false, "data": 2.5, "name": "anyOf -- second anyOf valid", "schema": {"anyOf": [{"type": "integer"}, {"minimum": 2}]}}, {"fail": false, "data": 3, "name": "anyOf -- both anyOf valid", "schema": {"anyOf": [{"type": "integer"}, {"minimum": 2}]}}, {"fail": true, "data": 1.5, "name": "anyOf -- neither anyOf valid", "schema": {"anyOf": [{"type": "integer"}, {"minimum": 2}]}}, {"fail": true, "data": 3, "name": "anyOf with base schema -- mismatch base schema", "schema": {"anyOf": [{"maxLength": 2}, {"minLength": 4}], "type": "string"}}, {"fail": false, "data": "foobar", "name": "anyOf with base schema -- one anyOf valid", "schema": {"anyOf": [{"maxLength": 2}, {"minLength": 4}], "type": "string"}}, {"fail": true, "data": "foo", "name": "anyOf with base schema -- both anyOf invalid", "schema": {"anyOf": [{"maxLength": 2}, {"minLength": 4}], "type": "string"}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/convert.py b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/convert.py new file mode 100644 index 00000000..99bcec58 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/convert.py @@ -0,0 +1,16 @@ + +import json +import sys + +tests = json.load(sys.stdin) + +out = [] +for t in tests: + for case in t['tests']: + out.append({ + 'name': t['description'] + ' -- ' + case['description'], + 'schema': t['schema'], + 'data': case['data'], + 'fail': not case['valid'] + }) +json.dump(out, sys.stdout) diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/definitions.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/definitions.json new file mode 100644 index 00000000..cf935a32 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/definitions.json @@ -0,0 +1,32 @@ +[ + { + "description": "valid definition", + "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, + "tests": [ + { + "description": "valid definition schema", + "data": { + "definitions": { + "foo": {"type": "integer"} + } + }, + "valid": true + } + ] + }, + { + "description": "invalid definition", + "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, + "tests": [ + { + "description": "invalid definition schema", + "data": { + "definitions": { + "foo": {"type": 1} + } + }, + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/definitions.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/definitions.test new file mode 100644 index 00000000..4bd8350a --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/definitions.test @@ -0,0 +1 @@ +[{"fail": false, "data": {"definitions": {"foo": {"type": "integer"}}}, "name": "valid definition -- valid definition schema", "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}}, {"fail": true, "data": {"definitions": {"foo": {"type": 1}}}, "name": "invalid definition -- invalid definition schema", "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/dependencies.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/dependencies.json new file mode 100644 index 00000000..7b9b16a7 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/dependencies.json @@ -0,0 +1,113 @@ +[ + { + "description": "dependencies", + "schema": { + "dependencies": {"bar": ["foo"]} + }, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependant", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "with dependency", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "multiple dependencies", + "schema": { + "dependencies": {"quux": ["foo", "bar"]} + }, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependants", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "with dependencies", + "data": {"foo": 1, "bar": 2, "quux": 3}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"foo": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing other dependency", + "data": {"bar": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing both dependencies", + "data": {"quux": 1}, + "valid": false + } + ] + }, + { + "description": "multiple dependencies subschema", + "schema": { + "dependencies": { + "bar": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "integer"} + } + } + } + }, + "tests": [ + { + "description": "valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "no dependency", + "data": {"foo": "quux"}, + "valid": true + }, + { + "description": "wrong type", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "wrong type other", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + }, + { + "description": "wrong type both", + "data": {"foo": "quux", "bar": "quux"}, + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/dependencies.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/dependencies.test new file mode 100644 index 00000000..f54a1118 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/dependencies.test @@ -0,0 +1 @@ +[{"fail": false, "data": {}, "name": "dependencies -- neither", "schema": {"dependencies": {"bar": ["foo"]}}}, {"fail": false, "data": {"foo": 1}, "name": "dependencies -- nondependant", "schema": {"dependencies": {"bar": ["foo"]}}}, {"fail": false, "data": {"foo": 1, "bar": 2}, "name": "dependencies -- with dependency", "schema": {"dependencies": {"bar": ["foo"]}}}, {"fail": true, "data": {"bar": 2}, "name": "dependencies -- missing dependency", "schema": {"dependencies": {"bar": ["foo"]}}}, {"fail": false, "data": "foo", "name": "dependencies -- ignores non-objects", "schema": {"dependencies": {"bar": ["foo"]}}}, {"fail": false, "data": {}, "name": "multiple dependencies -- neither", "schema": {"dependencies": {"quux": ["foo", "bar"]}}}, {"fail": false, "data": {"foo": 1, "bar": 2}, "name": "multiple dependencies -- nondependants", "schema": {"dependencies": {"quux": ["foo", "bar"]}}}, {"fail": false, "data": {"quux": 3, "foo": 1, "bar": 2}, "name": "multiple dependencies -- with dependencies", "schema": {"dependencies": {"quux": ["foo", "bar"]}}}, {"fail": true, "data": {"quux": 2, "foo": 1}, "name": "multiple dependencies -- missing dependency", "schema": {"dependencies": {"quux": ["foo", "bar"]}}}, {"fail": true, "data": {"quux": 2, "bar": 1}, "name": "multiple dependencies -- missing other dependency", "schema": {"dependencies": {"quux": ["foo", "bar"]}}}, {"fail": true, "data": {"quux": 1}, "name": "multiple dependencies -- missing both dependencies", "schema": {"dependencies": {"quux": ["foo", "bar"]}}}, {"fail": false, "data": {"foo": 1, "bar": 2}, "name": "multiple dependencies subschema -- valid", "schema": {"dependencies": {"bar": {"properties": {"foo": {"type": "integer"}, "bar": {"type": "integer"}}}}}}, {"fail": false, "data": {"foo": "quux"}, "name": "multiple dependencies subschema -- no dependency", "schema": {"dependencies": {"bar": {"properties": {"foo": {"type": "integer"}, "bar": {"type": "integer"}}}}}}, {"fail": true, "data": {"foo": "quux", "bar": 2}, "name": "multiple dependencies subschema -- wrong type", "schema": {"dependencies": {"bar": {"properties": {"foo": {"type": "integer"}, "bar": {"type": "integer"}}}}}}, {"fail": true, "data": {"foo": 2, "bar": "quux"}, "name": "multiple dependencies subschema -- wrong type other", "schema": {"dependencies": {"bar": {"properties": {"foo": {"type": "integer"}, "bar": {"type": "integer"}}}}}}, {"fail": true, "data": {"foo": "quux", "bar": "quux"}, "name": "multiple dependencies subschema -- wrong type both", "schema": {"dependencies": {"bar": {"properties": {"foo": {"type": "integer"}, "bar": {"type": "integer"}}}}}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/enum.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/enum.json new file mode 100644 index 00000000..a539edb7 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/enum.json @@ -0,0 +1,39 @@ +[ + { + "description": "simple enum validation", + "schema": {"enum": [1, 2, 3]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": 1, + "valid": true + }, + { + "description": "something else is invalid", + "data": 4, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum validation", + "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": [], + "valid": true + }, + { + "description": "something else is invalid", + "data": null, + "valid": false + }, + { + "description": "objects are deep compared", + "data": {"foo": false}, + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/enum.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/enum.test new file mode 100644 index 00000000..916e4375 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/enum.test @@ -0,0 +1 @@ +[{"fail": false, "data": 1, "name": "simple enum validation -- one of the enum is valid", "schema": {"enum": [1, 2, 3]}}, {"fail": true, "data": 4, "name": "simple enum validation -- something else is invalid", "schema": {"enum": [1, 2, 3]}}, {"fail": false, "data": [], "name": "heterogeneous enum validation -- one of the enum is valid", "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}}, {"fail": true, "data": null, "name": "heterogeneous enum validation -- something else is invalid", "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}}, {"fail": true, "data": {"foo": false}, "name": "heterogeneous enum validation -- objects are deep compared", "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/items.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/items.json new file mode 100644 index 00000000..f5e18a13 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/items.json @@ -0,0 +1,46 @@ +[ + { + "description": "a schema given for items", + "schema": { + "items": {"type": "integer"} + }, + "tests": [ + { + "description": "valid items", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "wrong type of items", + "data": [1, "x"], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + } + ] + }, + { + "description": "an array of schemas for items", + "schema": { + "items": [ + {"type": "integer"}, + {"type": "string"} + ] + }, + "tests": [ + { + "description": "correct types", + "data": [ 1, "foo" ], + "valid": true + }, + { + "description": "wrong types", + "data": [ "foo", 1 ], + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/items.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/items.test new file mode 100644 index 00000000..6975dbd9 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/items.test @@ -0,0 +1 @@ +[{"fail": false, "data": [1, 2, 3], "name": "a schema given for items -- valid items", "schema": {"items": {"type": "integer"}}}, {"fail": true, "data": [1, "x"], "name": "a schema given for items -- wrong type of items", "schema": {"items": {"type": "integer"}}}, {"fail": false, "data": {"foo": "bar"}, "name": "a schema given for items -- ignores non-arrays", "schema": {"items": {"type": "integer"}}}, {"fail": false, "data": [1, "foo"], "name": "an array of schemas for items -- correct types", "schema": {"items": [{"type": "integer"}, {"type": "string"}]}}, {"fail": true, "data": ["foo", 1], "name": "an array of schemas for items -- wrong types", "schema": {"items": [{"type": "integer"}, {"type": "string"}]}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxItems.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxItems.json new file mode 100644 index 00000000..3b53a6b3 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxItems.json @@ -0,0 +1,28 @@ +[ + { + "description": "maxItems validation", + "schema": {"maxItems": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": [1], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "too long is invalid", + "data": [1, 2, 3], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "foobar", + "valid": true + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxItems.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxItems.test new file mode 100644 index 00000000..a573f4c0 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxItems.test @@ -0,0 +1 @@ +[{"fail": false, "data": [1], "name": "maxItems validation -- shorter is valid", "schema": {"maxItems": 2}}, {"fail": false, "data": [1, 2], "name": "maxItems validation -- exact length is valid", "schema": {"maxItems": 2}}, {"fail": true, "data": [1, 2, 3], "name": "maxItems validation -- too long is invalid", "schema": {"maxItems": 2}}, {"fail": false, "data": "foobar", "name": "maxItems validation -- ignores non-arrays", "schema": {"maxItems": 2}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxLength.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxLength.json new file mode 100644 index 00000000..561767b9 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxLength.json @@ -0,0 +1,28 @@ +[ + { + "description": "maxLength validation", + "schema": {"maxLength": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": "f", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too long is invalid", + "data": "foo", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 10, + "valid": true + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxLength.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxLength.test new file mode 100644 index 00000000..4933e821 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxLength.test @@ -0,0 +1 @@ +[{"fail": false, "data": "f", "name": "maxLength validation -- shorter is valid", "schema": {"maxLength": 2}}, {"fail": false, "data": "fo", "name": "maxLength validation -- exact length is valid", "schema": {"maxLength": 2}}, {"fail": true, "data": "foo", "name": "maxLength validation -- too long is invalid", "schema": {"maxLength": 2}}, {"fail": false, "data": 10, "name": "maxLength validation -- ignores non-strings", "schema": {"maxLength": 2}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxProperties.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxProperties.json new file mode 100644 index 00000000..d282446a --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxProperties.json @@ -0,0 +1,28 @@ +[ + { + "description": "maxProperties validation", + "schema": {"maxProperties": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "exact length is valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "too long is invalid", + "data": {"foo": 1, "bar": 2, "baz": 3}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "foobar", + "valid": true + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxProperties.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxProperties.test new file mode 100644 index 00000000..dc132fa5 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maxProperties.test @@ -0,0 +1 @@ +[{"fail": false, "data": {"foo": 1}, "name": "maxProperties validation -- shorter is valid", "schema": {"maxProperties": 2}}, {"fail": false, "data": {"foo": 1, "bar": 2}, "name": "maxProperties validation -- exact length is valid", "schema": {"maxProperties": 2}}, {"fail": true, "data": {"baz": 3, "foo": 1, "bar": 2}, "name": "maxProperties validation -- too long is invalid", "schema": {"maxProperties": 2}}, {"fail": false, "data": "foobar", "name": "maxProperties validation -- ignores non-objects", "schema": {"maxProperties": 2}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maximum.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maximum.json new file mode 100644 index 00000000..86c7b89c --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maximum.json @@ -0,0 +1,42 @@ +[ + { + "description": "maximum validation", + "schema": {"maximum": 3.0}, + "tests": [ + { + "description": "below the maximum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 3.5, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "exclusiveMaximum validation", + "schema": { + "maximum": 3.0, + "exclusiveMaximum": true + }, + "tests": [ + { + "description": "below the maximum is still valid", + "data": 2.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 3.0, + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maximum.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maximum.test new file mode 100644 index 00000000..70b916e2 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/maximum.test @@ -0,0 +1 @@ +[{"fail": false, "data": 2.6000000000000001, "name": "maximum validation -- below the maximum is valid", "schema": {"maximum": 3.0}}, {"fail": true, "data": 3.5, "name": "maximum validation -- above the maximum is invalid", "schema": {"maximum": 3.0}}, {"fail": false, "data": "x", "name": "maximum validation -- ignores non-numbers", "schema": {"maximum": 3.0}}, {"fail": false, "data": 2.2000000000000002, "name": "exclusiveMaximum validation -- below the maximum is still valid", "schema": {"exclusiveMaximum": true, "maximum": 3.0}}, {"fail": true, "data": 3.0, "name": "exclusiveMaximum validation -- boundary point is invalid", "schema": {"exclusiveMaximum": true, "maximum": 3.0}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minItems.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minItems.json new file mode 100644 index 00000000..ed511881 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minItems.json @@ -0,0 +1,28 @@ +[ + { + "description": "minItems validation", + "schema": {"minItems": 1}, + "tests": [ + { + "description": "longer is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1], + "valid": true + }, + { + "description": "too short is invalid", + "data": [], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "", + "valid": true + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minItems.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minItems.test new file mode 100644 index 00000000..4e482def --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minItems.test @@ -0,0 +1 @@ +[{"fail": false, "data": [1, 2], "name": "minItems validation -- longer is valid", "schema": {"minItems": 1}}, {"fail": false, "data": [1], "name": "minItems validation -- exact length is valid", "schema": {"minItems": 1}}, {"fail": true, "data": [], "name": "minItems validation -- too short is invalid", "schema": {"minItems": 1}}, {"fail": false, "data": "", "name": "minItems validation -- ignores non-arrays", "schema": {"minItems": 1}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minLength.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minLength.json new file mode 100644 index 00000000..e9c14b17 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minLength.json @@ -0,0 +1,28 @@ +[ + { + "description": "minLength validation", + "schema": {"minLength": 2}, + "tests": [ + { + "description": "longer is valid", + "data": "foo", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too short is invalid", + "data": "f", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 1, + "valid": true + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minLength.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minLength.test new file mode 100644 index 00000000..f4fb32ab --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minLength.test @@ -0,0 +1 @@ +[{"fail": false, "data": "foo", "name": "minLength validation -- longer is valid", "schema": {"minLength": 2}}, {"fail": false, "data": "fo", "name": "minLength validation -- exact length is valid", "schema": {"minLength": 2}}, {"fail": true, "data": "f", "name": "minLength validation -- too short is invalid", "schema": {"minLength": 2}}, {"fail": false, "data": 1, "name": "minLength validation -- ignores non-strings", "schema": {"minLength": 2}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minProperties.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minProperties.json new file mode 100644 index 00000000..a72c7d29 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minProperties.json @@ -0,0 +1,28 @@ +[ + { + "description": "minProperties validation", + "schema": {"minProperties": 1}, + "tests": [ + { + "description": "longer is valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "exact length is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "too short is invalid", + "data": {}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "", + "valid": true + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minProperties.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minProperties.test new file mode 100644 index 00000000..e9fdab6b --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minProperties.test @@ -0,0 +1 @@ +[{"fail": false, "data": {"foo": 1, "bar": 2}, "name": "minProperties validation -- longer is valid", "schema": {"minProperties": 1}}, {"fail": false, "data": {"foo": 1}, "name": "minProperties validation -- exact length is valid", "schema": {"minProperties": 1}}, {"fail": true, "data": {}, "name": "minProperties validation -- too short is invalid", "schema": {"minProperties": 1}}, {"fail": false, "data": "", "name": "minProperties validation -- ignores non-objects", "schema": {"minProperties": 1}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minimum.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minimum.json new file mode 100644 index 00000000..d5bf000b --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minimum.json @@ -0,0 +1,42 @@ +[ + { + "description": "minimum validation", + "schema": {"minimum": 1.1}, + "tests": [ + { + "description": "above the minimum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "below the minimum is invalid", + "data": 0.6, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "exclusiveMinimum validation", + "schema": { + "minimum": 1.1, + "exclusiveMinimum": true + }, + "tests": [ + { + "description": "above the minimum is still valid", + "data": 1.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 1.1, + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minimum.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minimum.test new file mode 100644 index 00000000..ae413de4 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/minimum.test @@ -0,0 +1 @@ +[{"fail": false, "data": 2.6000000000000001, "name": "minimum validation -- above the minimum is valid", "schema": {"minimum": 1.1000000000000001}}, {"fail": true, "data": 0.59999999999999998, "name": "minimum validation -- below the minimum is invalid", "schema": {"minimum": 1.1000000000000001}}, {"fail": false, "data": "x", "name": "minimum validation -- ignores non-numbers", "schema": {"minimum": 1.1000000000000001}}, {"fail": false, "data": 1.2, "name": "exclusiveMinimum validation -- above the minimum is still valid", "schema": {"minimum": 1.1000000000000001, "exclusiveMinimum": true}}, {"fail": true, "data": 1.1000000000000001, "name": "exclusiveMinimum validation -- boundary point is invalid", "schema": {"minimum": 1.1000000000000001, "exclusiveMinimum": true}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/multipleOf.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/multipleOf.json new file mode 100644 index 00000000..ca3b7618 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/multipleOf.json @@ -0,0 +1,60 @@ +[ + { + "description": "by int", + "schema": {"multipleOf": 2}, + "tests": [ + { + "description": "int by int", + "data": 10, + "valid": true + }, + { + "description": "int by int fail", + "data": 7, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "by number", + "schema": {"multipleOf": 1.5}, + "tests": [ + { + "description": "zero is multiple of anything", + "data": 0, + "valid": true + }, + { + "description": "4.5 is multiple of 1.5", + "data": 4.5, + "valid": true + }, + { + "description": "35 is not multiple of 1.5", + "data": 35, + "valid": false + } + ] + }, + { + "description": "by small number", + "schema": {"multipleOf": 0.0001}, + "tests": [ + { + "description": "0.0075 is multiple of 0.0001", + "data": 0.0075, + "valid": true + }, + { + "description": "0.00751 is not multiple of 0.0001", + "data": 0.00751, + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/multipleOf.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/multipleOf.test new file mode 100644 index 00000000..0debf687 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/multipleOf.test @@ -0,0 +1 @@ +[{"fail": false, "data": 10, "name": "by int -- int by int", "schema": {"multipleOf": 2}}, {"fail": true, "data": 7, "name": "by int -- int by int fail", "schema": {"multipleOf": 2}}, {"fail": false, "data": "foo", "name": "by int -- ignores non-numbers", "schema": {"multipleOf": 2}}, {"fail": false, "data": 0, "name": "by number -- zero is multiple of anything", "schema": {"multipleOf": 1.5}}, {"fail": false, "data": 4.5, "name": "by number -- 4.5 is multiple of 1.5", "schema": {"multipleOf": 1.5}}, {"fail": true, "data": 35, "name": "by number -- 35 is not multiple of 1.5", "schema": {"multipleOf": 1.5}}, {"fail": false, "data": 0.0074999999999999997, "name": "by small number -- 0.0075 is multiple of 0.0001", "schema": {"multipleOf": 0.0001}}, {"fail": true, "data": 0.0075100000000000002, "name": "by small number -- 0.00751 is not multiple of 0.0001", "schema": {"multipleOf": 0.0001}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/not.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/not.json new file mode 100644 index 00000000..2cdc9790 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/not.json @@ -0,0 +1,73 @@ +[ + { + "description": "not", + "schema": { + "not": {"type": "integer"} + }, + "tests": [ + { + "description": "allowed", + "data": "foo", + "valid": true + }, + { + "description": "disallowed", + "data": 1, + "valid": false + } + ] + }, + { + "description": "not multiple types", + "schema": { + "not": {"type": ["integer", "boolean"]} + }, + "tests": [ + { + "description": "valid", + "data": "foo", + "valid": true + }, + { + "description": "mismatch", + "data": 1, + "valid": false + }, + { + "description": "other mismatch", + "data": true, + "valid": false + } + ] + }, + { + "description": "not more complex schema", + "schema": { + "not": { + "type": "object", + "properties": { + "foo": { + "type": "string" + } + } + } + }, + "tests": [ + { + "description": "match", + "data": 1, + "valid": true + }, + { + "description": "other match", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "mismatch", + "data": {"foo": "bar"}, + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/not.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/not.test new file mode 100644 index 00000000..1761ab0f --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/not.test @@ -0,0 +1 @@ +[{"fail": false, "data": "foo", "name": "not -- allowed", "schema": {"not": {"type": "integer"}}}, {"fail": true, "data": 1, "name": "not -- disallowed", "schema": {"not": {"type": "integer"}}}, {"fail": false, "data": "foo", "name": "not multiple types -- valid", "schema": {"not": {"type": ["integer", "boolean"]}}}, {"fail": true, "data": 1, "name": "not multiple types -- mismatch", "schema": {"not": {"type": ["integer", "boolean"]}}}, {"fail": true, "data": true, "name": "not multiple types -- other mismatch", "schema": {"not": {"type": ["integer", "boolean"]}}}, {"fail": false, "data": 1, "name": "not more complex schema -- match", "schema": {"not": {"type": "object", "properties": {"foo": {"type": "string"}}}}}, {"fail": false, "data": {"foo": 1}, "name": "not more complex schema -- other match", "schema": {"not": {"type": "object", "properties": {"foo": {"type": "string"}}}}}, {"fail": true, "data": {"foo": "bar"}, "name": "not more complex schema -- mismatch", "schema": {"not": {"type": "object", "properties": {"foo": {"type": "string"}}}}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/oneOf.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/oneOf.json new file mode 100644 index 00000000..1eaa4e47 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/oneOf.json @@ -0,0 +1,68 @@ +[ + { + "description": "oneOf", + "schema": { + "oneOf": [ + { + "type": "integer" + }, + { + "minimum": 2 + } + ] + }, + "tests": [ + { + "description": "first oneOf valid", + "data": 1, + "valid": true + }, + { + "description": "second oneOf valid", + "data": 2.5, + "valid": true + }, + { + "description": "both oneOf valid", + "data": 3, + "valid": false + }, + { + "description": "neither oneOf valid", + "data": 1.5, + "valid": false + } + ] + }, + { + "description": "oneOf with base schema", + "schema": { + "type": "string", + "oneOf" : [ + { + "minLength": 2 + }, + { + "maxLength": 4 + } + ] + }, + "tests": [ + { + "description": "mismatch base schema", + "data": 3, + "valid": false + }, + { + "description": "one oneOf valid", + "data": "foobar", + "valid": true + }, + { + "description": "both oneOf valid", + "data": "foo", + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/oneOf.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/oneOf.test new file mode 100644 index 00000000..f56d6071 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/oneOf.test @@ -0,0 +1 @@ +[{"fail": false, "data": 1, "name": "oneOf -- first oneOf valid", "schema": {"oneOf": [{"type": "integer"}, {"minimum": 2}]}}, {"fail": false, "data": 2.5, "name": "oneOf -- second oneOf valid", "schema": {"oneOf": [{"type": "integer"}, {"minimum": 2}]}}, {"fail": true, "data": 3, "name": "oneOf -- both oneOf valid", "schema": {"oneOf": [{"type": "integer"}, {"minimum": 2}]}}, {"fail": true, "data": 1.5, "name": "oneOf -- neither oneOf valid", "schema": {"oneOf": [{"type": "integer"}, {"minimum": 2}]}}, {"fail": true, "data": 3, "name": "oneOf with base schema -- mismatch base schema", "schema": {"oneOf": [{"minLength": 2}, {"maxLength": 4}], "type": "string"}}, {"fail": false, "data": "foobar", "name": "oneOf with base schema -- one oneOf valid", "schema": {"oneOf": [{"minLength": 2}, {"maxLength": 4}], "type": "string"}}, {"fail": true, "data": "foo", "name": "oneOf with base schema -- both oneOf valid", "schema": {"oneOf": [{"minLength": 2}, {"maxLength": 4}], "type": "string"}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/pattern.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/pattern.json new file mode 100644 index 00000000..befc4b56 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/pattern.json @@ -0,0 +1,23 @@ +[ + { + "description": "pattern validation", + "schema": {"pattern": "^a*$"}, + "tests": [ + { + "description": "a matching pattern is valid", + "data": "aaa", + "valid": true + }, + { + "description": "a non-matching pattern is invalid", + "data": "abc", + "valid": false + }, + { + "description": "ignores non-strings", + "data": true, + "valid": true + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/pattern.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/pattern.test new file mode 100644 index 00000000..0485d619 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/pattern.test @@ -0,0 +1 @@ +[{"fail": false, "data": "aaa", "name": "pattern validation -- a matching pattern is valid", "schema": {"pattern": "^a*$"}}, {"fail": true, "data": "abc", "name": "pattern validation -- a non-matching pattern is invalid", "schema": {"pattern": "^a*$"}}, {"fail": false, "data": true, "name": "pattern validation -- ignores non-strings", "schema": {"pattern": "^a*$"}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/patternProperties.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/patternProperties.json new file mode 100644 index 00000000..18586e5d --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/patternProperties.json @@ -0,0 +1,110 @@ +[ + { + "description": + "patternProperties validates properties matching a regex", + "schema": { + "patternProperties": { + "f.*o": {"type": "integer"} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "multiple valid matches is valid", + "data": {"foo": 1, "foooooo" : 2}, + "valid": true + }, + { + "description": "a single invalid match is invalid", + "data": {"foo": "bar", "fooooo": 2}, + "valid": false + }, + { + "description": "multiple invalid matches is invalid", + "data": {"foo": "bar", "foooooo" : "baz"}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "multiple simultaneous patternProperties are validated", + "schema": { + "patternProperties": { + "a*": {"type": "integer"}, + "aaa*": {"maximum": 20} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"a": 21}, + "valid": true + }, + { + "description": "a simultaneous match is valid", + "data": {"aaaa": 18}, + "valid": true + }, + { + "description": "multiple matches is valid", + "data": {"a": 21, "aaaa": 18}, + "valid": true + }, + { + "description": "an invalid due to one is invalid", + "data": {"a": "bar"}, + "valid": false + }, + { + "description": "an invalid due to the other is invalid", + "data": {"aaaa": 31}, + "valid": false + }, + { + "description": "an invalid due to both is invalid", + "data": {"aaa": "foo", "aaaa": 31}, + "valid": false + } + ] + }, + { + "description": "regexes are not anchored by default and are case sensitive", + "schema": { + "patternProperties": { + "[0-9]{2,}": { "type": "boolean" }, + "X_": { "type": "string" } + } + }, + "tests": [ + { + "description": "non recognized members are ignored", + "data": { "answer 1": "42" }, + "valid": true + }, + { + "description": "recognized members are accounted for", + "data": { "a31b": null }, + "valid": false + }, + { + "description": "regexes are case sensitive", + "data": { "a_x_3": 3 }, + "valid": true + }, + { + "description": "regexes are case sensitive, 2", + "data": { "a_X_3": 3 }, + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/patternProperties.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/patternProperties.test new file mode 100644 index 00000000..a5ff2de2 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/patternProperties.test @@ -0,0 +1 @@ +[{"fail": false, "data": {"foo": 1}, "name": "patternProperties validates properties matching a regex -- a single valid match is valid", "schema": {"patternProperties": {"f.*o": {"type": "integer"}}}}, {"fail": false, "data": {"foooooo": 2, "foo": 1}, "name": "patternProperties validates properties matching a regex -- multiple valid matches is valid", "schema": {"patternProperties": {"f.*o": {"type": "integer"}}}}, {"fail": true, "data": {"foo": "bar", "fooooo": 2}, "name": "patternProperties validates properties matching a regex -- a single invalid match is invalid", "schema": {"patternProperties": {"f.*o": {"type": "integer"}}}}, {"fail": true, "data": {"foooooo": "baz", "foo": "bar"}, "name": "patternProperties validates properties matching a regex -- multiple invalid matches is invalid", "schema": {"patternProperties": {"f.*o": {"type": "integer"}}}}, {"fail": false, "data": 12, "name": "patternProperties validates properties matching a regex -- ignores non-objects", "schema": {"patternProperties": {"f.*o": {"type": "integer"}}}}, {"fail": false, "data": {"a": 21}, "name": "multiple simultaneous patternProperties are validated -- a single valid match is valid", "schema": {"patternProperties": {"a*": {"type": "integer"}, "aaa*": {"maximum": 20}}}}, {"fail": false, "data": {"aaaa": 18}, "name": "multiple simultaneous patternProperties are validated -- a simultaneous match is valid", "schema": {"patternProperties": {"a*": {"type": "integer"}, "aaa*": {"maximum": 20}}}}, {"fail": false, "data": {"a": 21, "aaaa": 18}, "name": "multiple simultaneous patternProperties are validated -- multiple matches is valid", "schema": {"patternProperties": {"a*": {"type": "integer"}, "aaa*": {"maximum": 20}}}}, {"fail": true, "data": {"a": "bar"}, "name": "multiple simultaneous patternProperties are validated -- an invalid due to one is invalid", "schema": {"patternProperties": {"a*": {"type": "integer"}, "aaa*": {"maximum": 20}}}}, {"fail": true, "data": {"aaaa": 31}, "name": "multiple simultaneous patternProperties are validated -- an invalid due to the other is invalid", "schema": {"patternProperties": {"a*": {"type": "integer"}, "aaa*": {"maximum": 20}}}}, {"fail": true, "data": {"aaaa": 31, "aaa": "foo"}, "name": "multiple simultaneous patternProperties are validated -- an invalid due to both is invalid", "schema": {"patternProperties": {"a*": {"type": "integer"}, "aaa*": {"maximum": 20}}}}, {"fail": false, "data": {"answer 1": "42"}, "name": "regexes are not anchored by default and are case sensitive -- non recognized members are ignored", "schema": {"patternProperties": {"X_": {"type": "string"}, "[0-9]{2,}": {"type": "boolean"}}}}, {"fail": true, "data": {"a31b": null}, "name": "regexes are not anchored by default and are case sensitive -- recognized members are accounted for", "schema": {"patternProperties": {"X_": {"type": "string"}, "[0-9]{2,}": {"type": "boolean"}}}}, {"fail": false, "data": {"a_x_3": 3}, "name": "regexes are not anchored by default and are case sensitive -- regexes are case sensitive", "schema": {"patternProperties": {"X_": {"type": "string"}, "[0-9]{2,}": {"type": "boolean"}}}}, {"fail": true, "data": {"a_X_3": 3}, "name": "regexes are not anchored by default and are case sensitive -- regexes are case sensitive, 2", "schema": {"patternProperties": {"X_": {"type": "string"}, "[0-9]{2,}": {"type": "boolean"}}}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/properties.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/properties.json new file mode 100644 index 00000000..cd1644dc --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/properties.json @@ -0,0 +1,92 @@ +[ + { + "description": "object properties validation", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "string"} + } + }, + "tests": [ + { + "description": "both properties present and valid is valid", + "data": {"foo": 1, "bar": "baz"}, + "valid": true + }, + { + "description": "one property invalid is invalid", + "data": {"foo": 1, "bar": {}}, + "valid": false + }, + { + "description": "both properties invalid is invalid", + "data": {"foo": [], "bar": {}}, + "valid": false + }, + { + "description": "doesn't invalidate other properties", + "data": {"quux": []}, + "valid": true + }, + { + "description": "ignores non-objects", + "data": [], + "valid": true + } + ] + }, + { + "description": + "properties, patternProperties, additionalProperties interaction", + "schema": { + "properties": { + "foo": {"type": "array", "maxItems": 3}, + "bar": {"type": "array"} + }, + "patternProperties": {"f.o": {"minItems": 2}}, + "additionalProperties": {"type": "integer"} + }, + "tests": [ + { + "description": "property validates property", + "data": {"foo": [1, 2]}, + "valid": true + }, + { + "description": "property invalidates property", + "data": {"foo": [1, 2, 3, 4]}, + "valid": false + }, + { + "description": "patternProperty invalidates property", + "data": {"foo": []}, + "valid": false + }, + { + "description": "patternProperty validates nonproperty", + "data": {"fxo": [1, 2]}, + "valid": true + }, + { + "description": "patternProperty invalidates nonproperty", + "data": {"fxo": []}, + "valid": false + }, + { + "description": "additionalProperty ignores property", + "data": {"bar": []}, + "valid": true + }, + { + "description": "additionalProperty validates others", + "data": {"quux": 3}, + "valid": true + }, + { + "description": "additionalProperty invalidates others", + "data": {"quux": "foo"}, + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/properties.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/properties.test new file mode 100644 index 00000000..61186f68 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/properties.test @@ -0,0 +1 @@ +[{"fail": false, "data": {"foo": 1, "bar": "baz"}, "name": "object properties validation -- both properties present and valid is valid", "schema": {"properties": {"foo": {"type": "integer"}, "bar": {"type": "string"}}}}, {"fail": true, "data": {"foo": 1, "bar": {}}, "name": "object properties validation -- one property invalid is invalid", "schema": {"properties": {"foo": {"type": "integer"}, "bar": {"type": "string"}}}}, {"fail": true, "data": {"foo": [], "bar": {}}, "name": "object properties validation -- both properties invalid is invalid", "schema": {"properties": {"foo": {"type": "integer"}, "bar": {"type": "string"}}}}, {"fail": false, "data": {"quux": []}, "name": "object properties validation -- doesn't invalidate other properties", "schema": {"properties": {"foo": {"type": "integer"}, "bar": {"type": "string"}}}}, {"fail": false, "data": [], "name": "object properties validation -- ignores non-objects", "schema": {"properties": {"foo": {"type": "integer"}, "bar": {"type": "string"}}}}, {"fail": false, "data": {"foo": [1, 2]}, "name": "properties, patternProperties, additionalProperties interaction -- property validates property", "schema": {"additionalProperties": {"type": "integer"}, "patternProperties": {"f.o": {"minItems": 2}}, "properties": {"foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"}}}}, {"fail": true, "data": {"foo": [1, 2, 3, 4]}, "name": "properties, patternProperties, additionalProperties interaction -- property invalidates property", "schema": {"additionalProperties": {"type": "integer"}, "patternProperties": {"f.o": {"minItems": 2}}, "properties": {"foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"}}}}, {"fail": true, "data": {"foo": []}, "name": "properties, patternProperties, additionalProperties interaction -- patternProperty invalidates property", "schema": {"additionalProperties": {"type": "integer"}, "patternProperties": {"f.o": {"minItems": 2}}, "properties": {"foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"}}}}, {"fail": false, "data": {"fxo": [1, 2]}, "name": "properties, patternProperties, additionalProperties interaction -- patternProperty validates nonproperty", "schema": {"additionalProperties": {"type": "integer"}, "patternProperties": {"f.o": {"minItems": 2}}, "properties": {"foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"}}}}, {"fail": true, "data": {"fxo": []}, "name": "properties, patternProperties, additionalProperties interaction -- patternProperty invalidates nonproperty", "schema": {"additionalProperties": {"type": "integer"}, "patternProperties": {"f.o": {"minItems": 2}}, "properties": {"foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"}}}}, {"fail": false, "data": {"bar": []}, "name": "properties, patternProperties, additionalProperties interaction -- additionalProperty ignores property", "schema": {"additionalProperties": {"type": "integer"}, "patternProperties": {"f.o": {"minItems": 2}}, "properties": {"foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"}}}}, {"fail": false, "data": {"quux": 3}, "name": "properties, patternProperties, additionalProperties interaction -- additionalProperty validates others", "schema": {"additionalProperties": {"type": "integer"}, "patternProperties": {"f.o": {"minItems": 2}}, "properties": {"foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"}}}}, {"fail": true, "data": {"quux": "foo"}, "name": "properties, patternProperties, additionalProperties interaction -- additionalProperty invalidates others", "schema": {"additionalProperties": {"type": "integer"}, "patternProperties": {"f.o": {"minItems": 2}}, "properties": {"foo": {"type": "array", "maxItems": 3}, "bar": {"type": "array"}}}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/ref.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/ref.json new file mode 100644 index 00000000..168f207d --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/ref.json @@ -0,0 +1,123 @@ +[ + { + "description": "root pointer ref", + "schema": { + "properties": { + "foo": {"$ref": "#"} + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "match", + "data": {"foo": false}, + "valid": true + }, + { + "description": "recursive match", + "data": {"foo": {"foo": false}}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": false}, + "valid": false + }, + { + "description": "recursive mismatch", + "data": {"foo": {"bar": false}}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"$ref": "#/properties/foo"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + }, + { + "description": "escaped pointer ref", + "schema": { + "tilda~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"}, + "properties": { + "tilda": {"$ref": "#/tilda~0field"}, + "slash": {"$ref": "#/slash~1field"}, + "percent": {"$ref": "#/percent%25field"} + } + }, + "tests": [ + { + "description": "slash", + "data": {"slash": "aoeu"}, + "valid": false + }, + { + "description": "tilda", + "data": {"tilda": "aoeu"}, + "valid": false + }, + { + "description": "percent", + "data": {"percent": "aoeu"}, + "valid": false + } + ] + }, + { + "description": "nested refs", + "schema": { + "definitions": { + "a": {"type": "integer"}, + "b": {"$ref": "#/definitions/a"}, + "c": {"$ref": "#/definitions/b"} + }, + "$ref": "#/definitions/c" + }, + "tests": [ + { + "description": "nested ref valid", + "data": 5, + "valid": true + }, + { + "description": "nested ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "remote ref, containing refs itself", + "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, + "tests": [ + { + "description": "remote ref valid", + "data": {"minLength": 1}, + "valid": true + }, + { + "description": "remote ref invalid", + "data": {"minLength": -1}, + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/ref.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/ref.test new file mode 100644 index 00000000..ab6631c3 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/ref.test @@ -0,0 +1 @@ +[{"fail": false, "data": {"foo": false}, "name": "root pointer ref -- match", "schema": {"additionalProperties": false, "properties": {"foo": {"$ref": "#"}}}}, {"fail": false, "data": {"foo": {"foo": false}}, "name": "root pointer ref -- recursive match", "schema": {"additionalProperties": false, "properties": {"foo": {"$ref": "#"}}}}, {"fail": true, "data": {"bar": false}, "name": "root pointer ref -- mismatch", "schema": {"additionalProperties": false, "properties": {"foo": {"$ref": "#"}}}}, {"fail": true, "data": {"foo": {"bar": false}}, "name": "root pointer ref -- recursive mismatch", "schema": {"additionalProperties": false, "properties": {"foo": {"$ref": "#"}}}}, {"fail": false, "data": {"bar": 3}, "name": "relative pointer ref -- match", "schema": {"properties": {"foo": {"type": "integer"}, "bar": {"$ref": "#/properties/foo"}}}}, {"fail": true, "data": {"bar": true}, "name": "relative pointer ref -- mismatch", "schema": {"properties": {"foo": {"type": "integer"}, "bar": {"$ref": "#/properties/foo"}}}}, {"fail": true, "data": {"slash": "aoeu"}, "name": "escaped pointer ref -- slash", "schema": {"slash/field": {"type": "integer"}, "tilda~field": {"type": "integer"}, "percent%field": {"type": "integer"}, "properties": {"tilda": {"$ref": "#/tilda~0field"}, "percent": {"$ref": "#/percent%25field"}, "slash": {"$ref": "#/slash~1field"}}}}, {"fail": true, "data": {"tilda": "aoeu"}, "name": "escaped pointer ref -- tilda", "schema": {"slash/field": {"type": "integer"}, "tilda~field": {"type": "integer"}, "percent%field": {"type": "integer"}, "properties": {"tilda": {"$ref": "#/tilda~0field"}, "percent": {"$ref": "#/percent%25field"}, "slash": {"$ref": "#/slash~1field"}}}}, {"fail": true, "data": {"percent": "aoeu"}, "name": "escaped pointer ref -- percent", "schema": {"slash/field": {"type": "integer"}, "tilda~field": {"type": "integer"}, "percent%field": {"type": "integer"}, "properties": {"tilda": {"$ref": "#/tilda~0field"}, "percent": {"$ref": "#/percent%25field"}, "slash": {"$ref": "#/slash~1field"}}}}, {"fail": false, "data": 5, "name": "nested refs -- nested ref valid", "schema": {"definitions": {"a": {"type": "integer"}, "c": {"$ref": "#/definitions/b"}, "b": {"$ref": "#/definitions/a"}}, "$ref": "#/definitions/c"}}, {"fail": true, "data": "a", "name": "nested refs -- nested ref invalid", "schema": {"definitions": {"a": {"type": "integer"}, "c": {"$ref": "#/definitions/b"}, "b": {"$ref": "#/definitions/a"}}, "$ref": "#/definitions/c"}}, {"fail": false, "data": {"minLength": 1}, "name": "remote ref, containing refs itself -- remote ref valid", "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}}, {"fail": true, "data": {"minLength": -1}, "name": "remote ref, containing refs itself -- remote ref invalid", "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/required.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/required.json new file mode 100644 index 00000000..612f73f3 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/required.json @@ -0,0 +1,39 @@ +[ + { + "description": "required validation", + "schema": { + "properties": { + "foo": {}, + "bar": {} + }, + "required": ["foo"] + }, + "tests": [ + { + "description": "present required property is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "non-present required property is invalid", + "data": {"bar": 1}, + "valid": false + } + ] + }, + { + "description": "required default validation", + "schema": { + "properties": { + "foo": {} + } + }, + "tests": [ + { + "description": "not required by default", + "data": {}, + "valid": true + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/required.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/required.test new file mode 100644 index 00000000..c9762a4d --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/required.test @@ -0,0 +1 @@ +[{"fail": false, "data": {"foo": 1}, "name": "required validation -- present required property is valid", "schema": {"required": ["foo"], "properties": {"foo": {}, "bar": {}}}}, {"fail": true, "data": {"bar": 1}, "name": "required validation -- non-present required property is invalid", "schema": {"required": ["foo"], "properties": {"foo": {}, "bar": {}}}}, {"fail": false, "data": {}, "name": "required default validation -- not required by default", "schema": {"properties": {"foo": {}}}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/type.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/type.json new file mode 100644 index 00000000..257f0512 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/type.json @@ -0,0 +1,330 @@ +[ + { + "description": "integer type matches integers", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "an integer is an integer", + "data": 1, + "valid": true + }, + { + "description": "a float is not an integer", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an integer", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an integer", + "data": {}, + "valid": false + }, + { + "description": "an array is not an integer", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an integer", + "data": true, + "valid": false + }, + { + "description": "null is not an integer", + "data": null, + "valid": false + } + ] + }, + { + "description": "number type matches numbers", + "schema": {"type": "number"}, + "tests": [ + { + "description": "an integer is a number", + "data": 1, + "valid": true + }, + { + "description": "a float is a number", + "data": 1.1, + "valid": true + }, + { + "description": "a string is not a number", + "data": "foo", + "valid": false + }, + { + "description": "an object is not a number", + "data": {}, + "valid": false + }, + { + "description": "an array is not a number", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a number", + "data": true, + "valid": false + }, + { + "description": "null is not a number", + "data": null, + "valid": false + } + ] + }, + { + "description": "string type matches strings", + "schema": {"type": "string"}, + "tests": [ + { + "description": "1 is not a string", + "data": 1, + "valid": false + }, + { + "description": "a float is not a string", + "data": 1.1, + "valid": false + }, + { + "description": "a string is a string", + "data": "foo", + "valid": true + }, + { + "description": "an object is not a string", + "data": {}, + "valid": false + }, + { + "description": "an array is not a string", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a string", + "data": true, + "valid": false + }, + { + "description": "null is not a string", + "data": null, + "valid": false + } + ] + }, + { + "description": "object type matches objects", + "schema": {"type": "object"}, + "tests": [ + { + "description": "an integer is not an object", + "data": 1, + "valid": false + }, + { + "description": "a float is not an object", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an object", + "data": "foo", + "valid": false + }, + { + "description": "an object is an object", + "data": {}, + "valid": true + }, + { + "description": "an array is not an object", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an object", + "data": true, + "valid": false + }, + { + "description": "null is not an object", + "data": null, + "valid": false + } + ] + }, + { + "description": "array type matches arrays", + "schema": {"type": "array"}, + "tests": [ + { + "description": "an integer is not an array", + "data": 1, + "valid": false + }, + { + "description": "a float is not an array", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an array", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an array", + "data": {}, + "valid": false + }, + { + "description": "an array is not an array", + "data": [], + "valid": true + }, + { + "description": "a boolean is not an array", + "data": true, + "valid": false + }, + { + "description": "null is not an array", + "data": null, + "valid": false + } + ] + }, + { + "description": "boolean type matches booleans", + "schema": {"type": "boolean"}, + "tests": [ + { + "description": "an integer is not a boolean", + "data": 1, + "valid": false + }, + { + "description": "a float is not a boolean", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not a boolean", + "data": "foo", + "valid": false + }, + { + "description": "an object is not a boolean", + "data": {}, + "valid": false + }, + { + "description": "an array is not a boolean", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a boolean", + "data": true, + "valid": true + }, + { + "description": "null is not a boolean", + "data": null, + "valid": false + } + ] + }, + { + "description": "null type matches only the null object", + "schema": {"type": "null"}, + "tests": [ + { + "description": "an integer is not null", + "data": 1, + "valid": false + }, + { + "description": "a float is not null", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not null", + "data": "foo", + "valid": false + }, + { + "description": "an object is not null", + "data": {}, + "valid": false + }, + { + "description": "an array is not null", + "data": [], + "valid": false + }, + { + "description": "a boolean is not null", + "data": true, + "valid": false + }, + { + "description": "null is null", + "data": null, + "valid": true + } + ] + }, + { + "description": "multiple types can be specified in an array", + "schema": {"type": ["integer", "string"]}, + "tests": [ + { + "description": "an integer is valid", + "data": 1, + "valid": true + }, + { + "description": "a string is valid", + "data": "foo", + "valid": true + }, + { + "description": "a float is invalid", + "data": 1.1, + "valid": false + }, + { + "description": "an object is invalid", + "data": {}, + "valid": false + }, + { + "description": "an array is invalid", + "data": [], + "valid": false + }, + { + "description": "a boolean is invalid", + "data": true, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/type.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/type.test new file mode 100644 index 00000000..d93bceae --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/type.test @@ -0,0 +1 @@ +[{"fail": false, "data": 1, "name": "integer type matches integers -- an integer is an integer", "schema": {"type": "integer"}}, {"fail": true, "data": 1.1000000000000001, "name": "integer type matches integers -- a float is not an integer", "schema": {"type": "integer"}}, {"fail": true, "data": "foo", "name": "integer type matches integers -- a string is not an integer", "schema": {"type": "integer"}}, {"fail": true, "data": {}, "name": "integer type matches integers -- an object is not an integer", "schema": {"type": "integer"}}, {"fail": true, "data": [], "name": "integer type matches integers -- an array is not an integer", "schema": {"type": "integer"}}, {"fail": true, "data": true, "name": "integer type matches integers -- a boolean is not an integer", "schema": {"type": "integer"}}, {"fail": true, "data": null, "name": "integer type matches integers -- null is not an integer", "schema": {"type": "integer"}}, {"fail": false, "data": 1, "name": "number type matches numbers -- an integer is a number", "schema": {"type": "number"}}, {"fail": false, "data": 1.1000000000000001, "name": "number type matches numbers -- a float is a number", "schema": {"type": "number"}}, {"fail": true, "data": "foo", "name": "number type matches numbers -- a string is not a number", "schema": {"type": "number"}}, {"fail": true, "data": {}, "name": "number type matches numbers -- an object is not a number", "schema": {"type": "number"}}, {"fail": true, "data": [], "name": "number type matches numbers -- an array is not a number", "schema": {"type": "number"}}, {"fail": true, "data": true, "name": "number type matches numbers -- a boolean is not a number", "schema": {"type": "number"}}, {"fail": true, "data": null, "name": "number type matches numbers -- null is not a number", "schema": {"type": "number"}}, {"fail": true, "data": 1, "name": "string type matches strings -- 1 is not a string", "schema": {"type": "string"}}, {"fail": true, "data": 1.1000000000000001, "name": "string type matches strings -- a float is not a string", "schema": {"type": "string"}}, {"fail": false, "data": "foo", "name": "string type matches strings -- a string is a string", "schema": {"type": "string"}}, {"fail": true, "data": {}, "name": "string type matches strings -- an object is not a string", "schema": {"type": "string"}}, {"fail": true, "data": [], "name": "string type matches strings -- an array is not a string", "schema": {"type": "string"}}, {"fail": true, "data": true, "name": "string type matches strings -- a boolean is not a string", "schema": {"type": "string"}}, {"fail": true, "data": null, "name": "string type matches strings -- null is not a string", "schema": {"type": "string"}}, {"fail": true, "data": 1, "name": "object type matches objects -- an integer is not an object", "schema": {"type": "object"}}, {"fail": true, "data": 1.1000000000000001, "name": "object type matches objects -- a float is not an object", "schema": {"type": "object"}}, {"fail": true, "data": "foo", "name": "object type matches objects -- a string is not an object", "schema": {"type": "object"}}, {"fail": false, "data": {}, "name": "object type matches objects -- an object is an object", "schema": {"type": "object"}}, {"fail": true, "data": [], "name": "object type matches objects -- an array is not an object", "schema": {"type": "object"}}, {"fail": true, "data": true, "name": "object type matches objects -- a boolean is not an object", "schema": {"type": "object"}}, {"fail": true, "data": null, "name": "object type matches objects -- null is not an object", "schema": {"type": "object"}}, {"fail": true, "data": 1, "name": "array type matches arrays -- an integer is not an array", "schema": {"type": "array"}}, {"fail": true, "data": 1.1000000000000001, "name": "array type matches arrays -- a float is not an array", "schema": {"type": "array"}}, {"fail": true, "data": "foo", "name": "array type matches arrays -- a string is not an array", "schema": {"type": "array"}}, {"fail": true, "data": {}, "name": "array type matches arrays -- an object is not an array", "schema": {"type": "array"}}, {"fail": false, "data": [], "name": "array type matches arrays -- an array is not an array", "schema": {"type": "array"}}, {"fail": true, "data": true, "name": "array type matches arrays -- a boolean is not an array", "schema": {"type": "array"}}, {"fail": true, "data": null, "name": "array type matches arrays -- null is not an array", "schema": {"type": "array"}}, {"fail": true, "data": 1, "name": "boolean type matches booleans -- an integer is not a boolean", "schema": {"type": "boolean"}}, {"fail": true, "data": 1.1000000000000001, "name": "boolean type matches booleans -- a float is not a boolean", "schema": {"type": "boolean"}}, {"fail": true, "data": "foo", "name": "boolean type matches booleans -- a string is not a boolean", "schema": {"type": "boolean"}}, {"fail": true, "data": {}, "name": "boolean type matches booleans -- an object is not a boolean", "schema": {"type": "boolean"}}, {"fail": true, "data": [], "name": "boolean type matches booleans -- an array is not a boolean", "schema": {"type": "boolean"}}, {"fail": false, "data": true, "name": "boolean type matches booleans -- a boolean is not a boolean", "schema": {"type": "boolean"}}, {"fail": true, "data": null, "name": "boolean type matches booleans -- null is not a boolean", "schema": {"type": "boolean"}}, {"fail": true, "data": 1, "name": "null type matches only the null object -- an integer is not null", "schema": {"type": "null"}}, {"fail": true, "data": 1.1000000000000001, "name": "null type matches only the null object -- a float is not null", "schema": {"type": "null"}}, {"fail": true, "data": "foo", "name": "null type matches only the null object -- a string is not null", "schema": {"type": "null"}}, {"fail": true, "data": {}, "name": "null type matches only the null object -- an object is not null", "schema": {"type": "null"}}, {"fail": true, "data": [], "name": "null type matches only the null object -- an array is not null", "schema": {"type": "null"}}, {"fail": true, "data": true, "name": "null type matches only the null object -- a boolean is not null", "schema": {"type": "null"}}, {"fail": false, "data": null, "name": "null type matches only the null object -- null is null", "schema": {"type": "null"}}, {"fail": false, "data": 1, "name": "multiple types can be specified in an array -- an integer is valid", "schema": {"type": ["integer", "string"]}}, {"fail": false, "data": "foo", "name": "multiple types can be specified in an array -- a string is valid", "schema": {"type": ["integer", "string"]}}, {"fail": true, "data": 1.1000000000000001, "name": "multiple types can be specified in an array -- a float is invalid", "schema": {"type": ["integer", "string"]}}, {"fail": true, "data": {}, "name": "multiple types can be specified in an array -- an object is invalid", "schema": {"type": ["integer", "string"]}}, {"fail": true, "data": [], "name": "multiple types can be specified in an array -- an array is invalid", "schema": {"type": ["integer", "string"]}}, {"fail": true, "data": true, "name": "multiple types can be specified in an array -- a boolean is invalid", "schema": {"type": ["integer", "string"]}}, {"fail": true, "data": null, "name": "multiple types can be specified in an array -- null is invalid", "schema": {"type": ["integer", "string"]}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/uniqueItems.json b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/uniqueItems.json new file mode 100644 index 00000000..c1f4ab99 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/uniqueItems.json @@ -0,0 +1,79 @@ +[ + { + "description": "uniqueItems validation", + "schema": {"uniqueItems": true}, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is invalid", + "data": [1, 1], + "valid": false + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": false + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is invalid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": false + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is invalid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": false + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is invalid", + "data": [["foo"], ["foo"]], + "valid": false + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are invalid", + "data": [{}, [1], true, null, {}, 1], + "valid": false + } + ] + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/uniqueItems.test b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/uniqueItems.test new file mode 100644 index 00000000..5ebe141c --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/jsonschema-tests/uniqueItems.test @@ -0,0 +1 @@ +[{"fail": false, "data": [1, 2], "name": "uniqueItems validation -- unique array of integers is valid", "schema": {"uniqueItems": true}}, {"fail": true, "data": [1, 1], "name": "uniqueItems validation -- non-unique array of integers is invalid", "schema": {"uniqueItems": true}}, {"fail": true, "data": [1.0, 1.0, 1], "name": "uniqueItems validation -- numbers are unique if mathematically unequal", "schema": {"uniqueItems": true}}, {"fail": false, "data": [{"foo": "bar"}, {"foo": "baz"}], "name": "uniqueItems validation -- unique array of objects is valid", "schema": {"uniqueItems": true}}, {"fail": true, "data": [{"foo": "bar"}, {"foo": "bar"}], "name": "uniqueItems validation -- non-unique array of objects is invalid", "schema": {"uniqueItems": true}}, {"fail": false, "data": [{"foo": {"bar": {"baz": true}}}, {"foo": {"bar": {"baz": false}}}], "name": "uniqueItems validation -- unique array of nested objects is valid", "schema": {"uniqueItems": true}}, {"fail": true, "data": [{"foo": {"bar": {"baz": true}}}, {"foo": {"bar": {"baz": true}}}], "name": "uniqueItems validation -- non-unique array of nested objects is invalid", "schema": {"uniqueItems": true}}, {"fail": false, "data": [["foo"], ["bar"]], "name": "uniqueItems validation -- unique array of arrays is valid", "schema": {"uniqueItems": true}}, {"fail": true, "data": [["foo"], ["foo"]], "name": "uniqueItems validation -- non-unique array of arrays is invalid", "schema": {"uniqueItems": true}}, {"fail": false, "data": [1, true], "name": "uniqueItems validation -- 1 and true are unique", "schema": {"uniqueItems": true}}, {"fail": false, "data": [0, false], "name": "uniqueItems validation -- 0 and false are unique", "schema": {"uniqueItems": true}}, {"fail": false, "data": [{}, [1], true, null, 1], "name": "uniqueItems validation -- unique heterogeneous types are valid", "schema": {"uniqueItems": true}}, {"fail": true, "data": [{}, [1], true, null, {}, 1], "name": "uniqueItems validation -- non-unique heterogeneous types are invalid", "schema": {"uniqueItems": true}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/negative-unique-items.test b/src/hos_libvariant/src/test/test_schema_data/negative-unique-items.test new file mode 100644 index 00000000..a1d53187 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/negative-unique-items.test @@ -0,0 +1,19 @@ +[ + { + "name": "Negative unique items", + "schema": { + "type": "array", + "uniqueItems": false + }, + "data": [ "a", "b", "a", "c" ] + }, + { + "name": "Negative unique items", + "schema": { + "type": "array", + "uniqueItems": true + }, + "data": [ "a", "b", "a", "c" ], + "fail": true + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/recursion.test b/src/hos_libvariant/src/test/test_schema_data/recursion.test new file mode 100644 index 00000000..30d2e8b4 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/recursion.test @@ -0,0 +1,16 @@ +[ + { + "name": "infinite recursion test", + "schema": { + "definitions": { + "a": { "$ref": "#/definitions/b" }, + "b": { "$ref": "#/definitions/a" } + }, + "properties": { + "a": { "$ref": "#/definitions/a" } + } + }, + "data": { "a": { "a": {} } }, + "fail": true + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/sample-test.test b/src/hos_libvariant/src/test/test_schema_data/sample-test.test new file mode 100644 index 00000000..0ebeb3f4 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/sample-test.test @@ -0,0 +1,78 @@ +[ + { + "name": "sample test", + "schema": { + "$schema": "http://json-schema.org/draft-04/schema", + "type":"object", + "additionalProperties":false, + "properties":{ + "fw": { + "type":"number" + }, + "sw": { + "type":"number" + }, + "repos": { + "type":"object", + "additionalProperties": { + "type":"string" + } + } + }, + "required": ["fw", "sw"] + }, + "data": { + "fw": 21, + "repos": { + "abc1": "f4562e9b588a 109 default tip", + "blah2": "b8a9198883cf 22 default tip", + "arg4": "686bb1a70728 1043 default tip lwlcca-development", + "mmmooo": "heads/lwlcca-0-ge679eade196c", + "aaaaaa": "ac7006fded4e 519 default tip", + "....s;iodufhaj": "1e63ee2e1813 568 default tip", + "ufksdid": "b563665d4a02 17 default tip", + "naaa": "5a7cd1abfd8e 59 default tip" + }, + "sw": 21 + } + }, + { + "name": "sample test - failure", + "schema": { + "$schema": "http://json-schema.org/draft-04/schema", + "type":"object", + "additionalProperties":false, + "properties":{ + "fw": { + "type":"number" + }, + "sw": { + "type":"number" + }, + "repos": { + "type":"object", + "additionalProperties": { + "type":"string" + } + } + }, + "required": ["fw", "sw"] + }, + "data": { + "fw": 21, + "repos": { + "abc1": "f4562e9b588a 109 default tip", + "blah2": "b8a9198883cf 22 default tip", + "arg4": "686bb1a70728 1043 default tip lwlcca-development", + "mmmooo": "heads/lwlcca-0-ge679eade196c", + "aaaaaa": "ac7006fded4e 519 default tip", + "....s;iodufhaj": "1e63ee2e1813 568 default tip", + "ufksdid": "b563665d4a02 17 default tip", + "naaa": "5a7cd1abfd8e 59 default tip", + "foo": 21 + }, + "sw": 21 + }, + "fail": true + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/simple-test-fail.json b/src/hos_libvariant/src/test/test_schema_data/simple-test-fail.json new file mode 100644 index 00000000..5267a612 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/simple-test-fail.json @@ -0,0 +1,13 @@ +{ + "fw": 21, + "repos": { + "abc1": "f4562e9b588a 109 default tip", + "blah2": "b8a9198883cf 22 default tip", + "arg4": "686bb1a70728 1043 default tip lwlcca-development", + "mmmooo": "heads/lwlcca-0-ge679eade196c", + "aaaaaa": "ac7006fded4e 519 default tip", + "....s;iodufhaj": "1e63ee2e1813 568 default tip", + "ufksdid": "b563665d4a02 17 default tip", + "naaa": "5a7cd1abfd8e 59 default tip" + } +} diff --git a/src/hos_libvariant/src/test/test_schema_data/simple-test-schema.json b/src/hos_libvariant/src/test/test_schema_data/simple-test-schema.json new file mode 100644 index 00000000..c3d98d9c --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/simple-test-schema.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema", + "type":"object", + "additionalProperties":false, + "properties":{ + "fw": { + "type":"number" + }, + "sw": { + "type":"number" + }, + "repos": { + "type":"object", + "additionalProperties": { + "type":"string" + } + } + }, + "required": ["fw", "sw"] +} diff --git a/src/hos_libvariant/src/test/test_schema_data/simple-test.json b/src/hos_libvariant/src/test/test_schema_data/simple-test.json new file mode 100644 index 00000000..38f8eeb9 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/simple-test.json @@ -0,0 +1,14 @@ +{ + "fw": 21, + "repos": { + "abc1": "f4562e9b588a 109 default tip", + "blah2": "b8a9198883cf 22 default tip", + "arg4": "686bb1a70728 1043 default tip lwlcca-development", + "mmmooo": "heads/lwlcca-0-ge679eade196c", + "aaaaaa": "ac7006fded4e 519 default tip", + "....s;iodufhaj": "1e63ee2e1813 568 default tip", + "ufksdid": "b563665d4a02 17 default tip", + "naaa": "5a7cd1abfd8e 59 default tip" + }, + "sw": 21 +} diff --git a/src/hos_libvariant/src/test/test_schema_data/test_resolveuri.json b/src/hos_libvariant/src/test/test_schema_data/test_resolveuri.json new file mode 100644 index 00000000..3e59369b --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/test_resolveuri.json @@ -0,0 +1,203 @@ +[ +/* These tests where taken verbatim from: +// http://skew.org/uri/uri_tests.html#absoluteizeURI +// They are in the format of reference, base, expected result +// ends in a empty string +These where then modified for the slightly different behavior we want +regarding .. segments. +*/ +"","http://example.com/path?query#frag","http://example.com/path?query", +"../c","foo:a/b","foo:c", +"foo:.","foo:a","foo:", +"/foo/../../../bar","zz:abc","zz:/bar", +"/foo/../bar","zz:abc","zz:/bar", +"foo/../../../bar","zz:abc","zz:bar", +"foo/../bar","zz:abc","zz:bar", +"zz:.","zz:abc","zz:", +"/.","http://a/b/c/d;p?q","http://a/", +"/.foo","http://a/b/c/d;p?q","http://a/.foo", +".foo","http://a/b/c/d;p?q","http://a/b/c/.foo", +"g:h","http://a/b/c/d;p?q","g:h", +"g","http://a/b/c/d;p?q","http://a/b/c/g", +"./g","http://a/b/c/d;p?q","http://a/b/c/g", +"g/","http://a/b/c/d;p?q","http://a/b/c/g/", +"/g","http://a/b/c/d;p?q","http://a/g", +"//g","http://a/b/c/d;p?q","http://g", +"?y","http://a/b/c/d;p?q","http://a/b/c/d;p?y", +"g?y","http://a/b/c/d;p?q","http://a/b/c/g?y", +"#s","http://a/b/c/d;p?q","http://a/b/c/d;p?q#s", +"g#s","http://a/b/c/d;p?q","http://a/b/c/g#s", +"g?y#s","http://a/b/c/d;p?q","http://a/b/c/g?y#s", +";x","http://a/b/c/d;p?q","http://a/b/c/;x", +"g;x","http://a/b/c/d;p?q","http://a/b/c/g;x", +"g;x?y#s","http://a/b/c/d;p?q","http://a/b/c/g;x?y#s", +"","http://a/b/c/d;p?q","http://a/b/c/d;p?q", +".","http://a/b/c/d;p?q","http://a/b/c/", +"./","http://a/b/c/d;p?q","http://a/b/c/", +"..","http://a/b/c/d;p?q","http://a/b/", +"../","http://a/b/c/d;p?q","http://a/b/", +"../g","http://a/b/c/d;p?q","http://a/b/g", +"../..","http://a/b/c/d;p?q","http://a/", +"../../","http://a/b/c/d;p?q","http://a/", +"../../g","http://a/b/c/d;p?q","http://a/g", +"../../../g","http://a/b/c/d;p?q","http://a/../g", +"../../../../g","http://a/b/c/d;p?q","http://a/g", +"/./g","http://a/b/c/d;p?q","http://a/g", +"/../g","http://a/b/c/d;p?q","http://a/../g", +"g.","http://a/b/c/d;p?q","http://a/b/c/g.", +".g","http://a/b/c/d;p?q","http://a/b/c/.g", +"g..","http://a/b/c/d;p?q","http://a/b/c/g..", +"..g","http://a/b/c/d;p?q","http://a/b/c/..g", +"./../g","http://a/b/c/d;p?q","http://a/b/g", +"./g/.","http://a/b/c/d;p?q","http://a/b/c/g/", +"g/./h","http://a/b/c/d;p?q","http://a/b/c/g/h", +"g/../h","http://a/b/c/d;p?q","http://a/b/c/h", +"g;x=1/./y","http://a/b/c/d;p?q","http://a/b/c/g;x=1/y", +"g;x=1/../y","http://a/b/c/d;p?q","http://a/b/c/y", +"g?y/./x","http://a/b/c/d;p?q","http://a/b/c/g?y/./x", +"g?y/../x","http://a/b/c/d;p?q","http://a/b/c/g?y/../x", +"g#s/./x","http://a/b/c/d;p?q","http://a/b/c/g#s/./x", +"g#s/../x","http://a/b/c/d;p?q","http://a/b/c/g#s/../x", +"http:g","http://a/b/c/d;p?q","http:g", +"http:","http://a/b/c/d;p?q","http:", +"/a/b/c/./../../g","http://a/b/c/d;p?q","http://a/a/g", +"g","http://a/b/c/d;p?q=1/2","http://a/b/c/g", +"./g","http://a/b/c/d;p?q=1/2","http://a/b/c/g", +"g/","http://a/b/c/d;p?q=1/2","http://a/b/c/g/", +"/g","http://a/b/c/d;p?q=1/2","http://a/g", +"//g","http://a/b/c/d;p?q=1/2","http://g", +"?y","http://a/b/c/d;p?q=1/2","http://a/b/c/d;p?y", +"g?y","http://a/b/c/d;p?q=1/2","http://a/b/c/g?y", +"g?y/./x","http://a/b/c/d;p?q=1/2","http://a/b/c/g?y/./x", +"g?y/../x","http://a/b/c/d;p?q=1/2","http://a/b/c/g?y/../x", +"g#s","http://a/b/c/d;p?q=1/2","http://a/b/c/g#s", +"g#s/./x","http://a/b/c/d;p?q=1/2","http://a/b/c/g#s/./x", +"g#s/../x","http://a/b/c/d;p?q=1/2","http://a/b/c/g#s/../x", +"./","http://a/b/c/d;p?q=1/2","http://a/b/c/", +"../","http://a/b/c/d;p?q=1/2","http://a/b/", +"../g","http://a/b/c/d;p?q=1/2","http://a/b/g", +"../../","http://a/b/c/d;p?q=1/2","http://a/", +"../../g","http://a/b/c/d;p?q=1/2","http://a/g", +"g","http://a/b/c/d;p=1/2?q","http://a/b/c/d;p=1/g", +"./g","http://a/b/c/d;p=1/2?q","http://a/b/c/d;p=1/g", +"g/","http://a/b/c/d;p=1/2?q","http://a/b/c/d;p=1/g/", +"g?y","http://a/b/c/d;p=1/2?q","http://a/b/c/d;p=1/g?y", +";x","http://a/b/c/d;p=1/2?q","http://a/b/c/d;p=1/;x", +"g;x","http://a/b/c/d;p=1/2?q","http://a/b/c/d;p=1/g;x", +"g;x=1/./y","http://a/b/c/d;p=1/2?q","http://a/b/c/d;p=1/g;x=1/y", +"g;x=1/../y","http://a/b/c/d;p=1/2?q","http://a/b/c/d;p=1/y", +"./","http://a/b/c/d;p=1/2?q","http://a/b/c/d;p=1/", +"../","http://a/b/c/d;p=1/2?q","http://a/b/c/", +"../g","http://a/b/c/d;p=1/2?q","http://a/b/c/g", +"../../","http://a/b/c/d;p=1/2?q","http://a/b/", +"../../g","http://a/b/c/d;p=1/2?q","http://a/b/g", +"g:h","fred:///s//a/b/c","g:h", +"g","fred:///s//a/b/c","fred:///s//a/b/g", +"./g","fred:///s//a/b/c","fred:///s//a/b/g", +"g/","fred:///s//a/b/c","fred:///s//a/b/g/", +"/g","fred:///s//a/b/c","fred:///g", +"//g","fred:///s//a/b/c","fred://g", +"//g/x","fred:///s//a/b/c","fred://g/x", +"///g","fred:///s//a/b/c","fred:///g", +"./","fred:///s//a/b/c","fred:///s//a/b/", +"../","fred:///s//a/b/c","fred:///s//a/", +"../g","fred:///s//a/b/c","fred:///s//a/g", +"../../","fred:///s//a/b/c","fred:///s//", +"../../g","fred:///s//a/b/c","fred:///s//g", +"../../../g","fred:///s//a/b/c","fred:///s/g", +"../../../../g","fred:///s//a/b/c","fred:///g", +"g:h","http:///s//a/b/c","g:h", +"g","http:///s//a/b/c","http:///s//a/b/g", +"./g","http:///s//a/b/c","http:///s//a/b/g", +"g/","http:///s//a/b/c","http:///s//a/b/g/", +"/g","http:///s//a/b/c","http:///g", +"//g","http:///s//a/b/c","http://g", +"//g/x","http:///s//a/b/c","http://g/x", +"///g","http:///s//a/b/c","http:///g", +"./","http:///s//a/b/c","http:///s//a/b/", +"../","http:///s//a/b/c","http:///s//a/", +"../g","http:///s//a/b/c","http:///s//a/g", +"../../","http:///s//a/b/c","http:///s//", +"../../g","http:///s//a/b/c","http:///s//g", +"../../../g","http:///s//a/b/c","http:///s/g", +"../../../../g","http:///s//a/b/c","http:///g", +"bar:abc","foo:xyz","bar:abc", +"../abc","http://example/x/y/z","http://example/x/abc", +"http://example/x/abc","http://example2/x/y/z","http://example/x/abc", +"../r","http://ex/x/y/z","http://ex/x/r", +"q/r","http://ex/x/y","http://ex/x/q/r", +"q/r#s","http://ex/x/y","http://ex/x/q/r#s", +"q/r#s/t","http://ex/x/y","http://ex/x/q/r#s/t", +"ftp://ex/x/q/r","http://ex/x/y","ftp://ex/x/q/r", +"","http://ex/x/y","http://ex/x/y", +"","http://ex/x/y/","http://ex/x/y/", +"","http://ex/x/y/pdq","http://ex/x/y/pdq", +"z/","http://ex/x/y/","http://ex/x/y/z/", +"#Animal","file:/swap/test/animal.rdf","file:/swap/test/animal.rdf#Animal", +"../abc","file:/e/x/y/z","file:/e/x/abc", +"/example/x/abc","file:/example2/x/y/z","file:/example/x/abc", +"../r","file:/ex/x/y/z","file:/ex/x/r", +"/r","file:/ex/x/y/z","file:/r", +"q/r","file:/ex/x/y","file:/ex/x/q/r", +"q/r#s","file:/ex/x/y","file:/ex/x/q/r#s", +"q/r#","file:/ex/x/y","file:/ex/x/q/r#", +"q/r#s/t","file:/ex/x/y","file:/ex/x/q/r#s/t", +"ftp://ex/x/q/r","file:/ex/x/y","ftp://ex/x/q/r", +"","file:/ex/x/y","file:/ex/x/y", +"","file:/ex/x/y/","file:/ex/x/y/", +"","file:/ex/x/y/pdq","file:/ex/x/y/pdq", +"z/","file:/ex/x/y/","file:/ex/x/y/z/", +"file://meetings.example.com/cal#m1","file:/devel/WWW/2000/10/swap/test/reluri-1.n3","file://meetings.example.com/cal#m1", +"file://meetings.example.com/cal#m1","file:/home/connolly/w3ccvs/WWW/2000/10/swap/test/reluri-1.n3","file://meetings.example.com/cal#m1", +"./#blort","file:/some/dir/foo","file:/some/dir/#blort", +"./#","file:/some/dir/foo","file:/some/dir/#", +"./","http://example/x/abc.efg","http://example/x/", +"//example/x/abc","http://example2/x/y/z","http://example/x/abc", +"/r","http://ex/x/y/z","http://ex/r", +"./q:r","http://ex/x/y","http://ex/x/q:r", +"./p=q:r","http://ex/x/y","http://ex/x/p=q:r", +"?pp/rr","http://ex/x/y?pp/qq","http://ex/x/y?pp/rr", +"y/z","http://ex/x/y?pp/qq","http://ex/x/y/z", +"local/qual@domain.org#frag","mailto:local","mailto:local/qual@domain.org#frag", +"more/qual2@domain2.org#frag","mailto:local/qual1@domain1.org","mailto:local/more/qual2@domain2.org#frag", +"y?q","http://ex/x/y?q","http://ex/x/y?q", +"/x/y?q","http://ex?p","http://ex/x/y?q", +"c/d","foo:a/b","foo:a/c/d", +"/c/d","foo:a/b","foo:/c/d", +"","foo:a/b?c#d","foo:a/b?c", +"b/c","foo:a","foo:b/c", +"../b/c","foo:/a/y/z","foo:/a/b/c", +"./b/c","foo:a","foo:b/c", +"/./b/c","foo:a","foo:/b/c", +"../../d","foo://a//b/c","foo://a/d", +".","foo:a","foo:", +"..","foo:a","foo:..", +"abc","http://example/x/y%2Fz","http://example/x/abc", +"../../x%2Fabc","http://example/a/x/y/z","http://example/a/x%2Fabc", +"../x%2Fabc","http://example/a/x/y%2Fz","http://example/a/x%2Fabc", +"abc","http://example/x%2Fy/z","http://example/x%2Fy/abc", +"q%3Ar","http://ex/x/y","http://ex/x/q%3Ar", +"/x%2Fabc","http://example/x/y%2Fz","http://example/x%2Fabc", +"/x%2Fabc","http://example/x/y/z","http://example/x%2Fabc", +"local2@domain2","mailto:local1@domain1?query1","mailto:local2@domain2", +"local2@domain2?query2","mailto:local1@domain1","mailto:local2@domain2?query2", +"local2@domain2?query2","mailto:local1@domain1?query1","mailto:local2@domain2?query2", +"?query2","mailto:local@domain?query1","mailto:local@domain?query2", +"local@domain?query2","mailto:?query1","mailto:local@domain?query2", +"?query2","mailto:local@domain?query1","mailto:local@domain?query2", +"http://example/a/b?c/../d","foo:bar","http://example/a/b?c/../d", +"http://example/a/b#c/../d","foo:bar","http://example/a/b#c/../d", +"http:this","http://example.org/base/uri","http:this", +"http:this","http:base","http:this", +".//g","f:/a","f://g", +"b/c//d/e","f://example.org/base/a","f://example.org/base/b/c//d/e", +"m2@example.ord/c2@example.org","mid:m@example.ord/c@example.org","mid:m@example.ord/m2@example.ord/c2@example.org", +"mini1.xml","file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/","file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/mini1.xml", +"../b/c","foo:a/y/z","foo:a/b/c", +"b","foo:","foo:b", +"b","foo://a","foo://a/b", +"b","foo://a?q","foo://a/b", +"b?q","foo://a","foo://a/b?q", +"b?q","foo://a?r","foo://a/b?q", +"", "", "" +] diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/01-type.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/01-type.test new file mode 100644 index 00000000..78c4d842 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/01-type.test @@ -0,0 +1,46 @@ +[ + { + "name": "no type specified", + "data": {}, + "schema": {} + }, + { + "name": "must be object, is object", + "data": {}, + "schema": { "type": "object" } + }, + { + "name": "must be object or string, is object", + "data": {}, + "schema": { "type": ["object", "string"] } + }, + { + "name": "must be object or string, is array", + "data": [], + "schema": { "type": ["object", "string"] }, + "fail": true + }, + { + "name": "must be array, is object", + "data": {}, + "schema": { "type": ["array"] }, + "fail": true + }, + { + "name": "must be string, is integer", + "data": 5, + "schema": {"type": ["string"] }, + "fail": true + }, + { + "name": "must be object, is null", + "data": null, + "schema": { "type": ["object"] }, + "fail": true + }, + { + "name": "must be null, is null", + "data": null, + "schema": { "type": "null" } + } +] diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/02-enum.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/02-enum.test new file mode 100644 index 00000000..c8c533b1 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/02-enum.test @@ -0,0 +1 @@ +[{"data": 1, "name": "enum [1], was 1", "schema": {"enum": [1]}}, {"fail": true, "data": "1", "name": "enum[1], was \"1\"", "schema": {"enum": [1]}}, {"data": {}, "name": "enum [{}], was {}", "schema": {"enum": [{}]}}, {"fail": true, "data": {}, "name": "enum [{\"key\":\"value\"}], was {}", "schema": {"enum": [{"key": "value"}]}}, {"fail": false, "data": {"key": "value"}, "name": "enum [{\"key\":\"value\", was {\"key\": \"value\"}", "schema": {"enum": [{"key": "value"}]}}, {"fail": false, "data": [1, true, 0], "name": "Enum with array value - success", "schema": {"enum": [[1, true, 0], 5, {}]}}, {"fail": true, "data": [1, true, 0, 5], "name": "Enum with array value - failure 1", "schema": {"enum": [[1, true, 0], 5, {}]}}, {"fail": true, "data": [1, true, 5], "name": "Enum with array value - failure 2", "schema": {"enum": [[1, true, 0], 5, {}]}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/02-enum.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/02-enum.yaml new file mode 100644 index 00000000..f8f3d20b --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/02-enum.yaml @@ -0,0 +1,30 @@ +- name: enum [1], was 1 + data: 1 + schema: { enum: [1] } +- name: enum[1], was "1" + data: "1" + schema: { enum: [1] } + fail: true +- name: enum [{}], was {} + data: {} + schema: { enum: [{}] } +- name: enum [{"key":"value"}], was {} + data: {} + schema: { enum: [{ key: value}] } + fail: true +- name: 'enum [{"key":"value", was {"key": "value"}' + data: { key: value } + schema: { enum: [{ key: value }] } + fail: false +- name: Enum with array value - success + data: [ 1, true, 0] + schema: { enum: [[1, true, 0], 5, {}] } + fail: false +- name: Enum with array value - failure 1 + data: [1, true, 0, 5] + schema: { enum: [[1, true, 0], 5, {}] } + fail: true +- name: Enum with array value - failure 2 + data: [1, true, 5] + schema: { enum: [[1, true, 0], 5, {}] } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/Makefile b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/Makefile new file mode 100644 index 00000000..91c369e5 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/01-any-type/Makefile @@ -0,0 +1,5 @@ + +tests: 02-enum.test + +02-enum.test: 02-enum.yaml + python -c "import json; import yaml; import sys; json.dump(yaml.load(sys.stdin), sys.stdout);" < $< > $@ diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/01-min-max.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/01-min-max.test new file mode 100644 index 00000000..45f121dd --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/01-min-max.test @@ -0,0 +1 @@ +[{"data": 5, "name": "minimum success", "schema": {"minimum": 2.5}}, {"fail": true, "data": 5, "name": "minimum failure", "schema": {"minimum": 7}}, {"data": 5, "name": "minimum equality success", "schema": {"minimum": 5}}, {"fail": true, "data": 5, "name": "minimum equality failure", "schema": {"minimum": 5, "exclusiveMinimum": true}}, {"data": 5, "name": "maximum success", "schema": {"maximum": 7}}, {"fail": true, "data": -5, "name": "maximum failure", "schema": {"maximum": -7}}, {"data": 5, "name": "exclusive maximum success", "schema": {"maximum": 5}}, {"fail": true, "data": 5, "name": "exclusive maximum failure", "schema": {"exclusiveMaximum": true, "maximum": 5}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/01-min-max.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/01-min-max.yaml new file mode 100644 index 00000000..89390321 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/01-min-max.yaml @@ -0,0 +1,28 @@ +- name: minimum success + data: 5 + schema: { minimum: 2.5 } +- name: minimum failure + data: 5 + schema: { minimum: 7 } + fail: true +- name: minimum equality success + data: 5 + schema: { minimum: 5 } +- name: minimum equality failure + data: 5 + schema: { minimum: 5, exclusiveMinimum: true } + fail: true +- name: maximum success + data: 5 + schema: { maximum: 7 } +- name: maximum failure + data: -5 + schema: { maximum: -7 } + fail: true +- name: exclusive maximum success + data: 5 + schema: { maximum: 5 } +- name: exclusive maximum failure + data: 5 + schema: { maximum: 5, exclusiveMaximum: true } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/02-multipleOf.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/02-multipleOf.test new file mode 100644 index 00000000..f7b0e24a --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/02-multipleOf.test @@ -0,0 +1 @@ +[{"data": 5, "name": "multipleOf", "schema": {"multipleOf": 2.5}}, {"fail": true, "data": 5, "name": "multipleOf failure", "schema": {"multipleOf": 0.75}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/02-multipleOf.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/02-multipleOf.yaml new file mode 100644 index 00000000..ba0fc6aa --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/02-multipleOf.yaml @@ -0,0 +1,7 @@ +- name: multipleOf + data: 5 + schema: { multipleOf: 2.5 } +- name: multipleOf failure + data: 5 + schema: { multipleOf: 0.75 } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/Makefile b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/Makefile new file mode 100644 index 00000000..a4899796 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/02-numeric/Makefile @@ -0,0 +1,9 @@ + +TARGETS := $(patsubst %.yaml,%.test,$(wildcard *.yaml)) + +tests: $(TARGETS) + + +%.test: %.yaml + python -c "import json; import yaml; import sys; json.dump(yaml.load(sys.stdin), sys.stdout);" < $< > $@ + diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/01-min-max-length.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/01-min-max-length.test new file mode 100644 index 00000000..ba630590 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/01-min-max-length.test @@ -0,0 +1 @@ +[{"data": "test", "name": "no length constraints", "schema": {}}, {"data": "test", "name": "minimum length success", "schema": {"minLength": 3}}, {"fail": true, "data": "test", "name": "min length failure", "schema": {"minLength": 5}}, {"data": "test1234", "name": "maximum length success", "schema": {"maxLength": 10}}, {"fail": true, "data": "test1234", "name": "maximum length failure", "schema": {"maxLength": 5}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/01-min-max-length.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/01-min-max-length.yaml new file mode 100644 index 00000000..c32d4c70 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/01-min-max-length.yaml @@ -0,0 +1,17 @@ +- name: no length constraints + data: test + schema: {} +- name: minimum length success + data: test + schema: { minLength: 3 } +- name: min length failure + data: test + schema: { minLength: 5 } + fail: true +- name: maximum length success + data: test1234 + schema: { maxLength: 10 } +- name: maximum length failure + data: test1234 + schema: { maxLength: 5 } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/02-pattern.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/02-pattern.test new file mode 100644 index 00000000..5ac7fa12 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/02-pattern.test @@ -0,0 +1 @@ +[{"data": "9test", "name": "pattern success", "schema": {"pattern": "^[0-9][a-zA-Z]*$"}}, {"fail": true, "data": "9test9", "name": "pattern failure", "schema": {"pattern": "^[0-9][a-zA-Z]*$"}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/02-pattern.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/02-pattern.yaml new file mode 100644 index 00000000..bfe04876 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/02-pattern.yaml @@ -0,0 +1,7 @@ +- name: pattern success + data: 9test + schema: { pattern: "^[0-9][a-zA-Z]*$" } +- name: pattern failure + data: 9test9 + schema: { pattern: "^[0-9][a-zA-Z]*$" } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/Makefile b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/Makefile new file mode 100644 index 00000000..a4899796 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/03-strings/Makefile @@ -0,0 +1,9 @@ + +TARGETS := $(patsubst %.yaml,%.test,$(wildcard *.yaml)) + +tests: $(TARGETS) + + +%.test: %.yaml + python -c "import json; import yaml; import sys; json.dump(yaml.load(sys.stdin), sys.stdout);" < $< > $@ + diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/01-min-max-length.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/01-min-max-length.test new file mode 100644 index 00000000..c7369388 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/01-min-max-length.test @@ -0,0 +1 @@ +[{"data": [1, 2, 3], "name": "no length contraints", "schema": {}}, {"data": [1, 2, 3], "name": "minimum length success", "schema": {"minItems": 3}}, {"fail": true, "data": [1, 2, 3], "name": "minimum length failure", "schema": {"minItems": 5}}, {"data": [1, 2, 3, 4, 5], "name": "maximum length success", "schema": {"maxItems": 10}}, {"fail": true, "data": [1, 2, 3, 4, 5], "name": "maximum length failure", "schema": {"maxItems": 3}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/01-min-max-length.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/01-min-max-length.yaml new file mode 100644 index 00000000..a399502c --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/01-min-max-length.yaml @@ -0,0 +1,17 @@ +- name: no length contraints + data: [1,2,3] + schema: {} +- name: minimum length success + data: [1,2,3] + schema: { minItems: 3 } +- name: minimum length failure + data: [1,2,3] + schema: { minItems: 5 } + fail: true +- name: maximum length success + data: [1,2,3,4,5] + schema: { maxItems: 10 } +- name: maximum length failure + data: [1,2,3,4,5] + schema: { maxItems: 3 } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/02-uniqueitems.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/02-uniqueitems.test new file mode 100644 index 00000000..30ee13a0 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/02-uniqueitems.test @@ -0,0 +1 @@ +[{"data": [1, true, "1"], "name": "uniqueItems success", "schema": {"uniqueItems": true}}, {"fail": true, "data": [1, true, "1", 1], "name": "uniqueItems failure", "schema": {"uniqueItems": true}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/02-uniqueitems.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/02-uniqueitems.yaml new file mode 100644 index 00000000..8cf319c4 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/02-uniqueitems.yaml @@ -0,0 +1,7 @@ +- name: uniqueItems success + data: [1, true, "1"] + schema: { uniqueItems: true } +- name: uniqueItems failure + data: [1, true, "1", 1] + schema: { uniqueItems: true } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/03-items-plain.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/03-items-plain.test new file mode 100644 index 00000000..bf60b9b9 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/03-items-plain.test @@ -0,0 +1 @@ +[{"data": [1, 2, 3, 4], "name": "plain item success", "schema": {"items": {"type": "integer"}}}, {"fail": true, "data": [1, 2, true, 4], "name": "plain item failure", "schema": {"items": {"type": "integer"}}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/03-items-plain.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/03-items-plain.yaml new file mode 100644 index 00000000..16930d55 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/03-items-plain.yaml @@ -0,0 +1,7 @@ +- name: plain item success + data: [1,2,3,4] + schema: { items: { type: integer } } +- name: plain item failure + data: [1,2,true,4] + schema: { items: { type: integer } } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/04-items-tuple-typing.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/04-items-tuple-typing.test new file mode 100644 index 00000000..77084821 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/04-items-tuple-typing.test @@ -0,0 +1 @@ +[{"data": [1, true, "one"], "name": "items success", "schema": {"items": [{"type": "integer"}, {"type": "boolean"}]}}, {"fail": true, "data": [1, null, "one"], "name": "items failure", "schema": {"items": [{"type": "integer"}, {"type": "boolean"}]}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/04-items-tuple-typing.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/04-items-tuple-typing.yaml new file mode 100644 index 00000000..89850307 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/04-items-tuple-typing.yaml @@ -0,0 +1,7 @@ +- name: items success + data: [1, true, "one"] + schema: { items: [ { type: integer} , { type: boolean } ] } +- name: items failure + data: [1, null, "one"] + schema: { items: [ { type: integer} , { type: boolean } ] } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/05-additionalitems.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/05-additionalitems.test new file mode 100644 index 00000000..f7c59a57 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/05-additionalitems.test @@ -0,0 +1 @@ +[{"data": [1, true, "one", "uno"], "name": "additional items schema success", "schema": {"items": [{"type": "integer"}, {"type": "boolean"}], "additionalItems": {"type": "string"}}}, {"fail": true, "data": [1, true, "one", 1], "name": "additional items schema failure", "schema": {"items": [{"type": "integer"}, {"type": "boolean"}], "additionalItems": {"type": "string"}}}, {"data": [1, true, "one", "uno"], "name": "additional items boolean success", "schema": {"items": [{"type": "integer"}, {"type": "boolean"}], "additionalItems": true}}, {"fail": true, "data": [1, true, "one", "uno"], "name": "additional items boolean failure", "schema": {"items": [{"type": "integer"}, {"type": "boolean"}], "additionalItems": false}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/05-additionalitems.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/05-additionalitems.yaml new file mode 100644 index 00000000..ee6ad935 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/05-additionalitems.yaml @@ -0,0 +1,31 @@ +- name: additional items schema success + data: [1, true, "one", "uno"] + schema: + items: + - type: integer + - type: boolean + additionalItems: { type: string } +- name: additional items schema failure + data: [1, true, "one", 1] + schema: + items: + - type: integer + - type: boolean + additionalItems: { type: string } + fail: true +- name: additional items boolean success + data: [1, true, "one", "uno"] + schema: + items: + - type: integer + - type: boolean + additionalItems: true +- name: additional items boolean failure + data: [1, true, "one", "uno"] + schema: + items: + - type: integer + - type: boolean + additionalItems: false + fail: true + diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/Makefile b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/Makefile new file mode 100644 index 00000000..a4899796 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/04-arrays/Makefile @@ -0,0 +1,9 @@ + +TARGETS := $(patsubst %.yaml,%.test,$(wildcard *.yaml)) + +tests: $(TARGETS) + + +%.test: %.yaml + python -c "import json; import yaml; import sys; json.dump(yaml.load(sys.stdin), sys.stdout);" < $< > $@ + diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/01-min-max-properties.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/01-min-max-properties.test new file mode 100644 index 00000000..9eecafed --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/01-min-max-properties.test @@ -0,0 +1 @@ +[{"data": {"key3": 3, "key2": 2, "key": 1}, "name": "minimum length success", "schema": {"minProperties": 3}}, {"fail": true, "data": {"key3": 3, "key2": 2, "key": 1}, "name": "minimum length failure", "schema": {"minProperties": 5}}, {"data": {"key3": 3, "key2": 2, "key": 1}, "name": "maximum length success", "schema": {"maxProperties": 5}}, {"fail": true, "data": {"key3": 3, "key2": 2, "key": 1}, "name": "maximum length failure", "schema": {"maxProperties": 2}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/01-min-max-properties.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/01-min-max-properties.yaml new file mode 100644 index 00000000..01151718 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/01-min-max-properties.yaml @@ -0,0 +1,14 @@ +- name: minimum length success + data: { key: 1, key2: 2, key3: 3 } + schema: { minProperties: 3 } +- name: minimum length failure + data: { key: 1, key2: 2, key3: 3 } + schema: { minProperties: 5 } + fail: true +- name: maximum length success + data: { key: 1, key2: 2, key3: 3 } + schema: { maxProperties: 5 } +- name: maximum length failure + data: { key: 1, key2: 2, key3: 3 } + schema: { maxProperties: 2 } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/02-required.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/02-required.test new file mode 100644 index 00000000..c33d9b7d --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/02-required.test @@ -0,0 +1 @@ +[{"data": {"key3": 3, "key2": 2, "key1": 1}, "name": "required success", "schema": {"required": ["key1", "key2"]}}, {"fail": true, "data": {"key3": 3, "key2": 2, "key1": 1}, "name": "required failure", "schema": {"required": ["key1", "notDefined"]}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/02-required.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/02-required.yaml new file mode 100644 index 00000000..0acc7e51 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/02-required.yaml @@ -0,0 +1,7 @@ +- name: required success + data: { key1: 1, key2: 2, key3: 3 } + schema: { required: [ key1, key2 ] } +- name: required failure + data: { key1: 1, key2: 2, key3: 3 } + schema: { required: [ key1, notDefined ] } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/03-properties.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/03-properties.test new file mode 100644 index 00000000..84cd7400 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/03-properties.test @@ -0,0 +1 @@ +[{"data": {"stringKey": "one", "intKey": 1}, "name": "properties success", "schema": {"properties": {"stringKey": {"type": "string"}, "intKey": {"type": "integer"}}}}, {"fail": true, "data": {"stringKey": false, "intKey": 1}, "name": "properties failure", "schema": {"properties": {"stringKey": {"type": "string"}, "intKey": {"type": "integer"}}}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/03-properties.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/03-properties.yaml new file mode 100644 index 00000000..024d09eb --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/03-properties.yaml @@ -0,0 +1,13 @@ +- name: properties success + data: { intKey: 1, stringKey: "one" } + schema: + properties: + intKey: { type: integer } + stringKey: { type: string } +- name: properties failure + data: { intKey: 1, stringKey: false } + schema: + properties: + intKey: { type: integer } + stringKey: { type: string } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/04-patternproperties.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/04-patternproperties.test new file mode 100644 index 00000000..2b911b39 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/04-patternproperties.test @@ -0,0 +1 @@ +[{"data": {"intKey2": 5, "intKey": 1}, "name": "patternProperties success", "schema": {"patternProperties": {"^int": {"minimum": 0}}, "properties": {"intKey": {"type": "integer"}}}}, {"fail": true, "data": {"intKey2": 5, "intKey": 1}, "name": "patternProperties failure 1", "schema": {"patternProperties": {"^int": {"type": "integer"}}, "properties": {"intKey": {"minimum": 5}}}}, {"fail": true, "data": {"intKey2": "string value", "intkey": 10}, "name": "patternProperties failure 2", "schema": {"patternProperties": {"^int": {"type": "integer"}}, "properties": {"intKey": {"minimum": 5}}}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/04-patternproperties.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/04-patternproperties.yaml new file mode 100644 index 00000000..d4beb524 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/04-patternproperties.yaml @@ -0,0 +1,23 @@ +- name: patternProperties success + data: { intKey: 1, intKey2: 5 } + schema: + properties: + intKey: { type: integer } + patternProperties: + "^int": { minimum: 0 } +- name: patternProperties failure 1 + data: { intKey: 1, intKey2: 5 } + schema: + properties: + intKey: { minimum: 5 } + patternProperties: + "^int": { type: integer } + fail: true +- name: patternProperties failure 2 + data: { intkey: 10, intKey2: "string value" } + schema: + properties: + intKey: { minimum: 5 } + patternProperties: + "^int": { type: integer } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/05-additionalproperties.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/05-additionalproperties.test new file mode 100644 index 00000000..2d5f0bc4 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/05-additionalproperties.test @@ -0,0 +1 @@ +[{"data": {"stringKey": "string", "intKey2": 5, "intKey": 1}, "name": "additionalProperties schema success", "schema": {"additionalProperties": {"type": "string"}, "patternProperties": {"^int": {"minimum": 0}}, "properties": {"intKey": {"type": "integer"}}}}, {"fail": true, "data": {"stringKey": null, "intKey2": 5, "intKey": 10}, "name": "additionalProperties schema failure", "schema": {"additionalProperties": {"type": "string"}, "patternProperties": {"^int": {"type": "integer"}}, "properties": {"intKey": {"minimum": 5}}}}, {"data": {"stringKey": null, "intKey2": 5, "intKey": 10}, "name": "additionalProperties boolean success", "schema": {"additionalProperties": true, "patternProperties": {"^int": {"type": "integer"}}, "properties": {"intKey": {"minimum": 5}}}}, {"fail": true, "data": {"stringKey": null, "intKey2": 5, "intKey": 10}, "name": "additionalProperties boolean failure", "schema": {"additionalProperties": false, "patternProperties": {"^int": {"type": "integer"}}, "properties": {"intKey": {"minimum": 5}}}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/05-additionalproperties.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/05-additionalproperties.yaml new file mode 100644 index 00000000..f3fb4fbd --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/05-additionalproperties.yaml @@ -0,0 +1,34 @@ +- name: additionalProperties schema success + data: { intKey: 1, intKey2: 5, stringKey: string } + schema: + properties: + intKey: { type: integer } + patternProperties: + "^int": { minimum: 0 } + additionalProperties: { type: string } +- name: additionalProperties schema failure + data: { intKey: 10, intKey2: 5, stringKey: null } + schema: + properties: + intKey: { minimum: 5 } + patternProperties: + "^int": { type: integer } + additionalProperties: { type: string } + fail: true +- name: additionalProperties boolean success + data: { intKey: 10, intKey2: 5, stringKey: null } + schema: + properties: + intKey: { minimum: 5 } + patternProperties: + "^int": { type: integer } + additionalProperties: true +- name: additionalProperties boolean failure + data: { intKey: 10, intKey2: 5, stringKey: null } + schema: + properties: + intKey: { minimum: 5 } + patternProperties: + "^int": { type: integer } + additionalProperties: false + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/06-dependencies.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/06-dependencies.test new file mode 100644 index 00000000..2a4c7600 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/06-dependencies.test @@ -0,0 +1 @@ +[{"data": {"key2": "string", "key1": 5}, "name": "string dependency success", "schema": {"dependencies": {"key1": "key2"}}}, {"fail": true, "data": {"key1": 5}, "name": "string dependency failure", "schema": {"dependencies": {"key1": "key2"}}}, {"data": {"key2": "string", "key1": 5}, "name": "array dependency success", "schema": {"dependencies": {"key1": ["key2"]}}}, {"fail": true, "data": {"key1": 5}, "name": "array dependency failure", "schema": {"dependencies": {"key1": ["key2"]}}}, {"data": {"key2": "string", "key1": 5}, "name": "schema dependency success", "schema": {"dependencies": {"key1": {"properties": {"key2": {"type": "string"}}}}}}, {"fail": true, "data": {"key2": 5, "key1": 5}, "name": "schema dependency failure", "schema": {"dependencies": {"key1": {"properties": {"key2": {"type": "string"}}}}}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/06-dependencies.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/06-dependencies.yaml new file mode 100644 index 00000000..e33a7d81 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/06-dependencies.yaml @@ -0,0 +1,21 @@ +- name: string dependency success + data: { key1: 5, key2: string } + schema: { dependencies: { key1: key2 } } +- name: string dependency failure + data: { key1: 5 } + schema: { dependencies: { key1: key2 } } + fail: true +- name: array dependency success + data: { key1: 5, key2: string } + schema: { dependencies: { key1: [ key2 ] } } +- name: array dependency failure + data: { key1: 5 } + schema: { dependencies: { key1: [ key2 ] } } + fail: true +- name: schema dependency success + data: { key1: 5, key2: string } + schema: { dependencies: { key1: { properties: { key2: { type: string } } } } } +- name: schema dependency failure + data: { key1: 5, key2: 5 } + schema: { dependencies: { key1: { properties: { key2: { type: string } } } } } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/Makefile b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/Makefile new file mode 100644 index 00000000..a4899796 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/05-objects/Makefile @@ -0,0 +1,9 @@ + +TARGETS := $(patsubst %.yaml,%.test,$(wildcard *.yaml)) + +tests: $(TARGETS) + + +%.test: %.yaml + python -c "import json; import yaml; import sys; json.dump(yaml.load(sys.stdin), sys.stdout);" < $< > $@ + diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/01-allOf.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/01-allOf.test new file mode 100644 index 00000000..c2da9972 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/01-allOf.test @@ -0,0 +1 @@ +[{"data": 10, "name": "allOf success", "schema": {"allOf": [{"type": "integer"}, {"minimum": 5}]}}, {"fail": true, "data": 1, "name": "allOf failure", "schema": {"allOf": [{"type": "integer"}, {"minimum": 5}]}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/01-allOf.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/01-allOf.yaml new file mode 100644 index 00000000..47673f6b --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/01-allOf.yaml @@ -0,0 +1,13 @@ +- name: allOf success + data: 10 + schema: + allOf: + - type: integer + - minimum: 5 +- name: allOf failure + data: 1 + schema: + allOf: + - type: integer + - minimum: 5 + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/02-anyOf.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/02-anyOf.test new file mode 100644 index 00000000..8215a2ba --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/02-anyOf.test @@ -0,0 +1 @@ +[{"data": "hello", "name": "anyOf success", "schema": {"anyOf": [{"type": "integer"}, {"type": "string"}, {"minlength": 1}]}}, {"fail": true, "data": true, "name": "anyOf failure", "schema": {"anyOf": [{"type": "integer"}, {"type": "string"}]}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/02-anyOf.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/02-anyOf.yaml new file mode 100644 index 00000000..708f3ed7 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/02-anyOf.yaml @@ -0,0 +1,14 @@ +- name: anyOf success + data: hello + schema: + anyOf: + - type: integer + - type: string + - minlength: 1 +- name: anyOf failure + data: true + schema: + anyOf: + - type: integer + - type: string + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/03-oneOf.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/03-oneOf.test new file mode 100644 index 00000000..6142b60b --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/03-oneOf.test @@ -0,0 +1 @@ +[{"data": 5, "name": "oneOf success", "schema": {"oneOf": [{"type": "integer"}, {"type": "string"}, {"minLength": 1, "type": "string"}]}}, {"fail": true, "data": "string", "name": "oneOf failure (too many)", "schema": {"oneOf": [{"type": "integer"}, {"type": "string"}, {"minLength": 1, "type": "string"}]}}, {"fail": true, "data": false, "name": "oneOf failure (no matches)", "schema": {"oneOf": [{"type": "integer"}, {"type": "string"}, {"minLength": 1, "type": "string"}]}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/03-oneOf.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/03-oneOf.yaml new file mode 100644 index 00000000..259e2597 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/03-oneOf.yaml @@ -0,0 +1,23 @@ +- name: oneOf success + data: 5 + schema: + oneOf: + - type: integer + - type: string + - { type: string, minLength: 1 } +- name: oneOf failure (too many) + data: string + schema: + oneOf: + - type: integer + - type: string + - { type: string, minLength: 1 } + fail: true +- name: oneOf failure (no matches) + data: false + schema: + oneOf: + - type: integer + - type: string + - { type: string, minLength: 1 } + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/04-not.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/04-not.test new file mode 100644 index 00000000..0589f2fd --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/04-not.test @@ -0,0 +1 @@ +[{"data": 5, "name": "not success", "schema": {"not": {"type": "string"}}}, {"fail": true, "data": "test", "name": "not failure", "schema": {"not": {"type": "string"}}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/04-not.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/04-not.yaml new file mode 100644 index 00000000..89774327 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/04-not.yaml @@ -0,0 +1,11 @@ +- name: not success + data: 5 + schema: + not: + type: string +- name: not failure + data: test + schema: + not: + type: string + fail: true diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/Makefile b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/Makefile new file mode 100644 index 00000000..a4899796 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/06-combinations/Makefile @@ -0,0 +1,9 @@ + +TARGETS := $(patsubst %.yaml,%.test,$(wildcard *.yaml)) + +tests: $(TARGETS) + + +%.test: %.yaml + python -c "import json; import yaml; import sys; json.dump(yaml.load(sys.stdin), sys.stdout);" < $< > $@ + diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/04-ref.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/04-ref.test new file mode 100644 index 00000000..4df30aeb --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/04-ref.test @@ -0,0 +1 @@ +[{"data": [[], [[]]], "name": "internal $ref 1", "schema": {"items": {"$ref": "#"}, "type": "array"}}, {"fail": true, "data": [1, 2, 3, 4], "name": "internal $ref 2", "schema": {"items": {"$ref": "#"}, "type": "array"}}, {"fail": true, "data": [[false], [[]]], "name": "internal $ref 2", "schema": {"items": {"$ref": "#"}, "type": "array"}}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/04-ref.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/04-ref.yaml new file mode 100644 index 00000000..819de210 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/04-ref.yaml @@ -0,0 +1,12 @@ +- name: internal $ref 1 + schema: { type: array, items: { "$ref": "#" } } + data: [[],[[]]] +- name: internal $ref 2 + schema: { type: array, items: { "$ref": "#" } } + data: [1,2,3,4] + fail: true +- name: internal $ref 2 + schema: { type: array, items: { "$ref": "#" } } + data: [[false],[[]]] + fail: true + diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/05-inline-addressing.test b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/05-inline-addressing.test new file mode 100644 index 00000000..e096a487 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/05-inline-addressing.test @@ -0,0 +1 @@ +[{"fail": true, "data": [0, false], "name": "inline addressing for fragments", "schema": {"items": {"$ref": "#test"}, "type": "array", "testSchema": {"type": "boolean", "id": "#test"}}}, {"schema": {"items": {"$ref": "other-schema"}, "type": "array", "id": "http://example.com/123/schema", "testSchema": {"type": "boolean", "id": "/other-schema"}}, "data": [0, false], "name": "don't trust non sub-paths", "missing": ["http://example.com/123/other-schema"]}] \ No newline at end of file diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/05-inline-addressing.yaml b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/05-inline-addressing.yaml new file mode 100644 index 00000000..06fdbfdb --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/05-inline-addressing.yaml @@ -0,0 +1,20 @@ +- name: inline addressing for fragments + data: [0, false] + schema: + type: array + items: { "$ref": "#test" } + testSchema: + id: "#test" + type: boolean + fail: true +- name: "don't trust non sub-paths" + data: [0, false] + schema: + id: 'http://example.com/123/schema' + type: array + items: { "$ref": "other-schema" } + testSchema: + id: "/other-schema" + type: boolean + missing: + - 'http://example.com/123/other-schema' diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/Makefile b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/Makefile new file mode 100644 index 00000000..a4899796 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/07-ref/Makefile @@ -0,0 +1,9 @@ + +TARGETS := $(patsubst %.yaml,%.test,$(wildcard *.yaml)) + +tests: $(TARGETS) + + +%.test: %.yaml + python -c "import json; import yaml; import sys; json.dump(yaml.load(sys.stdin), sys.stdout);" < $< > $@ + diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/Makefile b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/Makefile new file mode 100644 index 00000000..de57236d --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/Makefile @@ -0,0 +1,11 @@ + +all: + $(MAKE) -C 01-any-type + $(MAKE) -C 02-numeric + $(MAKE) -C 03-strings + $(MAKE) -C 04-arrays + $(MAKE) -C 05-objects + $(MAKE) -C 06-combinations + $(MAKE) -C 07-ref + + diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/README b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/README new file mode 100644 index 00000000..f7613fc4 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/README @@ -0,0 +1,4 @@ + +All the tests in this folder came from the tv4 javascript implementation. + +http://geraintluff.github.com/tv4/ diff --git a/src/hos_libvariant/src/test/test_schema_data/tv4-tests/submakefile b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/submakefile new file mode 100644 index 00000000..a4899796 --- /dev/null +++ b/src/hos_libvariant/src/test/test_schema_data/tv4-tests/submakefile @@ -0,0 +1,9 @@ + +TARGETS := $(patsubst %.yaml,%.test,$(wildcard *.yaml)) + +tests: $(TARGETS) + + +%.test: %.yaml + python -c "import json; import yaml; import sys; json.dump(yaml.load(sys.stdin), sys.stdout);" < $< > $@ + diff --git a/src/hos_libvariant/src/test/test_variant.cc b/src/hos_libvariant/src/test/test_variant.cc new file mode 100644 index 00000000..6a8c0bce --- /dev/null +++ b/src/hos_libvariant/src/test/test_variant.cc @@ -0,0 +1,744 @@ +//============================================================================= +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published +// by the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// The GNU Public License is available in the file LICENSE, or you +// can write to the Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA, or you can find it on the +// World Wide Web at http://www.fsf.org. +//============================================================================= +/** \file + * \author John Bridgman + * \brief A simple test for the Variant and JSONToVariant parser. + */ +#include +#include +#include +#include "TestCommon.h" +#include "TestAssert.h" +#include +#include +#include +#include +#include + +using namespace libvariant; +using namespace std; + + +void VariantTest() { + std::cout << "Testing some of Variant's functionality\n"; + + Variant null; + ASSERT(null.IsNull()); + Variant v; + v = 5; + ASSERT(!v.IsNull()); + ASSERT(v.AsInt() == 5); + ASSERT(v.AsUnsigned() == 5u); + ASSERT(v.AsDouble() == 5.0); + ASSERT(v == Variant(5)); + ASSERT(v != "5"); + Variant b = true; + ASSERT(b.IsBool()); + ASSERT(b.IsTrue()); + ASSERT(!b.IsFalse()); + b = false; + ASSERT(b.IsBool()); + ASSERT(b.IsFalse()); + ASSERT(!b.IsTrue()); + Variant map; + ASSERT(map.Empty()); + map["one"] = v; + map["two"] = "two"; + ASSERT(map["one"] == v); + ASSERT(v == map["one"]); + ASSERT(map.Empty() == false); + ASSERT(map["one"].Exists()); + ASSERT(!map["nothing"].Exists()); + ASSERT(map.Exists()); + Variant list; + ASSERT(list.GetType() == Variant::NullType); + list[0] = 1; + list[2] = "two"; + list[5] = map; + list[4] = 123u; + list[6] = 0.3535566; + ASSERT(list.GetType() == Variant::ListType); + ASSERT(!list.Empty()); + ASSERT(list.Size() == 7); + ASSERT(list[0].GetType() == Variant::IntegerType); + ASSERT(list[2].GetType() == Variant::StringType); + ASSERT(list[4].GetType() == Variant::UnsignedType); + ASSERT(list[5].GetType() == Variant::MapType); + ASSERT(list[6].GetType() == Variant::FloatType); + + ASSERT(list.Index("two") == 2); + ASSERT(list.Index("not here") == list.Size()); + + VariantRef listref = list; + ASSERT(listref.Index("two") == 2); + ASSERT(listref.Index("not here") == listref.Size()); + + try { + map.Index("abc"); + abort(); + } catch (const std::runtime_error &) {} + + try { + map.AsBool(); + abort(); + } catch (const std::runtime_error &) {} + try { + map.AsInt(); + abort(); + } catch (const std::runtime_error &) {} + try { + map.AsUnsigned(); + abort(); + } catch (const std::runtime_error &) {} + try { + map.AsLongDouble(); + abort(); + } catch (const std::runtime_error &) {} + try { + map.AsString(); + abort(); + } catch (const std::runtime_error &) {} + try { + map.AsBlob(); + abort(); + } catch (const std::runtime_error &) {} + try { + map.AsList(); + abort(); + } catch (const std::runtime_error &) {} + try { + map[1]; + abort(); + } catch (const std::runtime_error &) {} + try { + list.AsMap(); + abort(); + } catch (const std::runtime_error &) {} + try { + list["test"]; + abort(); + } catch (const std::runtime_error &) {} + try { + b.Size(); + abort(); + } catch (const std::runtime_error &) {} + ASSERT(b.IsBool()); + try { + b.Empty(); + abort(); + } catch (const std::runtime_error &) {} + try { + b.Erase("abc"); + abort(); + } catch (const std::runtime_error &) {} + try { + b.At("abc"); + abort(); + } catch (const std::runtime_error &) {} + try { + b.At(1); + abort(); + } catch (const std::runtime_error &) {} + try { + b.Get("abc"); + abort(); + } catch (const std::runtime_error &) {} + try { + b.Get(1); + abort(); + } catch (const std::runtime_error &) {} + try { + list.AtPath("[0][1]").As(); + abort(); + } catch (const std::runtime_error &) {} + try { + b.Set("abc", 1); + abort(); + } catch (const std::runtime_error &) {} + try { + b.Set(1, 1); + abort(); + } catch (const std::runtime_error &) {} + + b.Clear(); + ASSERT(b.IsNull()); + ASSERT(!b.Contains(123)); + ASSERT(!b.Contains("abc")); + ASSERT(b.AsBool() == false); + ASSERT(b.AsInt() == 0); + ASSERT(b.AsUnsigned() == 0); + ASSERT(b.AsLongDouble() == 0.0); + ASSERT(b.AsString() == ""); + ASSERT(b.Empty()); + ASSERT(b.Size() == 0); + b.Clear(); + b.Erase("abc"); + b.AsMap(); + ASSERT(b.IsMap()); + b.Clear(); + ASSERT(Variant(true).AsString() == "true"); + ASSERT(Variant(false).AsString() == "false"); + ASSERT(Variant(true).AsInt() == 1); + ASSERT(Variant(false).AsInt() == 0); + ASSERT(Variant(true).AsUnsigned() == 1); + ASSERT(Variant(false).AsUnsigned() == 0); + ASSERT(Variant(true).AsLongDouble() == 1.); + ASSERT(Variant(false).AsLongDouble() == 0.); + ASSERT(Variant(false) != Variant()); + ASSERT(Variant(123u).AsBool()); + ASSERT(Variant(123.456).AsUnsigned() == 123u); + ASSERT(Variant(123.456).AsInt() == 123); + ASSERT(Variant(123.456).AsBool() == true); + ASSERT(Variant(0.0).AsBool() == false); + ASSERT(Variant("true").AsBool() == true); + ASSERT(Variant("anything").AsBool() == true); + ASSERT(Variant("false").AsBool() == false); + ASSERT(Variant("555.5").AsLongDouble() == 555.5); + ASSERT(Variant("123").AsUnsigned() == 123u); + ASSERT(Variant("123").AsInt() == 123); + ASSERT(Variant("").Empty()); + ASSERT(!Variant("abc").Empty()); + b = "abc"; + b.Clear(); + ASSERT(b.Empty()); + + cout << "Some simple path testing\n"; + + ASSERT(map.GetPath("/") == map); + ASSERT(map.GetPath("/one") == v); + ASSERT(list.GetPath("[5]/two") == "two"); + + cout << "Testing that the proxy works as expected.\n"; + list[1] = map["one"]; + VariantRef ref = map["three"]; + ref = 3; + ASSERT(map["three"].AsInt() == 3); + + VariantRef ref2 = map["nothing"]; + ref2 = 4; + map.Erase("nothing"); + try { + ref2.AsUnsigned(); + abort(); + } catch (const std::runtime_error &) {} + + try { + map["four"].IsNull(); + ASSERT(false); + } catch (const KeyError &e) {} + ASSERT(!map.Contains("four")); + ASSERT(map.AsMap().find("four") == map.MapEnd()); + + try { + Variant tmp; + tmp = map["four"]; + SerializeJSON(stdout, map); + ASSERT(false); + } catch (const KeyError &e) {} + ASSERT(!map.Contains("four")); + ASSERT(map.AsMap().find("four") == map.MapEnd()); + + try { + Variant tmp = map["four"]; + SerializeJSON(stdout, map); + ASSERT(false); + } catch (const KeyError &e) {} + ASSERT(!map.Contains("four")); + ASSERT(map.AsMap().find("four") == map.MapEnd()); + + cout << "Testing vector constructor\n"; + std::vector intvec; + intvec.push_back(1); + intvec.push_back(2); + intvec.push_back(3); + intvec.push_back(4); + Variant v2 = intvec; + ASSERT(intvec == variant_cast< std::vector >(v2)); + + std::vector< std::complex< float > > complexvec; + complexvec.push_back(std::complex(1, 3)); + complexvec.push_back(std::complex(0, 2)); + complexvec.push_back(std::complex(10, 0)); + complexvec.push_back(std::complex(4, 0)); + Variant complexvec1 = Variant() + .Append(Variant().Set("real", 1).Set("imag", 3)) + .Append(Variant().Set("imag", 2)) + .Append(Variant().Set("real", 10)) + .Append(4); + ASSERT(complexvec == variant_cast< std::vector< std::complex > >(complexvec1)); + Variant complexvec2 = Variant() + .Append(Variant().Append(1).Append(3)) + .Append(Variant().Append(0).Append(2)) + .Append(10) + .Append(Variant().Append(4)); + std::vector< std::complex< float > > complexvec4 = variant_cast< std::vector< std::complex > >(complexvec2); + ASSERT(complexvec == complexvec4); + + cout << "Testing map constructor\n"; + std::map intmap; + intmap["key1"] = 1; + intmap["key2"] = 2; + v2.Append(intmap); + ASSERT( (intmap == variant_cast< std::map >(v2[4])) ); + ASSERT(variant_cast(v2[1]) == 2); + std::vector intvec2(4); + transform(v2.ListBegin(), v2.ListEnd() - 1, intvec2.begin(), variant_cast); + ASSERT(intvec2 == intvec); + ASSERT(v2 == variant_cast(v2)); + + VariantPrint(v2); + // Test a case where proxy had a dangling reference on resize. + for (unsigned i = v2.Size(), end = v2.AsList().capacity()*2; i < end; ++i) { + v2[i] = v2[i-1]; + } + + cout << "Test Get and GetInto\n"; + int ival; + map.GetInto(ival, "one", 0); + ASSERT(ival == v.AsInt()); + ASSERT(map.Get("three").AsUnsigned() == 3); + map["intmap"] = intmap; + ival = 0; + map["intmap"].GetInto(ival, "key1", 0); + ASSERT(ival == 1); + try { + map["none"].GetInto(ival, "blah", 0); + ASSERT(false); + } catch (const KeyError &e) {} + + // list == [ 1, 5, "two", null, 123, { "intmap": { "key1": 1, "key2": 2 }, "one": 5, "two": "two", "three": 3 }, 0.3535566 ] + ASSERT(list == Variant().Append(1).Append(5).Append("two").Append(Variant::NullType) + .Append(123u).Append( + Variant().Set("intmap", Variant().Set("key1", 1).Set("key2", 2)) + .Set("one", 5).Set("two", "two").Set("three", 3) + ).Append(0.3535566) + ); + + list.Clear(); + ASSERT(list.Empty()); + ASSERT(list.Size() == 0); + ASSERT(list.Get(2, 123) == 123); + ASSERT(list.At(2, 123) == 123); + ASSERT(list.Get(2) == 123); + list.Set(2, 345); + ASSERT(list.Get(2) == 345); +} + +void TestCopy() { + cout << "Testing Copy\n"; + Variant v1; + v1.SetPath("foo/bar", 3); + v1.SetPath("list[0]", "abc"); + Variant v2 = v1; + ASSERT(v1 == v2); + v2 = v1.Copy(); + v2.SetPath("foo/goo", 4); + ASSERT(v1 != v2); + v2 = v1.Copy(); + v2.SetPath("list[1]", 123); + ASSERT(v1 != v2); +} + +void TestRefReassign() { + cout << "Testing VariantRef reassign\n"; + + Variant v1; + v1.SetPath("a/b/c", 1) + .SetPath("a/b/d", 2) + .SetPath("a/d", 4); + VariantRef ref = v1["a"]["b"]["c"]; + ASSERT(ref == 1); + ref.ReassignRef(v1.AtPath("a/b/d")); + ASSERT(ref == 2); + ref = 5; + ASSERT(v1.GetPath("a/b/c") == 1); + ASSERT(v1.GetPath("a/b/d") == 5); + + VariantRef ref1 = v1.AtPath("foo/bar"); + VariantRef ref2 = v1.AtPath("foo").AtPath("bar"); + VariantPrint(v1); + ASSERT(!v1.HasPath("foo")); + ASSERT(!v1.HasPath("foo/bar")); + +} + +void TestProxy() { + Variant v = Variant().Set("abc", 123).Set("def", 0.456); + // Error cases + try { + v["none"].GetType(); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].AsBool(); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].AsLongDouble(); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].AsUnsigned(); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].AsInt(); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].AsString(); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].AsBlob(); + abort(); + } catch (const std::runtime_error &) {} + try { + ((const Variant &)v["none"]).AsList(); + abort(); + } catch (const std::runtime_error &) {} + try { + ((const Variant &)v["none"]).AsMap(); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Size(); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Empty(); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Clear(); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Contains(1); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Contains("1"); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Erase("1"); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Add(1); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Sub(1); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Mul(1); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Div(1); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Rem(1); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Incr(); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Decr(); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Neg(); + abort(); + } catch (const std::runtime_error &) {} + try { + v["none"].Compare("abc"); + abort(); + } catch (const std::runtime_error &) {} + + std::map map; + map["abc"] = 123; + std::vector list; + list.push_back(123); + v["map"] = map; + v["list"] = list; + + v["abc"].GetType(); + v["abc"].AsBool(); + v["abc"].AsLongDouble(); + v["abc"].AsInt(); + v["abc"].AsUnsigned(); + v["map"].AsMap(); + v["list"].AsList(); + v["map"].Size(); + v["map"].Empty(); + v["map"].Clear(); + v["map"].Contains("abc"); + v["list"].Contains(1); + v["map"].Erase("foo"); + v["n"] = 0; + v["n"]++; + v["n"]--; + v["n"] + 1; + v["n"] - 1; + v["n"] * 1; + v["n"] / 1; + v["n"] % 1; + -v["n"]; + + VariantRef ref = v["n"].Ref(); + ASSERT(ref == v["n"]); + ASSERT(v["map"].Copy() == v["map"]); + ASSERT(ref.Resolve() == v["n"]); + + ASSERT(ref.As() == v["n"].As()); + + Variant v_copy = v.Copy(); + try { + v.AtPath("/some/path/string").As(); + abort(); + } catch (const KeyError &) {} + try { + v_copy["some"]["path"]["string"].As(); + abort(); + } catch (const KeyError &) {} + try { + const VariantRef const_ref = v_copy["does not exist"]; + const_ref.Resolve(); + abort(); + } catch (const KeyError &) {} + ASSERT(v_copy == v); + + VariantRef p = v["p"].Ref(); + v["p"] = 123; + ASSERT(p == 123); + + try { + v.GetPath("/some/path/string"); + abort(); + } catch (const KeyError &) {} + ASSERT(v.AtPath("/some/path/string", "value") == "value"); + v.AtPath("/some/other/path") = 123; + ASSERT(v.GetPath("/some/other/path") == 123); + VariantRef ref_copy = v_copy.AtPath("/some/path/string"); + ref_copy.Resolve() = "value"; + ASSERT(v_copy.AtPath("/some/path/string") == "value"); + + v.AtPath("/one/two/three").Resolve(123); + v.AtPath("/some/path/string").Resolve(123); + ASSERT(v.GetPath("/one/two/three") == 123); + ASSERT(v.GetPath("/some/path/string") == "value"); + v.ErasePath("/one/two/three", true); + v.ErasePath("p"); + v.ErasePath("some/other/path", true); + v.ErasePath("/some/path/string"); + v_copy.ErasePath("/some/path/string"); + ASSERT(v == v_copy); + ASSERT(v.HasPath("some/path")); + v.SetPath("list[1]/a", 123); + v.ErasePath("list[1]/a", true); + ASSERT(v == v_copy); + +} + +void VariantTestJSONParsing() { + std::cout << "Testing JSON -> Variant parsing\n"; + Variant v; + Variant param; + param["pretty"] = true; + Emitter emitter = JSONEmitter(CreateEmitterOutput(std::cout.rdbuf()), param); + std::string text = "[1,2,3,4,{\"A\":2}, \"text\"]"; + text += "[\"doodle\", \"foo\", \"bar\", \"\\b\\f\\r\\u0001\\u1111\", true, false]"; + std::istringstream iss(text); + Parser jv = JSONParser(CreateParserInputFile(iss.rdbuf())); + v = ParseVariant(jv); + emitter << v; + v = v; + ASSERT(v.IsList()); + ASSERT(v[4].IsMap()); + ASSERT(v[5].IsString()); + ASSERT(v[4]["A"].IsNumber()); + v[4]["b"]; + ASSERT(!v[4].Contains("b")); + v[10]; + ASSERT(!v.Contains(10)); + const Variant cv = v; + ASSERT(cv.IsList()); + ASSERT(cv[4].IsMap()); + ASSERT(cv[5].IsString()); + ASSERT(cv[4]["A"].IsNumber()); + ASSERT(!cv[4].Contains("b")); + try { + cv[10]; + ASSERT(false); + } catch (const std::out_of_range&) { + + } + v = v[4]; + v = "\n"; + + jv.Reset(); + v = ParseVariant(jv); + ASSERT(jv.Done()); + ASSERT(v[1].AsString() == "foo"); + + emitter.Flush(); + std::cout << std::endl; + // Test that really big indents work... + Serialize(std::cout.rdbuf(), v, SERIALIZE_JSON, Variant().Set("pretty", true).Set("indent", 200)); + std::cout << std::endl; + +} + +void VariantTestYAMLParsing() { + std::cout << "Testing YAML -> Variant parsing\n"; + std::string text = "some: yaml\na key: and a value\n" + "some more: [a, list, 123, values, 1.23, null, true, false]\n" + "max uintmax: 18446744073709551616\n" + "---\n" + "Lets try multiple documents!\n"; + Parser parser = YAMLParser(CreateParserInput(text.c_str(), text.length())); + Variant v1 = ParseVariant(parser); + Variant v2 = ParseVariant(parser); + ASSERT(v1["some"].IsString()); + ASSERT(v1["some more"].IsList()); + ASSERT(v1["some more"].Size() == 8); + ASSERT(v1["some more"][6].IsTrue()); + ASSERT(v1["max uintmax"].AsUnsigned() == std::numeric_limits::max()); + ASSERT(v2.IsString()); +} + +void PrintError(std::vector &stack, const std::string &msg, Variant orig, Variant cur) { + cerr << "Error comparing variants at: "; + for (std::vector::iterator i(stack.begin()), e(stack.end()); i!=e; ++i) { + cerr << i->AsString() << ": "; + } + cerr << "\n\n" << msg; + Emitter emitter = JSONEmitter(CreateEmitterOutput(cerr.rdbuf())); + emitter.BeginMap(); + emitter << "orig" << orig << "cur" << cur; + emitter.EndMap(); + emitter.Close(); + cerr << "\n"; + abort(); +} + +void DoDiff(Variant orig, Variant cur, std::vector &stack) { + if (orig != cur) { + if (orig.GetType() != cur.GetType()) { + PrintError(stack, "differing types", orig, cur); + } + // find the difference and print it out + switch (orig.GetType()) { + case Variant::NullType: + abort(); + case Variant::BoolType: + PrintError(stack, "differing boolean", orig, cur); + abort(); + break; + case Variant::IntegerType: + case Variant::UnsignedType: + case Variant::FloatType: + abort(); + break; + case Variant::StringType: + abort(); + break; + case Variant::ListType: + for (unsigned i = 0; i < orig.Size(); ++i) { + stack.push_back(i); + DoDiff(orig[i], cur[i], stack); + stack.pop_back(); + } + break; + case Variant::MapType: + for (Variant::MapIterator i(orig.MapBegin()), e(orig.MapEnd()); i!=e; i++) { + stack.push_back(i->first); + DoDiff(i->second, cur[i->first], stack); + stack.pop_back(); + } + break; + case Variant::BlobType: + abort(); + break; + } + PrintError(stack, "Comparison showed different but cannot find difference", orig, cur); + } +} + +void Diff(Variant orig, Variant cur) { + std::vector stack; + DoDiff(orig, cur, stack); +} + +void TestVariantEmitParseRandom(int verbose, int numtests, Parser (*Parser_t)(shared_ptr), Emitter (*Emitter_t)(shared_ptr, Variant), bool allow_nan) { + for (int i = 0; i < numtests; ++i) { + if (verbose > 0) { + std::cout << "Random test number " << i << std::endl; + } + Variant v = GenerateRandomVariant(allow_nan); + ASSERT(!v.IsNull()); + std::stringstream ss; + Emitter emitter = Emitter_t(CreateEmitterOutput(ss.rdbuf()), Variant()); + emitter << v; + emitter.Close(); + if (verbose > 1) { + std::cout << ss.str() << std::endl; + } + Parser parser = Parser_t(CreateParserInputFile(ss.rdbuf())); + Variant v2 = ParseVariant(parser); + Diff(v, v2); + if (verbose > 0) { + std::cout << "End random test number " << i << std::endl; + } + } +} + +int main(int argv, char** argc) { + VariantTest(); + TestCopy(); + TestRefReassign(); + TestProxy(); + VariantTestJSONParsing(); +#ifdef ENABLE_YAML + VariantTestYAMLParsing(); +#endif + int verbose = 1; + int num_tests = 100; + + cout << "Random test of JSON\n"; + TestVariantEmitParseRandom(verbose, num_tests, JSONParser, JSONEmitter, false); +#ifdef ENABLE_YAML + cout << "Random test of YAML\n"; + TestVariantEmitParseRandom(verbose, num_tests, YAMLParser, YAMLEmitter, true); +#endif +#ifdef ENABLE_XML + cout << "Random test of XML\n"; + TestVariantEmitParseRandom(verbose, num_tests, XMLPLISTParser, XMLPLISTEmitter, true); +#endif +#ifdef ENABLE_MSGPACK + cout << "Random test of MsgPack\n"; + TestVariantEmitParseRandom(verbose, num_tests, MsgPackParser, MsgPackEmitter, true); +#endif + return 0; +} diff --git a/src/hos_libvariant/src/test/test_xml_parser.cc b/src/hos_libvariant/src/test/test_xml_parser.cc new file mode 100644 index 00000000..57df8e81 --- /dev/null +++ b/src/hos_libvariant/src/test/test_xml_parser.cc @@ -0,0 +1,32 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include "TestAssert.h" +#include +#include + +using namespace libvariant; +using namespace std; + +const char *test_xml = +"\n" +" \n" +"\n\n" +" some value with spaces \n" +"\n\n\n" +"\n" +"\tSome formated\n" +"\tstring with strange stuff in it...\n" +"\n" +"\n" +"\n"; + +int main(int argc, char **argv) { + Variant v = DeserializeXMLPLIST(test_xml); + SerializeJSON(cout.rdbuf(), v, true); + cout << endl; + Variant v2 = DeserializeXMLPLIST(SerializeXMLPLIST(v, true)); + ASSERT(v2 == v); + return 0; +} diff --git a/src/hos_libvariant/src/test/test_yaml_parser.cc b/src/hos_libvariant/src/test/test_yaml_parser.cc new file mode 100644 index 00000000..7baf82d3 --- /dev/null +++ b/src/hos_libvariant/src/test/test_yaml_parser.cc @@ -0,0 +1,64 @@ +/** \file + * \author John Bridgman + * \brief + */ +#include +#include +#include "EventBuffer.h" +#include "TestCommon.h" +#include + +using namespace libvariant; + +static const char *input_document = "---\n" +"string: value\n" +"int10: 1234\n" +"int8: 0o234\n" +"int16: 0x2F\n" +"float: [ 0.1, .12, 1.0e-2 ]\n" +"nan: .nan\n" +"inf: .inf\n" +"strnum: '12345'\n" +"...\n"; + +void ExpectedEvents(Emitter e) { + e.BeginDocument(); + e.BeginMap(); + e.Emit("string"); + e.Emit("value"); + e.Emit("int10"); + e.Emit(intmax_t(1234ll)); + e.Emit("int8"); + e.Emit(uintmax_t(0234ll)); + e.Emit("int16"); + e.Emit(uintmax_t(0x2Fll)); + e.Emit("float"); + e.BeginList(); + e.Emit(0.1); + e.Emit(.12); + e.Emit(1.0e-2); + e.EndList(); + e.Emit("nan"), + e.Emit(std::numeric_limits::quiet_NaN()), + e.Emit("inf"), + e.Emit(std::numeric_limits::infinity()), + e.Emit("strnum"), + e.Emit("12345"), + e.EndMap(); + e.EndDocument(); +} + + +int main(int argc, char **argv) { + Parser parser = YAMLParser(CreateParserInput(input_document)); + shared_ptr expected(new EventBuffer); + ExpectedEvents(Emitter(expected)); + shared_ptr result(new EventBuffer); + + result->Fill(parser); + + if (!ErrorCheckEventBuffer(expected, result)) { + return 1; + } + return 0; +} diff --git a/src/hos_philips_hue/python/hos_huecontroller/huecontroller.py b/src/hos_philips_hue/python/hos_huecontroller/huecontroller.py index 66df1b10..0cdcc645 100644 --- a/src/hos_philips_hue/python/hos_huecontroller/huecontroller.py +++ b/src/hos_philips_hue/python/hos_huecontroller/huecontroller.py @@ -87,7 +87,7 @@ class HueController(object): msg = DeviceStatusUpdate() msg.seq = seq msg.device_id = device_id - msg.device_type = "hos/huelight" + msg.device_type = "hue/huelight" msg.stamp = stamp msg_body = dict()

pxaXsq&PF39ISNlzv_g>+E<-&qNL?I=wn}1 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 C1X8&G literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_variant_emitting.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_variant_emitting.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..613a0cad7fad62069e0d94a40e27d581723c427f GIT binary patch literal 1122 zcmV-o1fBZ;0RRC20000000bfc01Mdw0000000030|NsC0|NsB%X{4ABE!VWkok&0z z44?VZg&jly00000000000001ZoV`|UYa&Sy{;a>E*n^Xiz`I|g)z+7e}7Z_+tAe_{y3nrg zJAA5gm4GeKhH)Cgu>u1+<+vu%-asPUF4UuAhsv;18-i3hcC1rU784}tU&|x`A0e|C zWl1Y1ojJH2&cEC&=Fl78!EJ9k?TzPmT{`SyOYf-6JDSFN)>9 zDXL6$C6;JYE;tSRs=$VS>-AcR4@WfVMmTNG&l_7CEmfeEbx^W_qg9ilYBfva9mLRB zc~|J>n-m+(!Vw4>pz?I5GtQEPy&dw@&|_RSHJV*E_{8l;_gT<|*1I4Xagv^8W0j+V znwtzus0YA=F!sFzL6*w>Lb{=Hc#q}@%{(c&DCbLD7s|?eh2f#-%J&MyAko4divLs7 zTH-6wGrFW9*6#o>Kpw0Sgo9Kt;|=rW@K>HUFbo7SY$v3VWn#v~Gn{0AG=EU#KSBjbRh zf35APr^1M(EytaKbb(Z?6liNX>kgI-o(cUdYBXDnU7(dH-5ohTM;NTQV7byV+@n`4 z+&=XqzF&BOcjOLprz8MSJEWjmX)HfK!zIaZSlSzp-fl9NX0B1C^@8s?;pPER6(09; z@7=phbh&*8Bo2n7J{(6sTh6=jubM-1K>dbe>;Gga)_;?hLQGcPOM8NHeaERYE!cXg z_y0rH7KVNUeJ3cAb<%yK+MHKT=cq(`TPL?0Sb*fcrGn(*OAQlRI9IOV?u)Y1+14Rf ox9{1OtdFttU>*@~s`$yaS*WBN4Ocrhg zo@)yx9spnGf^&$1xx8nB_u(OkVa9wA+;Jl*TsxK=TnWr~_5%USz;Wj|PZCt@J6wQV zaFARqBM9c|jHMa67!d9$rqq^l`9U1lY@0Ttm6b z&~p(P*Cm)QACNvFd^){8`G`}7$D@nU(aFul@EWde zuCG3iPrCqP&J#To$P22TE32V89WI&cMQa6UOBIHrD%c9gG27#bBIYi>UyM#pFUO~( zX;Lvkke}QO7ac?f&)TmIBY)Oy!!Q4U2}f0MxboPHLx)htF(JHrchH98Ad)ot(-01R zK0G|^9KJjFwGB7pVIo%f=G^rivPq!m5yovGJO^%Fhr=zm0Zq1$GVJZ|-{0SN=h3_y zh&x*NmZNEJ55AIent(4XMxzV(Em-()EL`Vq$$Zse3zyFUU-z4TbN!hYBg^-{GvT5q z?3-tIF{tRgVj|)q-xo=Tf1B}8<{O3U-<4bPQ|H*o*>cdtwmBSRdfXuC${@IRKJyfU z!%^iNo&4k@x~0YZ8Ljl6U|xE#v(rjPO@`-SNp^?*^nbqd!|~*LcyeknaTm3~3E=T- zvq3Iuxjx1j9Ki(!jc2v`_%VQkK6E;63myTN-RsS`5b*vz>~vwL4^KEX*G!=FRE^ws zy#Ckb6WlMzeXTk3B925jKC0VCWw``1w1yJ4fzmqoT&vYS@>SP zXjQktSZx49rIt@D?Bkr7$D#%tFf2Z&BC9h!)Z^bpPPfkh#LjkWS{b5eQZOgiuO+0$_^q*NElpne8k@F?~qwmhvhW%`a;#IIAcR$$h!*Q>KgX%|CE+UU$(-v z4a@65d*)%=K=JEw|4uI2Q01}NHp~kOy$pPT+wj|wi_k;QWl<5f)~Qq7sA*vBP);$q zkCIQzC~C~*@63z26&fe#3{1SFQFYL&w9a_OJSK{SoFJx6ceU9n3tSDP;<{2a+fXEK zS|~x+tpkPUB6uU>S!$S9+7SD+d0@TsJ!X4mLD`I@1ZdpW>(^O__?qS0LE!zRt#%oE z-pk&Wz=VWYwby_AplkTfhH`POZUEolKf;;W1UoNvGo*_E}Qv@FwhPsMUBY&#cw2jdG zF55^8FSQ!eSG8{wER`7v483;-SygGq?Sy9+&s*}rYGE~gfF+b^oJ}$5S*@0l4pbBy zM5B&$;c1PgSvIIH%2XbWurs&{LR~&tYxB^iZA$qPb1-G2CZCM@I~*F_X*S8I!-~3e zO-dzS;*@?=D7~MrvuT&YN2U_3sspi!Mr3x1#KKkeDpo`_-zp^NPZ?wg$%8 zHg0hITgYc}`Uiio$cU<3&AED-rjZO~>FSWf!m(5ZRuq>wM#nP%u z5rVH2zTIIo*4w@I`Nn!AcB@*xHWsQ=gHhPO5aHixg2=2R@)AT8l+Jxc3il4L&{l;snYwlT$9HZW=2pB0%KY_Z*87;@jS zR_PY9aTILh%vccy3ih>eP;!yVKqx!X|1J^|J1KeQ!)Oh5jgMsAINc)4iz^wTa&cwX z-ZiT`&`S%u)odH)#xCq$$5>Lp(Giv|ySwmHx_a90)ksq!DBSM)HYu~*4;%@&%ya+4 z%{5jw-|nij-#8gTfdzEQr`2K5vk*8wDW2#MDZ1Lp=u6FeQF`W-{C#4TIFv^38%tB+ zvlkZ6m9s)@+DFwk>qLr_b5Nmv?y zFG|Tp+-Bf4@%FN!HOMmo1{_})zP zM{I-7l1>h!g+aZZI=JM{n$(ii=UATi3^R*L^`|1=EHHLUlFqp_H<0Q^c0~)(cef(A*Qqp!1(#*@8(raT{d1s(k-2FhmL${LKEHxIrvt%1{ z@=6cr$^MeXO7DA{={*<8Go;D5Moc0l)6;L}@5VMFs;9n{u98(Diq3=?F{t+LC{n+5 zr7W^E=zPd!a{c#|UTD`XR@DjWzOH1!Ak=S1M<$UMbI~sS*;vcmG9-r9f{-+IcC%K` ddJi3U*8>cbWQ1`RbsEl~D0h2m{uiXK)-Ig!y;T4J literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_x_m_l_p_l_i_s_t_defs.h.i b/src/hos_libvariant/src/.hg/store/data/src/_x_m_l_p_l_i_s_t_defs.h.i new file mode 100644 index 0000000000000000000000000000000000000000..f0ae3ff2550ff3721a6e02744ea6d2b5c26bd298 GIT binary patch literal 723 zcmV;^0xbOi0RRC20000000NT$00lz;0000000030|NsC0|NsB8{9|E}{KCh6TaomK zs_kRn0zjq!00000000000001ZoUN4KZ`v>r$DhYvacW<-ijvZ5nzm{Wp$jx!2vHKo zkS0|Qxe#l{Mvha&f4_5@G-%q7m-6KJbNBV#_iP;J^K1SFj`Johc?E)Jn&~6Zve1Z7 zslptX##=b58a7OV#++A1^Q<-q+yIlgqcrSP&I`&jR;rdcYA_{&LA|R$70t&iTtd(u zFhhx&35e=U@C|KmP*w=6g1z0TO3bZNc5E`Iww9!=1*VD)V1_Gs3&@FUctTy#H(YmT zwSq%X+UmSz#&)1V?QPyWD*Fh6nLc$yVSlor?=}Z68|_lQm`o%QGCK@DZbkaPRi7mX3`v~e5)|`;=6lFaVLJ@ zr)z2grhXcFNdnVF3@$`&ocedmz>OhV#?d12MgR$7=d%_0kJUvpHL^2D!?>t=1D+@K zTR2(4o+yrG0y`rLPV2zG^TNclPFstuguN#R&FO*|_0RbY!IzuS5Z-@;6v+yNNU#mU zrBz94t8jC3HH3+(jE$bVaCJQ%k1xkJS09G3Ox*6+=57{T=5{8kDbH%GlomOxc#g2b z3}|GfG5b%Bb2uDEMOBQH-rB}r`88c!zz=KA0BFH#8oGuDRZ5s>o^N+dHXzd+3!tSl zIOheunF7AKu}^b<{5}t&z)#XI-ZXi}5YmV?Ug=$X;%_?O_@(y%rf=V-KcokaVPAqB=o-n0hlWZXuTjx2R7tgN2*6P$LsP zi5H6w&@-q`YP8L@#J-GUPr_vov_#h8MC_}#ZufuUN&F;OOgbBwVQ1tIO8T!F`~oXY Fo>XM}R9gT5 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_x_m_l_p_l_i_s_t_emitter.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_x_m_l_p_l_i_s_t_emitter.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..05009e29353a3d993e3fed2ee3317d8b65050840 GIT binary patch literal 1794 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 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_x_m_l_p_l_i_s_t_parser.h.i b/src/hos_libvariant/src/.hg/store/data/src/_x_m_l_p_l_i_s_t_parser.h.i new file mode 100644 index 0000000000000000000000000000000000000000..2cfbbc234c59af7673f8bf2e3f6783f7641a112c GIT binary patch literal 1075 zcmV-31kC#Y0RRC20000000Z*?00{#C0000000030|NsC0|NsAdBImDPP>tfW#vsoP zm12g8Wg3eB00000000000001ZoUK-EPvbZc{@nbEk@!+jw}nNg(*lPSxU%G~lqyM= zLpljL$%I<#+F9FasaCtc{l-pTZwn`#7OCKQdpz^ZjA^g;+t2(7dc9UU;RXcHG}8;9 zW2q6rsM5}v#&cMx8geEl4QyQkK;3dUb2UW`gHP{J)MLjj3N-umI zj$yF8;3G=ZOu(ql1kXvGqcjN2K;<-Mf`voM7C!RE<&rFOfg42^Fw2!Z2jpbeFhgxf zhWD$xmVg~l+TpaBbron(m5V#1v=<YsBVAVa7P zmbK{kq-zTgQF?nnP9YpV!b2Fx;V^wXCuciRWW^aaP<&bmPRLZ3X3{PweTQ(@kFRej zB)p0SQTj+lz)h46`$+;f_c4Sp3ga}o9uLA8M&o#NpY*!`3F3-p2l5|Om%eL6XMvV+ zVKxLbo%)wMQNd>9$1;H{B1%r@L3G_8CVj`Wqu4>XIhkut17g*i{p&y^^KJ)z`2Z;r z6$m52a)fsdC8-_4>FIF?u9UIP`!0mz_a`SO?@msSf9=3H30K$p*(|v%Tu+ow&tW_$ zEed$x1;PVnKrNeCTb=cK^ZC46nzF0(vn%{3Z`08c{O!mIfDWvtrfc{^O(a}tUOZ2k z^oC4xEP;-_;DDF3GbMZqDRv`keIRr`zCwtX$$74wYtvOtt4oa55J) z6@5|Qml`j(6g1i|Q_-W3Mn-Geoorh_G0kZXdn2aJ+qOtnwcYQKOsLDn$olvokZg*k za&4u%XN?bh4T4rKm@%-fq=BU=fV1Wi$YD$OHE6X^)>B9&PGO<+RXFQ3=ql~CDQxMS7&+@Dr_oosS-Am7_5!zPu8=aiwDGe$$k7lQ4ZG_|p`P4YwtehTZeKb}|Ew-c)E)06 zut|0|F84RD1Gha^={B>RDmQpL*=*-Rz4DL7#WLy=917B}{IkQPm&1`5``3e(9GZ8; tU-#;4(w{ZGKG9+=qFaZJq#LBIkwHfuok>sI@hvz&N#8Yse*mDv-U+uW2)+OS literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_y_a_m_l_emitter.cc.i b/src/hos_libvariant/src/.hg/store/data/src/_y_a_m_l_emitter.cc.i new file mode 100644 index 0000000000000000000000000000000000000000..82e851de44e3e17ff2f3fcfcbb0e55425efaf99a GIT binary patch literal 2670 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 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_y_a_m_l_emitter.h.i b/src/hos_libvariant/src/.hg/store/data/src/_y_a_m_l_emitter.h.i new file mode 100644 index 0000000000000000000000000000000000000000..ee852568bd3e2c414fae1c97a659d871f45d86ab GIT binary patch literal 1789 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 literal 0 HcmV?d00001 diff --git a/src/hos_libvariant/src/.hg/store/data/src/_y_a_m_l_parser.h.i b/src/hos_libvariant/src/.hg/store/data/src/_y_a_m_l_parser.h.i new file mode 100644 index 0000000000000000000000000000000000000000..675f5a0c19634e3d967bc3c8e3d7de8cee59f5b6 GIT binary patch literal 879 zcmV-#1Caax0RRC20000000S=o00zGR0000000030|NsC0|NsB>V~nWL?@}r}VYV-5 zKYMGNu-*#*00000000000001ZoUK)DYvV=`{w)29f%}pepOsuFrS|neNu7%h$1##! z6DWk0G>Vq4cg5_=#yzgTy|Yr%xNg#ZIb+ajUY?!jnb}no{ro+DVHEK{Sk}^lk~s<5 z11~E=1Zyg{6ND4kn-&V8fv}X;k<43%ARP!@MuuQxN?CE9^H8lWk-*gm4ryb-RNc$x z`3h!F8+=BMBor*#T*-pX1!{{REHvI?Yb-rdzV9-xeJ$BjEpTmk1L3666F|v+f-REe zclhwU*Aw6n40)Ur;XDHZ)A+noE_)A3xR=z?8#27GEkWuIyEY9os~M8{@1#wNTLL{G05L=EDxx!~5D#`0vay6Z2Q?Im_*hBa^*^%S{apph!H-tnNqapn86D*OX zKv*bIAiVb|S?dulF3yH9o0Zh1?}_Qk^B8MG zs)V&H5!RRkx2$%q8As7>w;NTq8X0=@#J}@_8Vuk!FHQ)&5G^;I;ESm>T#_swH$r!g zoFrDj%P0)Pce3JBQvuw^w=-^UHccOr`BnIijZ)*k?F|V=Vy*>pvMyB1BtQNtNb(>> z3qclXRDXKYm*}Q-uLoo`x2asXqx`+tC~pb1*r08Eqxhg~`y}|vBm!n01_#^%PcA5w zu(l`AZ_TZSaevYaIIw*UgWfm}gW#X>C$=l