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
data/ext/zsv/zsv_ext.c
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/* Main entry point for zsv Ruby extension */
|
|
2
|
+
#include "common.h"
|
|
3
|
+
#include "options.h"
|
|
4
|
+
#include "options_internal.h"
|
|
5
|
+
#include "parser.h"
|
|
6
|
+
#include "row.h"
|
|
7
|
+
|
|
8
|
+
/* Module and class definitions */
|
|
9
|
+
VALUE mZSV = Qnil;
|
|
10
|
+
VALUE cParser = Qnil;
|
|
11
|
+
VALUE eZSVError = Qnil;
|
|
12
|
+
VALUE eMalformedCSVError = Qnil;
|
|
13
|
+
VALUE eInvalidEncodingError = Qnil;
|
|
14
|
+
|
|
15
|
+
/* GC marking function for Parser */
|
|
16
|
+
static void zsv_parser_mark(void *ptr)
|
|
17
|
+
{
|
|
18
|
+
zsv_ruby_parser_t *parser = (zsv_ruby_parser_t *)ptr;
|
|
19
|
+
if (!parser)
|
|
20
|
+
return;
|
|
21
|
+
|
|
22
|
+
rb_gc_mark(parser->io);
|
|
23
|
+
rb_gc_mark(parser->headers);
|
|
24
|
+
rb_gc_mark(parser->current_row);
|
|
25
|
+
rb_gc_mark(parser->row_buffer);
|
|
26
|
+
rb_gc_mark(parser->options.header_array);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* GC freeing function for Parser */
|
|
30
|
+
static void zsv_parser_gc_free(void *ptr)
|
|
31
|
+
{
|
|
32
|
+
zsv_parser_free((zsv_ruby_parser_t *)ptr);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* Size function for GC */
|
|
36
|
+
static size_t zsv_parser_memsize(const void *ptr)
|
|
37
|
+
{
|
|
38
|
+
return ptr ? sizeof(zsv_ruby_parser_t) : 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* Data type definition */
|
|
42
|
+
static const rb_data_type_t zsv_parser_type = {
|
|
43
|
+
.wrap_struct_name = "ZSV::Parser",
|
|
44
|
+
.function =
|
|
45
|
+
{
|
|
46
|
+
.dmark = zsv_parser_mark,
|
|
47
|
+
.dfree = zsv_parser_gc_free,
|
|
48
|
+
.dsize = zsv_parser_memsize,
|
|
49
|
+
},
|
|
50
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/* Unwrap parser from Ruby object */
|
|
54
|
+
static zsv_ruby_parser_t *get_parser(VALUE self)
|
|
55
|
+
{
|
|
56
|
+
zsv_ruby_parser_t *parser;
|
|
57
|
+
TypedData_Get_Struct(self, zsv_ruby_parser_t, &zsv_parser_type, parser);
|
|
58
|
+
return parser;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* Wrap parser in Ruby object */
|
|
62
|
+
static VALUE wrap_parser(zsv_ruby_parser_t *parser)
|
|
63
|
+
{
|
|
64
|
+
return TypedData_Wrap_Struct(cParser, &zsv_parser_type, parser);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Allocate function for Parser class */
|
|
68
|
+
static VALUE zsv_parser_alloc(VALUE klass)
|
|
69
|
+
{
|
|
70
|
+
return TypedData_Wrap_Struct(klass, &zsv_parser_type, NULL);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/*
|
|
74
|
+
* call-seq:
|
|
75
|
+
* ZSV::Parser.new(io, **options) -> parser
|
|
76
|
+
*
|
|
77
|
+
* Creates a new parser for the given IO object.
|
|
78
|
+
*/
|
|
79
|
+
static VALUE rb_zsv_parser_initialize(int argc, VALUE *argv, VALUE self)
|
|
80
|
+
{
|
|
81
|
+
VALUE io, opts;
|
|
82
|
+
rb_scan_args(argc, argv, "11", &io, &opts);
|
|
83
|
+
|
|
84
|
+
zsv_ruby_parser_t *parser;
|
|
85
|
+
|
|
86
|
+
if (TYPE(io) == T_STRING) {
|
|
87
|
+
const char *str = StringValueCStr(io);
|
|
88
|
+
|
|
89
|
+
/* Detect if it's a file path or CSV content */
|
|
90
|
+
/* If it contains newlines or commas and doesn't exist as a file, treat as CSV data */
|
|
91
|
+
if (strchr(str, '\n') != NULL || strchr(str, ',') != NULL) {
|
|
92
|
+
/* Looks like CSV content, parse as string */
|
|
93
|
+
parser = zsv_parser_new_from_string(io, opts);
|
|
94
|
+
} else {
|
|
95
|
+
/* Try as file path */
|
|
96
|
+
parser = zsv_parser_new_from_path(str, opts);
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
/* IO object */
|
|
100
|
+
parser = zsv_parser_new_from_io(io, opts);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
DATA_PTR(self) = parser;
|
|
104
|
+
return self;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/*
|
|
108
|
+
* call-seq:
|
|
109
|
+
* parser.shift -> array or hash or nil
|
|
110
|
+
*
|
|
111
|
+
* Reads and returns the next row. Returns nil at EOF.
|
|
112
|
+
*/
|
|
113
|
+
static VALUE rb_zsv_parser_shift(VALUE self)
|
|
114
|
+
{
|
|
115
|
+
zsv_ruby_parser_t *parser = get_parser(self);
|
|
116
|
+
return zsv_parser_shift(parser);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/*
|
|
120
|
+
* call-seq:
|
|
121
|
+
* parser.each {|row| block } -> nil
|
|
122
|
+
* parser.each -> enumerator
|
|
123
|
+
*
|
|
124
|
+
* Iterates over all rows.
|
|
125
|
+
*/
|
|
126
|
+
static VALUE rb_zsv_parser_each(VALUE self)
|
|
127
|
+
{
|
|
128
|
+
RETURN_ENUMERATOR(self, 0, 0);
|
|
129
|
+
|
|
130
|
+
zsv_ruby_parser_t *parser = get_parser(self);
|
|
131
|
+
zsv_parser_each(parser);
|
|
132
|
+
return Qnil;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/*
|
|
136
|
+
* call-seq:
|
|
137
|
+
* parser.rewind -> nil
|
|
138
|
+
*
|
|
139
|
+
* Rewinds the parser to the beginning.
|
|
140
|
+
*/
|
|
141
|
+
static VALUE rb_zsv_parser_rewind(VALUE self)
|
|
142
|
+
{
|
|
143
|
+
zsv_ruby_parser_t *parser = get_parser(self);
|
|
144
|
+
zsv_parser_rewind(parser);
|
|
145
|
+
return Qnil;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/*
|
|
149
|
+
* call-seq:
|
|
150
|
+
* parser.close -> nil
|
|
151
|
+
*
|
|
152
|
+
* Closes the parser and releases resources.
|
|
153
|
+
*/
|
|
154
|
+
static VALUE rb_zsv_parser_close(VALUE self)
|
|
155
|
+
{
|
|
156
|
+
zsv_ruby_parser_t *parser = get_parser(self);
|
|
157
|
+
zsv_parser_close(parser);
|
|
158
|
+
return Qnil;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/*
|
|
162
|
+
* call-seq:
|
|
163
|
+
* parser.headers -> array or nil
|
|
164
|
+
*
|
|
165
|
+
* Returns the headers if header mode is enabled.
|
|
166
|
+
*/
|
|
167
|
+
static VALUE rb_zsv_parser_headers_get(VALUE self)
|
|
168
|
+
{
|
|
169
|
+
zsv_ruby_parser_t *parser = get_parser(self);
|
|
170
|
+
return zsv_parser_headers(parser);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/*
|
|
174
|
+
* call-seq:
|
|
175
|
+
* parser.closed? -> bool
|
|
176
|
+
*
|
|
177
|
+
* Returns true if the parser is closed.
|
|
178
|
+
*/
|
|
179
|
+
static VALUE rb_zsv_parser_closed_p(VALUE self)
|
|
180
|
+
{
|
|
181
|
+
zsv_ruby_parser_t *parser = get_parser(self);
|
|
182
|
+
return zsv_parser_closed(parser) ? Qtrue : Qfalse;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/*
|
|
186
|
+
* call-seq:
|
|
187
|
+
* ZSV.foreach(path, **options) {|row| block } -> nil
|
|
188
|
+
* ZSV.foreach(path, **options) -> enumerator
|
|
189
|
+
*
|
|
190
|
+
* Efficiently streams rows from a CSV file.
|
|
191
|
+
*/
|
|
192
|
+
static VALUE rb_zsv_foreach(int argc, VALUE *argv, VALUE klass)
|
|
193
|
+
{
|
|
194
|
+
VALUE path, opts;
|
|
195
|
+
rb_scan_args(argc, argv, "11", &path, &opts);
|
|
196
|
+
|
|
197
|
+
RETURN_ENUMERATOR(klass, argc, argv);
|
|
198
|
+
|
|
199
|
+
Check_Type(path, T_STRING);
|
|
200
|
+
|
|
201
|
+
zsv_ruby_parser_t *parser = zsv_parser_new_from_path(StringValueCStr(path), opts);
|
|
202
|
+
VALUE parser_obj = wrap_parser(parser);
|
|
203
|
+
|
|
204
|
+
/* Ensure cleanup even if exception occurs */
|
|
205
|
+
int state;
|
|
206
|
+
rb_protect((VALUE(*)(VALUE))rb_zsv_parser_each, parser_obj, &state);
|
|
207
|
+
|
|
208
|
+
zsv_parser_close(parser);
|
|
209
|
+
|
|
210
|
+
if (state) {
|
|
211
|
+
rb_jump_tag(state);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return Qnil;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/*
|
|
218
|
+
* call-seq:
|
|
219
|
+
* ZSV.parse(string, **options) -> array
|
|
220
|
+
*
|
|
221
|
+
* Parses a CSV string and returns all rows as an array.
|
|
222
|
+
*/
|
|
223
|
+
static VALUE rb_zsv_parse(int argc, VALUE *argv, VALUE klass)
|
|
224
|
+
{
|
|
225
|
+
VALUE string, opts;
|
|
226
|
+
rb_scan_args(argc, argv, "11", &string, &opts);
|
|
227
|
+
|
|
228
|
+
Check_Type(string, T_STRING);
|
|
229
|
+
|
|
230
|
+
zsv_ruby_parser_t *parser = zsv_parser_new_from_string(string, opts);
|
|
231
|
+
VALUE result = rb_ary_new();
|
|
232
|
+
|
|
233
|
+
VALUE row;
|
|
234
|
+
while (!NIL_P(row = zsv_parser_shift(parser))) {
|
|
235
|
+
rb_ary_push(result, row);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
zsv_parser_free(parser);
|
|
239
|
+
return result;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/*
|
|
243
|
+
* call-seq:
|
|
244
|
+
* ZSV.read(path, **options) -> array
|
|
245
|
+
*
|
|
246
|
+
* Reads entire CSV file into an array of rows.
|
|
247
|
+
*/
|
|
248
|
+
static VALUE rb_zsv_read(int argc, VALUE *argv, VALUE klass)
|
|
249
|
+
{
|
|
250
|
+
VALUE path, opts;
|
|
251
|
+
rb_scan_args(argc, argv, "11", &path, &opts);
|
|
252
|
+
|
|
253
|
+
Check_Type(path, T_STRING);
|
|
254
|
+
|
|
255
|
+
zsv_ruby_parser_t *parser = zsv_parser_new_from_path(StringValueCStr(path), opts);
|
|
256
|
+
VALUE result = rb_ary_new();
|
|
257
|
+
|
|
258
|
+
VALUE row;
|
|
259
|
+
while (!NIL_P(row = zsv_parser_shift(parser))) {
|
|
260
|
+
rb_ary_push(result, row);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
zsv_parser_free(parser);
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/*
|
|
268
|
+
* call-seq:
|
|
269
|
+
* ZSV.open(path, mode="r", **options) -> parser
|
|
270
|
+
* ZSV.open(path, mode="r", **options) {|parser| block } -> result
|
|
271
|
+
*
|
|
272
|
+
* Opens a CSV file for reading. If a block is given, the parser is
|
|
273
|
+
* automatically closed after the block completes.
|
|
274
|
+
*/
|
|
275
|
+
static VALUE rb_zsv_open(int argc, VALUE *argv, VALUE klass)
|
|
276
|
+
{
|
|
277
|
+
VALUE path, mode, opts;
|
|
278
|
+
rb_scan_args(argc, argv, "11:", &path, &mode, &opts);
|
|
279
|
+
|
|
280
|
+
Check_Type(path, T_STRING);
|
|
281
|
+
|
|
282
|
+
/* If mode is a hash, it's actually the options */
|
|
283
|
+
if (!NIL_P(mode) && TYPE(mode) == T_HASH) {
|
|
284
|
+
opts = mode;
|
|
285
|
+
mode = Qnil;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* Currently only support read mode */
|
|
289
|
+
if (!NIL_P(mode) && strcmp(StringValueCStr(mode), "r") != 0) {
|
|
290
|
+
rb_raise(rb_eNotImpError, "Only read mode is currently supported");
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
zsv_ruby_parser_t *parser = zsv_parser_new_from_path(StringValueCStr(path), opts);
|
|
294
|
+
VALUE parser_obj = wrap_parser(parser);
|
|
295
|
+
|
|
296
|
+
if (rb_block_given_p()) {
|
|
297
|
+
int state;
|
|
298
|
+
VALUE result = rb_protect(rb_yield, parser_obj, &state);
|
|
299
|
+
zsv_parser_close(parser);
|
|
300
|
+
|
|
301
|
+
if (state) {
|
|
302
|
+
rb_jump_tag(state);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return result;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return parser_obj;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/* Initialize the extension */
|
|
312
|
+
void Init_zsv(void)
|
|
313
|
+
{
|
|
314
|
+
/* Define module */
|
|
315
|
+
mZSV = rb_define_module("ZSV");
|
|
316
|
+
|
|
317
|
+
/* Define Parser class */
|
|
318
|
+
cParser = rb_define_class_under(mZSV, "Parser", rb_cObject);
|
|
319
|
+
rb_include_module(cParser, rb_mEnumerable);
|
|
320
|
+
rb_define_alloc_func(cParser, zsv_parser_alloc);
|
|
321
|
+
rb_define_method(cParser, "initialize", rb_zsv_parser_initialize, -1);
|
|
322
|
+
rb_define_method(cParser, "shift", rb_zsv_parser_shift, 0);
|
|
323
|
+
rb_define_method(cParser, "each", rb_zsv_parser_each, 0);
|
|
324
|
+
rb_define_alias(cParser, "each_row", "each");
|
|
325
|
+
rb_define_method(cParser, "rewind", rb_zsv_parser_rewind, 0);
|
|
326
|
+
rb_define_method(cParser, "close", rb_zsv_parser_close, 0);
|
|
327
|
+
rb_define_method(cParser, "headers", rb_zsv_parser_headers_get, 0);
|
|
328
|
+
rb_define_method(cParser, "closed?", rb_zsv_parser_closed_p, 0);
|
|
329
|
+
|
|
330
|
+
/* Define module methods */
|
|
331
|
+
rb_define_module_function(mZSV, "foreach", rb_zsv_foreach, -1);
|
|
332
|
+
rb_define_module_function(mZSV, "parse", rb_zsv_parse, -1);
|
|
333
|
+
rb_define_module_function(mZSV, "read", rb_zsv_read, -1);
|
|
334
|
+
rb_define_module_function(mZSV, "open", rb_zsv_open, -1);
|
|
335
|
+
|
|
336
|
+
/* Define exceptions */
|
|
337
|
+
eZSVError = rb_define_class_under(mZSV, "Error", rb_eStandardError);
|
|
338
|
+
eMalformedCSVError = rb_define_class_under(mZSV, "MalformedCSVError", eZSVError);
|
|
339
|
+
eInvalidEncodingError = rb_define_class_under(mZSV, "InvalidEncodingError", eZSVError);
|
|
340
|
+
|
|
341
|
+
/* Initialize submodules */
|
|
342
|
+
Init_zsv_options();
|
|
343
|
+
}
|
data/lib/zsv/version.rb
ADDED
data/lib/zsv.rb
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'zsv/version'
|
|
4
|
+
require_relative 'zsv/zsv' # Load C extension
|
|
5
|
+
|
|
6
|
+
# ZSV - SIMD-accelerated CSV parser
|
|
7
|
+
#
|
|
8
|
+
# A drop-in replacement for Ruby's CSV stdlib that uses the zsv C library
|
|
9
|
+
# for 10-50x performance improvements on large CSV files.
|
|
10
|
+
#
|
|
11
|
+
# @example Basic usage
|
|
12
|
+
# ZSV.foreach("data.csv") do |row|
|
|
13
|
+
# puts row.inspect
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# @example With headers
|
|
17
|
+
# ZSV.foreach("data.csv", headers: true) do |row|
|
|
18
|
+
# puts row["name"]
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# @example Parse string
|
|
22
|
+
# rows = ZSV.parse("a,b,c\n1,2,3\n")
|
|
23
|
+
#
|
|
24
|
+
module ZSV
|
|
25
|
+
class << self
|
|
26
|
+
# Create a new parser instance
|
|
27
|
+
#
|
|
28
|
+
# This is a convenience method that creates a Parser object.
|
|
29
|
+
#
|
|
30
|
+
# @param io [String, IO] File path or IO object to parse
|
|
31
|
+
# @param options [Hash] Parser options
|
|
32
|
+
# @return [Parser] New parser instance
|
|
33
|
+
#
|
|
34
|
+
# @example
|
|
35
|
+
# parser = ZSV.new("data.csv", headers: true)
|
|
36
|
+
# parser.each { |row| puts row }
|
|
37
|
+
# parser.close
|
|
38
|
+
#
|
|
39
|
+
def new(io, **)
|
|
40
|
+
Parser.new(io, **)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Parse CSV data and return an Enumerator
|
|
44
|
+
#
|
|
45
|
+
# This method provides lazy enumeration over CSV rows without loading
|
|
46
|
+
# the entire file into memory.
|
|
47
|
+
#
|
|
48
|
+
# @param source [String, IO] CSV data or IO object
|
|
49
|
+
# @param options [Hash] Parser options
|
|
50
|
+
# @return [Enumerator] Lazy enumerator over rows
|
|
51
|
+
#
|
|
52
|
+
# @example
|
|
53
|
+
# enum = ZSV.parse_enum("a,b\n1,2\n3,4", headers: true)
|
|
54
|
+
# enum.first # => {"a" => "1", "b" => "2"}
|
|
55
|
+
#
|
|
56
|
+
def parse_enum(source, **)
|
|
57
|
+
parser = Parser.new(source, **)
|
|
58
|
+
|
|
59
|
+
Enumerator.new do |yielder|
|
|
60
|
+
parser.each { |row| yielder << row }
|
|
61
|
+
ensure
|
|
62
|
+
parser.close
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Parser class methods for convenience
|
|
68
|
+
class Parser
|
|
69
|
+
# Read all rows and return as an array
|
|
70
|
+
#
|
|
71
|
+
# @return [Array<Array, Hash>] All rows
|
|
72
|
+
def read
|
|
73
|
+
rows = []
|
|
74
|
+
each { |row| rows << row }
|
|
75
|
+
rows
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Alias for compatibility
|
|
79
|
+
alias to_a read
|
|
80
|
+
end
|
|
81
|
+
end
|