zsv 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +36 -0
- data/LICENSE +21 -0
- data/README.md +311 -0
- data/ext/zsv/common.h +34 -0
- data/ext/zsv/extconf.rb +137 -0
- data/ext/zsv/options.c +126 -0
- data/ext/zsv/options.h +31 -0
- data/ext/zsv/options_internal.h +8 -0
- data/ext/zsv/parser.c +300 -0
- data/ext/zsv/parser.h +62 -0
- data/ext/zsv/row.c +122 -0
- data/ext/zsv/row.h +39 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/2db.c +756 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/2json.c +381 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/2tsv.c +228 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/builtin/help.c +123 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/builtin/license.c +39 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/builtin/register.c +104 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/builtin/thirdparty.c +41 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/builtin/unregister.c +1 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/builtin/version.c +14 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/check/simdutf_wrapper.h +19 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/check/utf8.c +116 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/check.c +194 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/cli.c +796 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/cli_const.h +41 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/cli_export.h +16 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/cli_ini.c +280 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/cli_internal.h +36 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/compare.c +913 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/compare.h +23 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/compare_added_column.c +20 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/compare_internal.h +140 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/compare_sort.c +91 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/compare_unique_colname.c +81 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/count-pull.c +82 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/count.c +404 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/desc.c +569 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/echo.c +365 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/my_extension.c +366 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/mysheet_extension.c +341 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/ext_template/YOUR_EXTENSION_zsvext.c +263 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.c +298 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.h +157 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/json_numeric.c +177 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.c +444 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.h +145 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/utils.c +110 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/include/memfile.h +15 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/src/memfile.c +64 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sglib/sglib.h +1955 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/simdutf/simdutf.h +6802 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.c +230517 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.h +12174 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_and_csv_vtab.c +2 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.c +142 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.h +49 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-zsv.c +485 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab.c +1015 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3ext.h +663 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/vtab_helper.c +85 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_common.h +75 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_gen.h +167 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_parse.h +228 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_tree.h +186 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_version.h +23 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_common.h +76 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_gen.h +167 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_parse.h +238 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_tree.h +186 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl.c +184 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.c +52 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.h +34 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.c +103 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.h +57 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_bytestack.h +69 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.c +220 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.h +34 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_gen.c +362 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.c +764 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.h +117 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.c +508 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.h +78 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_tree.c +505 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_version.c +7 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/json_value.h +59 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/yajl_helper.h +208 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper.c +795 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper_internal.h +28 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/flatten.c +851 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/jq.c +106 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/jq.h +6 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/mv.c +113 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/noop.c +90 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/overwrite.c +295 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/paste.c +175 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/pretty.c +693 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/prop.c +980 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/rm.c +131 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/fixed.c +130 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/internal.h +118 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.c +45 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.h +41 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/processing.c +107 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/rand.c +20 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/regex.c +61 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/search.c +14 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/selection.c +192 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select/usage.c +72 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select-pull.c +812 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/select.c +753 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/serialize.c +372 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/curses.h +15 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/cursor.c +119 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/errors.c +45 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.c +63 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.h +12 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/filter.c +166 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers.c +214 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers_internal.h +128 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/help.c +43 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.c +81 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.h +25 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.c +325 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.h +73 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/lexer.c +203 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/newline_handler.c +7 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/pivot.c +318 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.c +134 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.h +119 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/read-data.c +322 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.c +203 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.h +36 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet-sql.c +167 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet_internal.h +36 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sqlfilter.c +153 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/terminfo.c +32 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.c +312 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.h +29 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/ui_buffer.c +266 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/usage.c +9 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet/utf8-width.c +60 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sheet.c +1007 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sql.c +453 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.c +101 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.h +49 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/stack.c +393 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/arg.c +322 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/cache.c +228 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/cat.c +91 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.c +240 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.h +63 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/clock.c +57 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/db.c +148 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs-no-jq.c +2 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs.c +427 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_from_json.c +253 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_to_json.c +121 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/dl.c +20 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/emcc/fs_api.c +159 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/err.c +24 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/file-mem.c +180 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/file.c +256 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.c +197 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.h +49 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/jq.c +400 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/json.c +120 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/mem.c +18 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/memmem.c +132 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/os.c +178 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite.c +258 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite_writer.c +246 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8-test.c +123 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.c +153 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.h +54 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/prop.c +267 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/signal.c +53 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/string.c +357 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dir_exists_longpath.c +83 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dl.c +33 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/fopen_longpath.c +184 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/foreach_dirent_longpath.c +292 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.c +259 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.h +13 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/mkdir_longpath.c +255 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/remove_longpath.c +96 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/utils/writer.c +361 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command.h +40 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command_standalone.c +16 -0
- data/ext/zsv/vendor/zsv-1.3.0/app/zsv_main.h +44 -0
- data/ext/zsv/vendor/zsv-1.3.0/examples/js/zsv_parser_api_dummy.c +3 -0
- data/ext/zsv/vendor/zsv-1.3.0/examples/lib/parse_by_chunk.c +100 -0
- data/ext/zsv/vendor/zsv-1.3.0/examples/lib/print_my_column.c +143 -0
- data/ext/zsv/vendor/zsv-1.3.0/examples/lib/pull.c +89 -0
- data/ext/zsv/vendor/zsv-1.3.0/examples/lib/simple.c +123 -0
- data/ext/zsv/vendor/zsv-1.3.0/fuzz/fuzz.c +16 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/api.h +336 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/common.h +361 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation.h +62 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation_private.h +113 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/sheet.h +73 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext.h +329 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/arg.h +90 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/cache.h +49 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/clock.h +36 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/compiler.h +58 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/db.h +19 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dirs.h +147 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dl.h +22 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/emcc/fs_api.h +28 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/err.h +22 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file-mem.h +17 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file.h +99 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/jq.h +65 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/json.h +19 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/mem.h +19 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/memmem.h +13 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/os.h +54 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite.h +71 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite_writer.h +53 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/prop.h +107 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/signal.h +18 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/sql.h +11 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/string.h +148 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/utf8.h +41 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/win/dl.h +25 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/writer.h +101 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv/zsv_export.h +33 -0
- data/ext/zsv/vendor/zsv-1.3.0/include/zsv.h +20 -0
- data/ext/zsv/vendor/zsv-1.3.0/src/vector_delim.c +60 -0
- data/ext/zsv/vendor/zsv-1.3.0/src/zsv.c +484 -0
- data/ext/zsv/vendor/zsv-1.3.0/src/zsv_internal.c +731 -0
- data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_delim.c +285 -0
- data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_fixed.c +88 -0
- data/ext/zsv/vendor/zsv-1.3.0/src/zsv_strencode.c +51 -0
- data/ext/zsv/zsv_ext.c +343 -0
- data/lib/zsv/version.rb +5 -0
- data/lib/zsv.rb +81 -0
- metadata +340 -0
|
@@ -0,0 +1,795 @@
|
|
|
1
|
+
#include <stdlib.h>
|
|
2
|
+
#include <math.h>
|
|
3
|
+
#include <errno.h>
|
|
4
|
+
#include <string.h>
|
|
5
|
+
|
|
6
|
+
#include "yajl_helper/yajl_helper.h"
|
|
7
|
+
#include "yajl_helper_internal.h"
|
|
8
|
+
|
|
9
|
+
static inline void *yh_memdup(const void *src, size_t n) {
|
|
10
|
+
void *m = calloc(1, n + 2);
|
|
11
|
+
if(n)
|
|
12
|
+
memcpy(m, src, n);
|
|
13
|
+
return m;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#include "yajl_helper/yajl_helper.h"
|
|
17
|
+
#include "yajl_helper/json_value.h"
|
|
18
|
+
|
|
19
|
+
#define YAJL_HELPER_LEVEL(st) (st->level - st->level_offset)
|
|
20
|
+
|
|
21
|
+
static void yajl_helper_clear(yajl_helper_t yh);
|
|
22
|
+
static void yajl_helper_pop(struct yajl_helper_parse_state *st) {
|
|
23
|
+
if(st->parent) {
|
|
24
|
+
struct yajl_helper_parse_state *parent = st->parent;
|
|
25
|
+
yajl_helper_clear(st);
|
|
26
|
+
*st = *parent;
|
|
27
|
+
free(parent);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
unsigned int yajl_helper_level_raw(struct yajl_helper_parse_state *st) {
|
|
32
|
+
return st->level;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
unsigned int yajl_helper_level_offset(struct yajl_helper_parse_state *st) {
|
|
36
|
+
return st->level_offset;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
unsigned int yajl_helper_level(struct yajl_helper_parse_state *st) {
|
|
40
|
+
return YAJL_HELPER_LEVEL(st);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
void yajl_helper_set_ctx(struct yajl_helper_parse_state *st, void *ctx) {
|
|
44
|
+
st->ctx = ctx;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
void *yajl_helper_ctx(struct yajl_helper_parse_state *st) {
|
|
48
|
+
return st->ctx;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* walk the current path and apply a user-defined function to each ancestor
|
|
53
|
+
* starting with the oldest
|
|
54
|
+
*/
|
|
55
|
+
void yajl_helper_walk_path(struct yajl_helper_parse_state *st,
|
|
56
|
+
void *ctx,
|
|
57
|
+
void (*func)(void *ctx, unsigned depth, char type, unsigned item_index, const char *map_key)) {
|
|
58
|
+
for(unsigned int i = 0; i < st->level; i++) {
|
|
59
|
+
switch(st->stack[i]) {
|
|
60
|
+
case '[':
|
|
61
|
+
func(ctx, i, st->stack[i], st->item_ind[i], NULL);
|
|
62
|
+
break;
|
|
63
|
+
case '{':
|
|
64
|
+
func(ctx, i, st->stack[i], st->item_ind[i], st->map_keys[i]);
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static void dump_path(void *ctx, unsigned depth, char type,
|
|
71
|
+
unsigned item_index, const char *map_key) {
|
|
72
|
+
(void)(depth);
|
|
73
|
+
FILE *out = ctx;
|
|
74
|
+
fwrite(&type,1,1,out);
|
|
75
|
+
if(type == '[')
|
|
76
|
+
fprintf(out, "%u]", item_index);
|
|
77
|
+
else if(map_key)
|
|
78
|
+
fwrite(map_key, 1, strlen(map_key), out);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Print the current path for e.g. error reporting
|
|
83
|
+
*/
|
|
84
|
+
void yajl_helper_dump_path(struct yajl_helper_parse_state *st, FILE *out) {
|
|
85
|
+
yajl_helper_walk_path(st, out, dump_path);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// yajl_helper_set_level_offset(): return error
|
|
89
|
+
int yajl_helper_set_level_offset(struct yajl_helper_parse_state *st, unsigned int offset) {
|
|
90
|
+
if(offset > st->level) {
|
|
91
|
+
fprintf(stderr, "yajl_helper_level_offset: level_offset may not exceed level\n");
|
|
92
|
+
return 1;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
st->level_offset = offset;
|
|
96
|
+
return 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
unsigned int yajl_helper_item_ind_at(struct yajl_helper_parse_state *st, unsigned int level) {
|
|
100
|
+
if(level < st->max_level)
|
|
101
|
+
return st->item_ind[level];
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
unsigned int yajl_helper_array_index_plus_1(struct yajl_helper_parse_state *st, unsigned int offset) {
|
|
106
|
+
if(offset > YAJL_HELPER_LEVEL(st))
|
|
107
|
+
return 0;
|
|
108
|
+
unsigned int level = st->level - offset;
|
|
109
|
+
if(level > 0 && st->stack[level-1] == '[' && level <= st->max_level)
|
|
110
|
+
return st->item_ind[level-1] + 1;
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
unsigned int yajl_helper_element_index_plus_1(struct yajl_helper_parse_state *st, unsigned int offset) {
|
|
115
|
+
if(offset > YAJL_HELPER_LEVEL(st))
|
|
116
|
+
return 0;
|
|
117
|
+
unsigned int level = st->level - offset;
|
|
118
|
+
if(level > 0 && strchr("{[", st->stack[level-1]) && level <= st->max_level)
|
|
119
|
+
return st->item_ind[level-1] + 1;
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
long long json_value_long(struct json_value *value, int *err) {
|
|
124
|
+
*err = 0;
|
|
125
|
+
if(!value)
|
|
126
|
+
*err = 1;
|
|
127
|
+
else {
|
|
128
|
+
switch(value->type) {
|
|
129
|
+
case json_value_bool:
|
|
130
|
+
return value->val.i ? 1 : 0;
|
|
131
|
+
case json_value_int:
|
|
132
|
+
return value->val.i;
|
|
133
|
+
case json_value_double:
|
|
134
|
+
return (long long)value->val.dbl;
|
|
135
|
+
case json_value_number_string:
|
|
136
|
+
if(value->strlen && value->strlen + 1 < 128) {
|
|
137
|
+
char buff[128];
|
|
138
|
+
size_t len = value->strlen >= sizeof(buff) ? sizeof(buff) - 1 : value->strlen;
|
|
139
|
+
memcpy(buff, value->val.s, len);
|
|
140
|
+
buff[len] = '\0';
|
|
141
|
+
errno = 0;
|
|
142
|
+
char *end;
|
|
143
|
+
long l = strtol(buff, &end, 10);
|
|
144
|
+
if(!(end && *end == '\0')) { // invalid
|
|
145
|
+
if(err)
|
|
146
|
+
*err = 1;
|
|
147
|
+
} else
|
|
148
|
+
return (long long)l;
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
default:
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
double json_value_dbl(struct json_value *value, int *err) {
|
|
159
|
+
if(!value)
|
|
160
|
+
*err = 1;
|
|
161
|
+
else {
|
|
162
|
+
switch(value->type) {
|
|
163
|
+
case json_value_bool:
|
|
164
|
+
return (double)value->val.i ? 1 : 0;
|
|
165
|
+
case json_value_int:
|
|
166
|
+
return (double)value->val.i;
|
|
167
|
+
case json_value_double:
|
|
168
|
+
return value->val.dbl;
|
|
169
|
+
case json_value_number_string:
|
|
170
|
+
if(value->strlen && value->strlen + 1 < 128) {
|
|
171
|
+
char buff[128];
|
|
172
|
+
memcpy(buff, value->val.s, value->strlen);
|
|
173
|
+
buff[value->strlen-1] = '\0';
|
|
174
|
+
errno = 0;
|
|
175
|
+
double d = strtod(buff, NULL);
|
|
176
|
+
if ((d == HUGE_VAL || d == -HUGE_VAL) && errno == ERANGE) // overflow
|
|
177
|
+
*err = 1;
|
|
178
|
+
else
|
|
179
|
+
return d;
|
|
180
|
+
}
|
|
181
|
+
break;
|
|
182
|
+
default:
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
char json_value_truthy(struct json_value *value) {
|
|
190
|
+
switch(value->type) {
|
|
191
|
+
case json_value_null:
|
|
192
|
+
return 0;
|
|
193
|
+
case json_value_bool:
|
|
194
|
+
case json_value_int:
|
|
195
|
+
return value->val.i ? 1 : 0;
|
|
196
|
+
case json_value_double:
|
|
197
|
+
return value->val.dbl ? 1 : 0;
|
|
198
|
+
case json_value_string:
|
|
199
|
+
case json_value_number_string:
|
|
200
|
+
if(value->strlen && value->strlen + 1 < 128) {
|
|
201
|
+
char buff[128];
|
|
202
|
+
memcpy(buff, value->val.s, value->strlen);
|
|
203
|
+
buff[value->strlen-1] = '\0';
|
|
204
|
+
errno = 0;
|
|
205
|
+
double d = strtod(buff, NULL);
|
|
206
|
+
if ((d == HUGE_VAL || d == -HUGE_VAL) && errno == ERANGE) // overflow
|
|
207
|
+
return 0;
|
|
208
|
+
return d ? 1 : 0;
|
|
209
|
+
}
|
|
210
|
+
break;
|
|
211
|
+
case json_value_error:
|
|
212
|
+
return 0;
|
|
213
|
+
}
|
|
214
|
+
return 0;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Print any error from the yajl parser
|
|
219
|
+
* Returns non-zero
|
|
220
|
+
*/
|
|
221
|
+
int yajl_helper_print_err(yajl_handle yajl,
|
|
222
|
+
unsigned char *last_parsed_buff,
|
|
223
|
+
size_t last_parsed_buff_len
|
|
224
|
+
) {
|
|
225
|
+
unsigned char *str = yajl_get_error(yajl, 1,
|
|
226
|
+
last_parsed_buff, last_parsed_buff_len);
|
|
227
|
+
if(str) {
|
|
228
|
+
fprintf(stderr, "Error parsing JSON: %s", (const char *)str);
|
|
229
|
+
yajl_free_error(yajl, str);
|
|
230
|
+
}
|
|
231
|
+
return 1;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const char *yajl_helper_map_key_at(struct yajl_helper_parse_state *st,
|
|
235
|
+
unsigned int level) {
|
|
236
|
+
if(level < st->max_level)
|
|
237
|
+
return st->map_keys[level];
|
|
238
|
+
return NULL;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
const char *yajl_helper_get_map_key(struct yajl_helper_parse_state *st, unsigned int offset) {
|
|
243
|
+
if(YAJL_HELPER_LEVEL(st) >= offset + 1) {
|
|
244
|
+
unsigned int level = st->level - offset;
|
|
245
|
+
if(level > 0 && st->stack[level-1] == '{' && level <= st->max_level)
|
|
246
|
+
return st->map_keys[level - 1];
|
|
247
|
+
}
|
|
248
|
+
return NULL;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
static char yajl_helper_got_path_aux(struct yajl_helper_parse_state *st, unsigned int level, const char *path) {
|
|
252
|
+
for(unsigned i = 1; *path && i <= level; path++, i++) {
|
|
253
|
+
unsigned this_level = st->level_offset + i;
|
|
254
|
+
switch(*path) {
|
|
255
|
+
case '{':
|
|
256
|
+
case '[':
|
|
257
|
+
if(st->stack[this_level - 1] != *path)
|
|
258
|
+
return 0;
|
|
259
|
+
|
|
260
|
+
if(*path == '{' && path[1]) { // check map key
|
|
261
|
+
const char *map_key = st->map_keys[this_level - 1];
|
|
262
|
+
size_t len = strlen(map_key);
|
|
263
|
+
if(path[1] == '*' && (!path[2] || path[2] == '{' || path[2] == '['))
|
|
264
|
+
path++;
|
|
265
|
+
else {
|
|
266
|
+
if(strncmp(map_key, path + 1, len) || (*(path + 1 + len) && !strchr("{[*", *(path + 1 + len))))
|
|
267
|
+
return 0;
|
|
268
|
+
path += len;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
break;
|
|
272
|
+
default: // map key start
|
|
273
|
+
return 0;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return 1;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
char yajl_helper_got_path(struct yajl_helper_parse_state *st, unsigned int level, const char *path) {
|
|
280
|
+
if(YAJL_HELPER_LEVEL(st) != level)
|
|
281
|
+
return 0;
|
|
282
|
+
return yajl_helper_got_path_aux(st, level, path);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
char yajl_helper_got_path_prefix(struct yajl_helper_parse_state *st, unsigned int level, const char *path) {
|
|
286
|
+
if(YAJL_HELPER_LEVEL(st) < level)
|
|
287
|
+
return 0;
|
|
288
|
+
return yajl_helper_got_path_aux(st, level, path);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// return '[' or '{' to indicate the object type at the given level
|
|
292
|
+
char yajl_helper_stack_at(struct yajl_helper_parse_state *st, unsigned level) {
|
|
293
|
+
if(level < st->max_level)
|
|
294
|
+
return st->stack[level];
|
|
295
|
+
return '\0';
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
char yajl_helper_path_is(struct yajl_helper_parse_state *st, const char *path) {
|
|
299
|
+
unsigned int level = 0;
|
|
300
|
+
for(int i = 0; path[i]; i++)
|
|
301
|
+
if(path[i] == '{' || path[i] == '[')
|
|
302
|
+
level++;
|
|
303
|
+
return yajl_helper_got_path(st, level, path);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
static int yajl_helper_start_array(void *ctx) {
|
|
307
|
+
struct yajl_helper_parse_state *st = ctx;
|
|
308
|
+
if(st->level < st->max_level) {
|
|
309
|
+
st->stack[st->level] = '[';
|
|
310
|
+
st->item_ind[st->level] = 0;
|
|
311
|
+
}
|
|
312
|
+
st->level++;
|
|
313
|
+
|
|
314
|
+
if(st->start_array)
|
|
315
|
+
return st->start_array(st);
|
|
316
|
+
|
|
317
|
+
return 1;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
static int yajl_helper_end_array(void *ctx) {
|
|
321
|
+
struct yajl_helper_parse_state *st = ctx;
|
|
322
|
+
st->level--;
|
|
323
|
+
if(st->level && strchr("[{", st->stack[st->level-1]) && st->level <= st->max_level)
|
|
324
|
+
st->item_ind[st->level-1]++;
|
|
325
|
+
|
|
326
|
+
int rc = 1;
|
|
327
|
+
if(st->end_array)
|
|
328
|
+
rc = st->end_array(st);
|
|
329
|
+
|
|
330
|
+
if(st->level_offset > st->level) {
|
|
331
|
+
fprintf(stderr, "yajl_helper_end_array: level_offset exceeds level\n");
|
|
332
|
+
return 0;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if(st->level == 0 && st->parent)
|
|
336
|
+
yajl_helper_pop(st);
|
|
337
|
+
|
|
338
|
+
return rc;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
static int yajl_helper_start_map(void *ctx) {
|
|
342
|
+
struct yajl_helper_parse_state *st = ctx;
|
|
343
|
+
if(st->level < st->max_level) {
|
|
344
|
+
st->stack[st->level] = '{';
|
|
345
|
+
st->item_ind[st->level] = 0;
|
|
346
|
+
}
|
|
347
|
+
st->level++;
|
|
348
|
+
|
|
349
|
+
if(st->start_map)
|
|
350
|
+
return st->start_map(st);
|
|
351
|
+
|
|
352
|
+
return 1;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
static int yajl_helper_end_map(void *ctx) {
|
|
356
|
+
struct yajl_helper_parse_state *st = ctx;
|
|
357
|
+
st->level--;
|
|
358
|
+
if(st->level < st->max_level && st->map_keys[st->level]) {
|
|
359
|
+
free(st->map_keys[st->level]);
|
|
360
|
+
st->map_keys[st->level] = NULL;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if(st->level && strchr("{[", st->stack[st->level-1]) && st->level <= st->max_level)
|
|
364
|
+
st->item_ind[st->level-1]++;
|
|
365
|
+
|
|
366
|
+
int rc = 1;
|
|
367
|
+
if(st->end_map)
|
|
368
|
+
rc = st->end_map(st);
|
|
369
|
+
|
|
370
|
+
if(st->level_offset > st->level) {
|
|
371
|
+
fprintf(stderr, "yajl_helper_end_map: level_offset exceeds level\n");
|
|
372
|
+
return 0;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if(st->level == 0 && st->parent)
|
|
376
|
+
yajl_helper_pop(st);
|
|
377
|
+
|
|
378
|
+
return rc;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
static int yajl_helper_map_key(void *ctx, const unsigned char *stringVal, size_t len) {
|
|
382
|
+
struct yajl_helper_parse_state *st = ctx;
|
|
383
|
+
if(st->level <= st->max_level) {
|
|
384
|
+
if(st->map_keys[st->level - 1])
|
|
385
|
+
free(st->map_keys[st->level - 1]);
|
|
386
|
+
char *str;
|
|
387
|
+
if((st->map_keys[st->level - 1] = str = malloc(1 + len))) {
|
|
388
|
+
memcpy(str, stringVal, len);
|
|
389
|
+
str[len] = '\0';
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if(st->map_key)
|
|
394
|
+
return st->map_key(st, stringVal, len);
|
|
395
|
+
|
|
396
|
+
return 1;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
static inline int process_value(struct yajl_helper_parse_state *st,
|
|
400
|
+
struct json_value *v) {
|
|
401
|
+
int rc = 1;
|
|
402
|
+
if(st->value) {
|
|
403
|
+
rc = st->value(st, v);
|
|
404
|
+
if(st->level && strchr("{[", st->stack[st->level-1]) && st->level <= st->max_level)
|
|
405
|
+
st->item_ind[st->level-1]++;
|
|
406
|
+
}
|
|
407
|
+
if(st->level == 0 && st->parent)
|
|
408
|
+
yajl_helper_pop(st);
|
|
409
|
+
return rc;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
static int yajl_helper_number_str(void * ctx, const char * numberVal,
|
|
413
|
+
size_t numberLen) {
|
|
414
|
+
struct json_value value;
|
|
415
|
+
value.type = json_value_number_string;
|
|
416
|
+
value.val.s = (unsigned char *)numberVal;
|
|
417
|
+
value.strlen = numberLen;
|
|
418
|
+
return process_value((struct yajl_helper_parse_state *)ctx, &value);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/* unified calls to a single yajl_helper_value */
|
|
422
|
+
static int yajl_helper_string(void *ctx, const unsigned char *stringVal, size_t len) {
|
|
423
|
+
struct json_value value;
|
|
424
|
+
value.type = json_value_string;
|
|
425
|
+
value.val.s = (unsigned char *)stringVal;
|
|
426
|
+
value.strlen = len;
|
|
427
|
+
return process_value((struct yajl_helper_parse_state *)ctx, &value);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
static int yajl_helper_double(void *ctx, double d) {
|
|
431
|
+
struct json_value value;
|
|
432
|
+
value.type = json_value_double;
|
|
433
|
+
value.val.dbl = d;
|
|
434
|
+
return process_value((struct yajl_helper_parse_state *)ctx, &value);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
static int yajl_helper_int(void *ctx, long long integerVal) {
|
|
438
|
+
struct json_value value;
|
|
439
|
+
value.type = json_value_int;
|
|
440
|
+
value.val.i = integerVal;
|
|
441
|
+
return process_value((struct yajl_helper_parse_state *)ctx, &value);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
static int yajl_helper_bool(void *ctx, int boolean) {
|
|
445
|
+
struct json_value value;
|
|
446
|
+
value.type = json_value_bool;
|
|
447
|
+
value.val.i = boolean ? 1 : 0;
|
|
448
|
+
return process_value((struct yajl_helper_parse_state *)ctx, &value);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
static int yajl_helper_null(void *ctx) {
|
|
452
|
+
struct json_value value;
|
|
453
|
+
value.type = json_value_null;
|
|
454
|
+
return process_value((struct yajl_helper_parse_state *)ctx, &value);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
static int yajl_helper_error(void * ctx, const unsigned char *buf,
|
|
458
|
+
size_t bufLen, int err_no) {
|
|
459
|
+
(void)(err_no);
|
|
460
|
+
struct yajl_helper_parse_state *st = ctx;
|
|
461
|
+
|
|
462
|
+
if(!st->value)
|
|
463
|
+
return 0; // stop parsing
|
|
464
|
+
|
|
465
|
+
struct json_value value;
|
|
466
|
+
value.type = json_value_error;
|
|
467
|
+
value.val.s = (unsigned char *)buf;
|
|
468
|
+
value.strlen = bufLen;
|
|
469
|
+
return process_value((struct yajl_helper_parse_state *)ctx, &value);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
static void yajl_helper_callbacks_init(yajl_callbacks *callbacks, char nums_as_strings) {
|
|
473
|
+
yajl_callbacks x = {
|
|
474
|
+
yajl_helper_null,
|
|
475
|
+
yajl_helper_bool,
|
|
476
|
+
yajl_helper_int,
|
|
477
|
+
yajl_helper_double,
|
|
478
|
+
nums_as_strings ? yajl_helper_number_str : NULL,
|
|
479
|
+
yajl_helper_string,
|
|
480
|
+
yajl_helper_start_map,
|
|
481
|
+
yajl_helper_map_key,
|
|
482
|
+
yajl_helper_end_map,
|
|
483
|
+
yajl_helper_start_array,
|
|
484
|
+
yajl_helper_end_array,
|
|
485
|
+
yajl_helper_error
|
|
486
|
+
};
|
|
487
|
+
memcpy(callbacks, &x, sizeof(x));
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// return error
|
|
491
|
+
static int yajl_helper_allocate_stack(yajl_helper_t yh, unsigned sz) {
|
|
492
|
+
char *stack = calloc(yh->max_level, sizeof(char));
|
|
493
|
+
char **map_keys = calloc(yh->max_level, sizeof(char *));
|
|
494
|
+
unsigned int *item_ind = calloc(yh->max_level, sizeof(*yh->item_ind));
|
|
495
|
+
if(stack && map_keys && item_ind) {
|
|
496
|
+
yh->stack = stack;
|
|
497
|
+
yh->map_keys = map_keys;
|
|
498
|
+
yh->item_ind = item_ind;
|
|
499
|
+
return 0;
|
|
500
|
+
}
|
|
501
|
+
// out of memory!
|
|
502
|
+
free(stack);
|
|
503
|
+
free(map_keys);
|
|
504
|
+
free(item_ind);
|
|
505
|
+
return 1;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
static void yajl_helper_free_stack(yajl_helper_t yh) {
|
|
509
|
+
if(yh->map_keys) {
|
|
510
|
+
for(unsigned int i = 0; i < yh->max_level; i++)
|
|
511
|
+
free(yh->map_keys[i]);
|
|
512
|
+
}
|
|
513
|
+
free(yh->stack);
|
|
514
|
+
free(yh->map_keys);
|
|
515
|
+
free(yh->item_ind);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
yajl_helper_t yajl_helper_new_w_params(struct yajl_helper_params *p) {
|
|
519
|
+
yajl_helper_t yh = calloc(1, sizeof(*yh));
|
|
520
|
+
if(yh) {
|
|
521
|
+
yh->max_level = p->max_level ? p->max_level : 32;
|
|
522
|
+
if(!yajl_helper_allocate_stack(yh, yh->max_level)) {
|
|
523
|
+
if(!p->parent) {
|
|
524
|
+
yh->yajl = yajl_alloc(&yh->callbacks, NULL, yh);
|
|
525
|
+
yajl_helper_callbacks_init(&yh->callbacks, 0);
|
|
526
|
+
}
|
|
527
|
+
yh->start_map = p->start_map;
|
|
528
|
+
yh->end_map = p->end_map;
|
|
529
|
+
yh->map_key = p->map_key;
|
|
530
|
+
yh->start_array = p->start_array;
|
|
531
|
+
yh->end_array = p->end_array;
|
|
532
|
+
yh->value = p->value;
|
|
533
|
+
yh->ctx = p->ctx;
|
|
534
|
+
yh->ctx_destructor = p->ctx_destructor;
|
|
535
|
+
if(p->parent) {
|
|
536
|
+
yh->yajl = p->parent->yajl;
|
|
537
|
+
yh->callbacks = p->parent->callbacks;
|
|
538
|
+
// swap parent and yh data, then set parent->parent = yh
|
|
539
|
+
// and yh->parent = parent->parent
|
|
540
|
+
yajl_helper_t yh_parent = p->parent->parent;
|
|
541
|
+
struct yajl_helper_parse_state tmp = *yh;
|
|
542
|
+
*yh = *p->parent;
|
|
543
|
+
*p->parent = tmp;
|
|
544
|
+
p->parent->parent = yh;
|
|
545
|
+
yh->parent = yh_parent;
|
|
546
|
+
}
|
|
547
|
+
return yh;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
// Error (e.g. out of mem)
|
|
551
|
+
yajl_helper_delete(yh);
|
|
552
|
+
return NULL;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
yajl_helper_t yajl_helper_new(
|
|
556
|
+
unsigned int max_level,
|
|
557
|
+
int (*start_map)(struct yajl_helper_parse_state *),
|
|
558
|
+
int (*end_map)(struct yajl_helper_parse_state *),
|
|
559
|
+
int (*map_key)(struct yajl_helper_parse_state *,
|
|
560
|
+
const unsigned char *, size_t),
|
|
561
|
+
int (*start_array)(struct yajl_helper_parse_state *),
|
|
562
|
+
int (*end_array)(struct yajl_helper_parse_state *),
|
|
563
|
+
int (*value)(struct yajl_helper_parse_state *,
|
|
564
|
+
struct json_value *),
|
|
565
|
+
void *ctx
|
|
566
|
+
) {
|
|
567
|
+
struct yajl_helper_params p = { 0 };
|
|
568
|
+
p.max_level = max_level;
|
|
569
|
+
p.start_map = start_map;
|
|
570
|
+
p.end_map = end_map;
|
|
571
|
+
p.map_key = map_key;
|
|
572
|
+
p.start_array = start_array;
|
|
573
|
+
p.end_array = end_array;
|
|
574
|
+
p.value = value;
|
|
575
|
+
p.ctx = ctx;
|
|
576
|
+
return yajl_helper_new_w_params(&p);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
void yajl_helper_set_ctx_destructor(yajl_helper_t yh,
|
|
580
|
+
void (*destructor)(void *)) {
|
|
581
|
+
yh->ctx_destructor = destructor;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
yajl_handle yajl_helper_yajl(yajl_helper_t yh) {
|
|
585
|
+
if(yh)
|
|
586
|
+
return yh->yajl;
|
|
587
|
+
return NULL;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
static void yajl_helper_clear(yajl_helper_t yh) {
|
|
591
|
+
if(yh) {
|
|
592
|
+
if(yh->ctx_destructor)
|
|
593
|
+
yh->ctx_destructor(yh->ctx);
|
|
594
|
+
yajl_helper_free_stack(yh);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
void yajl_helper_delete(yajl_helper_t yh) {
|
|
599
|
+
if(yh) {
|
|
600
|
+
while(yh->parent) // delete all nested contexts
|
|
601
|
+
yajl_helper_pop(yh);
|
|
602
|
+
|
|
603
|
+
// delete self
|
|
604
|
+
yajl_helper_clear(yh);
|
|
605
|
+
if(yh->yajl)
|
|
606
|
+
yajl_free(yh->yajl);
|
|
607
|
+
free(yh);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
///// misc
|
|
612
|
+
|
|
613
|
+
size_t json_value_default_string(struct json_value *value, const unsigned char **target,
|
|
614
|
+
size_t *len) {
|
|
615
|
+
switch(value->type) {
|
|
616
|
+
case json_value_string:
|
|
617
|
+
case json_value_number_string:
|
|
618
|
+
*target = value->val.s;
|
|
619
|
+
*len = value->strlen;
|
|
620
|
+
break;
|
|
621
|
+
case json_value_null:
|
|
622
|
+
*target = NULL;
|
|
623
|
+
*len = 0;
|
|
624
|
+
break;
|
|
625
|
+
default:
|
|
626
|
+
*target = (unsigned char *)"";
|
|
627
|
+
*len = 0;
|
|
628
|
+
break;
|
|
629
|
+
}
|
|
630
|
+
return *len;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
size_t json_value_to_string_dup(struct json_value *value, char **target, char convert) {
|
|
634
|
+
struct json_value_string jvs;
|
|
635
|
+
json_value_to_string(value, &jvs, convert);
|
|
636
|
+
|
|
637
|
+
if(target) {
|
|
638
|
+
char *dupe = jvs.len && jvs.s ? yh_memdup(jvs.s, jvs.len) : NULL;
|
|
639
|
+
if(*target)
|
|
640
|
+
free(*target);
|
|
641
|
+
*target = dupe;
|
|
642
|
+
}
|
|
643
|
+
return jvs.len;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/*
|
|
647
|
+
json_value_to_string: return string representation of json value
|
|
648
|
+
will use provided buff if necessary
|
|
649
|
+
returns length of string
|
|
650
|
+
ex:
|
|
651
|
+
struct json_value_string jvs;
|
|
652
|
+
fprintf(stderr, "my value: %.*s\n", json_value_default_string2(v, &jvs), jvs.s);
|
|
653
|
+
*/
|
|
654
|
+
size_t json_value_to_string(struct json_value *value, struct json_value_string *jvs, char convert_if_not_str) {
|
|
655
|
+
switch(value->type) {
|
|
656
|
+
case json_value_string:
|
|
657
|
+
case json_value_number_string:
|
|
658
|
+
jvs->len = value->strlen;
|
|
659
|
+
jvs->s = value->val.s;
|
|
660
|
+
break;
|
|
661
|
+
default:
|
|
662
|
+
if(!convert_if_not_str) {
|
|
663
|
+
jvs->s = (unsigned char *)"";
|
|
664
|
+
jvs->len = 0;
|
|
665
|
+
} else {
|
|
666
|
+
switch(value->type) {
|
|
667
|
+
case json_value_bool:
|
|
668
|
+
if(value->val.i)
|
|
669
|
+
jvs->s = (unsigned char *)"true";
|
|
670
|
+
else
|
|
671
|
+
jvs->s = (unsigned char *)"false";
|
|
672
|
+
jvs->len = strlen((const char *)jvs->s);
|
|
673
|
+
break;
|
|
674
|
+
case json_value_int:
|
|
675
|
+
case json_value_double:
|
|
676
|
+
{
|
|
677
|
+
int n;
|
|
678
|
+
if(value->type == json_value_int)
|
|
679
|
+
n = snprintf((char *)jvs->_internal, sizeof(jvs->_internal), "%lli", value->val.i);
|
|
680
|
+
else
|
|
681
|
+
n = snprintf((char *)jvs->_internal, sizeof(jvs->_internal), "%lf", value->val.dbl);
|
|
682
|
+
|
|
683
|
+
if(n > 0 && (size_t)n < sizeof(jvs->_internal)) {
|
|
684
|
+
jvs->len = n;
|
|
685
|
+
jvs->s = jvs->_internal;
|
|
686
|
+
} else {
|
|
687
|
+
jvs->s = (unsigned char *)"";
|
|
688
|
+
jvs->len = 0;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
break;
|
|
692
|
+
default:
|
|
693
|
+
jvs->s = (unsigned char *)"";
|
|
694
|
+
jvs->len = 0;
|
|
695
|
+
break;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
return jvs->len;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
unsigned char *json_str_dup_if_len(struct json_value *value) {
|
|
703
|
+
return json_str_dup_if_len_buff(value, NULL, 0);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
unsigned char *json_str_dup_if_len_buff(struct json_value *value, unsigned char *buff, size_t bufflen) {
|
|
707
|
+
const unsigned char *src;
|
|
708
|
+
size_t len;
|
|
709
|
+
json_value_default_string(value, &src, &len);
|
|
710
|
+
if(len && *src) {
|
|
711
|
+
if(len < bufflen) {
|
|
712
|
+
memcpy(buff, src, len);
|
|
713
|
+
buff[len] = '\0';
|
|
714
|
+
return buff;
|
|
715
|
+
}
|
|
716
|
+
return yh_memdup(src, len);
|
|
717
|
+
}
|
|
718
|
+
return NULL;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
void json_value_delete(struct json_value **valuep) {
|
|
722
|
+
if(*valuep)
|
|
723
|
+
json_value_free(*valuep);
|
|
724
|
+
*valuep = NULL;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
struct json_value *json_value_copy(struct json_value *value) {
|
|
728
|
+
struct json_value *new_value = calloc(1, sizeof(*new_value));
|
|
729
|
+
if(new_value)
|
|
730
|
+
json_value_dup(new_value, value);
|
|
731
|
+
return new_value;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
#ifdef YAJL_HELPER_UTILS
|
|
735
|
+
void *linkedlist_reverse(void *p) {
|
|
736
|
+
struct struct_list *sl = (struct struct_list *)p;
|
|
737
|
+
struct struct_list *next1, *next2;
|
|
738
|
+
|
|
739
|
+
/*
|
|
740
|
+
a->b->c->d;
|
|
741
|
+
a b c->d;
|
|
742
|
+
a<-b c->d;
|
|
743
|
+
a = b, b = c, c = d;
|
|
744
|
+
*/
|
|
745
|
+
|
|
746
|
+
if(!sl || !sl->next)
|
|
747
|
+
return sl;
|
|
748
|
+
else
|
|
749
|
+
for(next1 = sl->next, next2 = (sl->next ? sl->next->next : NULL), sl->next = NULL; next2; sl = next1, next1 = next2, next2 = next2->next)
|
|
750
|
+
next1->next = sl;
|
|
751
|
+
|
|
752
|
+
next1->next = sl;
|
|
753
|
+
return next1;
|
|
754
|
+
}
|
|
755
|
+
#endif
|
|
756
|
+
|
|
757
|
+
///// ----- string_list
|
|
758
|
+
char add_string_to_array(struct string_list **head, struct json_value *value) {
|
|
759
|
+
const unsigned char *src;
|
|
760
|
+
size_t len;
|
|
761
|
+
json_value_default_string(value, &src, &len);
|
|
762
|
+
struct string_list *e = malloc(sizeof(*e));
|
|
763
|
+
e->next = *head;
|
|
764
|
+
e->value = src ? yh_memdup(src, len) : NULL;
|
|
765
|
+
*head = e;
|
|
766
|
+
return (e->value ? 1 : 0);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
void string_list_free(struct string_list *e) {
|
|
770
|
+
struct string_list *n;
|
|
771
|
+
for( ; e; e = n) {
|
|
772
|
+
n = e->next;
|
|
773
|
+
if(e->value)
|
|
774
|
+
free(e->value);
|
|
775
|
+
free(e);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
/// ---- int_list
|
|
780
|
+
void add_int_to_array(struct int_list **head, struct json_value *value) {
|
|
781
|
+
struct int_list *e = malloc(sizeof(*e));
|
|
782
|
+
e->next = *head;
|
|
783
|
+
e->i = (value && value->type == json_value_int ? value->val.i : -1);
|
|
784
|
+
*head = e;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
void int_list_free(struct int_list *e) {
|
|
788
|
+
struct int_list *n;
|
|
789
|
+
for( ; e; e = n) {
|
|
790
|
+
n = e->next;
|
|
791
|
+
free(e);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
// #include "yajl_helper_switch.c"
|