omnizip 0.4.7-arm-linux
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/.rspec +3 -0
- data/.rubocop.yml +32 -0
- data/.rubocop_todo.yml +293 -0
- data/CHANGELOG.md +1647 -0
- data/CONTEXT.md +68 -0
- data/COPYING +502 -0
- data/Gemfile +19 -0
- data/LICENSE +12 -0
- data/README.adoc +1327 -0
- data/Rakefile +15 -0
- data/TODO.refactor/00-overview.md +67 -0
- data/TODO.refactor/01-registry-base-class.md +81 -0
- data/TODO.refactor/02-error-hierarchy.md +57 -0
- data/TODO.refactor/03-autoload-entry-point.md +69 -0
- data/TODO.refactor/04-filter-base-consolidation.md +49 -0
- data/TODO.refactor/05-send-private-methods.md +64 -0
- data/TODO.refactor/06-instance-variable-access.md +69 -0
- data/TODO.refactor/07-respond-to-replacement.md +237 -0
- data/TODO.refactor/08-spec-doubles.md +27 -0
- data/TODO.refactor/09-cli-shared-module.md +35 -0
- data/TODO.refactor/10-format-detector-ocp.md +34 -0
- data/TODO.refactor/11-convenience-decoupling.md +38 -0
- data/TODO.refactor/12-thread-safety.md +8 -0
- data/TODO.refactor/13-lutaml-model-migration.md +158 -0
- data/TODO.refactor/14-add-missing-specs.md +25 -0
- data/benchmark/README.md +260 -0
- data/benchmark/benchmark_suite.rb +125 -0
- data/benchmark/compression_bench.rb +181 -0
- data/benchmark/filter_bench.rb +180 -0
- data/benchmark/models/benchmark_result.rb +59 -0
- data/benchmark/models/comparison_result.rb +69 -0
- data/benchmark/profile_suite.rb +167 -0
- data/benchmark/reporter.rb +150 -0
- data/benchmark/run_benchmarks.rb +66 -0
- data/benchmark/test_data.rb +137 -0
- data/config/formats/rar3_spec.yml +92 -0
- data/config/formats/rar5_spec.yml +102 -0
- data/docs/.github/workflows/docs.yml +142 -0
- data/docs/.gitignore +21 -0
- data/docs/.lychee.toml +67 -0
- data/docs/Gemfile +13 -0
- data/docs/RAR_WRITE_SUPPORT.md +26 -0
- data/docs/README.md +101 -0
- data/docs/_config.yml +112 -0
- data/docs/assets/logo.svg +1 -0
- data/docs/assets/omnizip-logo.pdf +1540 -11
- data/docs/comparison/feature-matrix.adoc +694 -0
- data/docs/comparison/index.adoc +113 -0
- data/docs/comparison/vs-7zip.adoc +309 -0
- data/docs/comparison/vs-peazip.adoc +77 -0
- data/docs/comparison/vs-rubyzip.adoc +342 -0
- data/docs/comparison/vs-winrar.adoc +100 -0
- data/docs/compatibility.adoc +579 -0
- data/docs/concepts/index.adoc +129 -0
- data/docs/developer/architecture.adoc +256 -0
- data/docs/developer/contributing.adoc +158 -0
- data/docs/developer/index.adoc +25 -0
- data/docs/developer/testing.adoc +212 -0
- data/docs/getting-started/basic-usage.adoc +263 -0
- data/docs/getting-started/index.adoc +42 -0
- data/docs/getting-started/installation.adoc +138 -0
- data/docs/getting-started/quick-start.adoc +183 -0
- data/docs/getting-started/your-first-archive.adoc +219 -0
- data/docs/guides/advanced-features/encryption.adoc +277 -0
- data/docs/guides/advanced-features/index.adoc +59 -0
- data/docs/guides/advanced-features/parallel-processing.adoc +144 -0
- data/docs/guides/advanced-features/progress-tracking.adoc +124 -0
- data/docs/guides/advanced-features/streaming.adoc +142 -0
- data/docs/guides/archive-formats/gzip-format.adoc +105 -0
- data/docs/guides/archive-formats/index.adoc +160 -0
- data/docs/guides/archive-formats/ole-format.adoc +151 -0
- data/docs/guides/archive-formats/rar-format.adoc +104 -0
- data/docs/guides/archive-formats/rar5.adoc +521 -0
- data/docs/guides/archive-formats/rpm-format.adoc +108 -0
- data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
- data/docs/guides/archive-formats/tar-format.adoc +106 -0
- data/docs/guides/archive-formats/xz-format.adoc +118 -0
- data/docs/guides/archive-formats/zip-format.adoc +35 -0
- data/docs/guides/compression-algorithms/bzip2.adoc +114 -0
- data/docs/guides/compression-algorithms/deflate.adoc +313 -0
- data/docs/guides/compression-algorithms/index.adoc +190 -0
- data/docs/guides/compression-algorithms/lzma.adoc +394 -0
- data/docs/guides/compression-algorithms/lzma2.adoc +244 -0
- data/docs/guides/compression-algorithms/ppmd.adoc +313 -0
- data/docs/guides/compression-algorithms/zstandard.adoc +296 -0
- data/docs/guides/creating-archives.adoc +348 -0
- data/docs/guides/extracting-archives.adoc +53 -0
- data/docs/guides/format-conversion.adoc +64 -0
- data/docs/guides/index.adoc +49 -0
- data/docs/guides/migration-rubyzip.adoc +217 -0
- data/docs/guides/parity-archives.adoc +605 -0
- data/docs/guides/performance-tuning.adoc +88 -0
- data/docs/index.adoc +228 -0
- data/docs/lychee.toml +67 -0
- data/docs/reference/api/overview.adoc +187 -0
- data/docs/reference/cli/compress-command.adoc +114 -0
- data/docs/reference/cli/overview.adoc +140 -0
- data/docs/reference/index.adoc +26 -0
- data/docs/resources/faq.adoc +185 -0
- data/docs/resources/quick-reference.adoc +222 -0
- data/docs/rust-backend.md +0 -0
- data/docs/troubleshooting/index.adoc +207 -0
- data/docs/xar_format.md +216 -0
- data/examples/api_comparison.rb +205 -0
- data/examples/deflate64_example.rb +96 -0
- data/examples/par2_demo.rb +121 -0
- data/examples/quick_start_native.rb +150 -0
- data/examples/quick_start_rubyzip.rb +115 -0
- data/examples/rubyzip_compatibility_demo.rb +194 -0
- data/exe/omnizip +27 -0
- data/lib/omnizip/algorithm.rb +176 -0
- data/lib/omnizip/algorithm_registry.rb +65 -0
- data/lib/omnizip/algorithms/.keep +0 -0
- data/lib/omnizip/algorithms/bzip2/bwt.rb +236 -0
- data/lib/omnizip/algorithms/bzip2/bz2.rb +687 -0
- data/lib/omnizip/algorithms/bzip2/rle.rb +146 -0
- data/lib/omnizip/algorithms/bzip2.rb +108 -0
- data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
- data/lib/omnizip/algorithms/deflate/decoder.rb +37 -0
- data/lib/omnizip/algorithms/deflate/encoder.rb +45 -0
- data/lib/omnizip/algorithms/deflate.rb +135 -0
- data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
- data/lib/omnizip/algorithms/deflate64/decoder.rb +151 -0
- data/lib/omnizip/algorithms/deflate64/encoder.rb +95 -0
- data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +352 -0
- data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +140 -0
- data/lib/omnizip/algorithms/deflate64.rb +118 -0
- data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
- data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
- data/lib/omnizip/algorithms/lzma/decoder.rb +146 -0
- data/lib/omnizip/algorithms/lzma/dictionary.rb +70 -0
- data/lib/omnizip/algorithms/lzma/distance_coder.rb +326 -0
- data/lib/omnizip/algorithms/lzma/encoder.rb +139 -0
- data/lib/omnizip/algorithms/lzma/length_coder.rb +172 -0
- data/lib/omnizip/algorithms/lzma/literal_decoder.rb +204 -0
- data/lib/omnizip/algorithms/lzma/literal_encoder.rb +208 -0
- data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +368 -0
- data/lib/omnizip/algorithms/lzma/lzma1_encoder.rb +105 -0
- data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +194 -0
- data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
- data/lib/omnizip/algorithms/lzma/match.rb +32 -0
- data/lib/omnizip/algorithms/lzma/match_finder.rb +233 -0
- data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
- data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +84 -0
- data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +159 -0
- data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
- data/lib/omnizip/algorithms/lzma/range_coder.rb +82 -0
- data/lib/omnizip/algorithms/lzma/range_decoder.rb +274 -0
- data/lib/omnizip/algorithms/lzma/range_encoder.rb +202 -0
- data/lib/omnizip/algorithms/lzma/state.rb +127 -0
- data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +323 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder.rb +420 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +640 -0
- data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +224 -0
- data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +167 -0
- data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +258 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +314 -0
- data/lib/omnizip/algorithms/lzma/xz_state.rb +108 -0
- data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +1311 -0
- data/lib/omnizip/algorithms/lzma.rb +266 -0
- data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +180 -0
- data/lib/omnizip/algorithms/lzma2/constants.rb +38 -0
- data/lib/omnizip/algorithms/lzma2/encoder.rb +145 -0
- data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +165 -0
- data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
- data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +122 -0
- data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
- data/lib/omnizip/algorithms/lzma2.rb +133 -0
- data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
- data/lib/omnizip/algorithms/ppmd7/context.rb +151 -0
- data/lib/omnizip/algorithms/ppmd7/decoder.rb +127 -0
- data/lib/omnizip/algorithms/ppmd7/encoder.rb +153 -0
- data/lib/omnizip/algorithms/ppmd7/model.rb +245 -0
- data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
- data/lib/omnizip/algorithms/ppmd7.rb +146 -0
- data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
- data/lib/omnizip/algorithms/ppmd8/context.rb +32 -0
- data/lib/omnizip/algorithms/ppmd8/decoder.rb +104 -0
- data/lib/omnizip/algorithms/ppmd8/encoder.rb +135 -0
- data/lib/omnizip/algorithms/ppmd8/model.rb +246 -0
- data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
- data/lib/omnizip/algorithms/ppmd8.rb +122 -0
- data/lib/omnizip/algorithms/ppmd_base.rb +142 -0
- data/lib/omnizip/algorithms/registration.rb +28 -0
- data/lib/omnizip/algorithms/zstandard/constants.rb +158 -0
- data/lib/omnizip/algorithms/zstandard/decoder.rb +249 -0
- data/lib/omnizip/algorithms/zstandard/dictionary.rb +73 -0
- data/lib/omnizip/algorithms/zstandard/encoder.rb +294 -0
- data/lib/omnizip/algorithms/zstandard/frame/block.rb +143 -0
- data/lib/omnizip/algorithms/zstandard/frame/header.rb +233 -0
- data/lib/omnizip/algorithms/zstandard/frame.rb +33 -0
- data/lib/omnizip/algorithms/zstandard/fse/bitstream.rb +183 -0
- data/lib/omnizip/algorithms/zstandard/fse/encoder.rb +534 -0
- data/lib/omnizip/algorithms/zstandard/fse/interleaved.rb +92 -0
- data/lib/omnizip/algorithms/zstandard/fse/table.rb +188 -0
- data/lib/omnizip/algorithms/zstandard/fse/table_description.rb +203 -0
- data/lib/omnizip/algorithms/zstandard/fse.rb +53 -0
- data/lib/omnizip/algorithms/zstandard/huffman.rb +276 -0
- data/lib/omnizip/algorithms/zstandard/huffman_encoder.rb +327 -0
- data/lib/omnizip/algorithms/zstandard/ldm.rb +121 -0
- data/lib/omnizip/algorithms/zstandard/literals.rb +241 -0
- data/lib/omnizip/algorithms/zstandard/literals_encoder.rb +96 -0
- data/lib/omnizip/algorithms/zstandard/match_finder.rb +483 -0
- data/lib/omnizip/algorithms/zstandard/sequences.rb +350 -0
- data/lib/omnizip/algorithms/zstandard/sequences_encoder.rb +333 -0
- data/lib/omnizip/algorithms/zstandard/xxhash.rb +159 -0
- data/lib/omnizip/algorithms/zstandard.rb +210 -0
- data/lib/omnizip/algorithms.rb +35 -0
- data/lib/omnizip/archive/builder.rb +48 -0
- data/lib/omnizip/archive/reader_session.rb +67 -0
- data/lib/omnizip/archive.rb +86 -0
- data/lib/omnizip/archive_handler.rb +82 -0
- data/lib/omnizip/archive_handlers/cpio_handler.rb +47 -0
- data/lib/omnizip/archive_handlers/iso_handler.rb +54 -0
- data/lib/omnizip/archive_handlers/ole_handler.rb +37 -0
- data/lib/omnizip/archive_handlers/rar_handler.rb +96 -0
- data/lib/omnizip/archive_handlers/rpm_handler.rb +45 -0
- data/lib/omnizip/archive_handlers/seven_zip_handler.rb +89 -0
- data/lib/omnizip/archive_handlers/tar_handler.rb +75 -0
- data/lib/omnizip/archive_handlers/xar_handler.rb +49 -0
- data/lib/omnizip/archive_handlers/zip_handler.rb +115 -0
- data/lib/omnizip/archive_handlers.rb +18 -0
- data/lib/omnizip/backends.rb +160 -0
- data/lib/omnizip/buffer/memory_archive.rb +246 -0
- data/lib/omnizip/buffer/memory_extractor.rb +234 -0
- data/lib/omnizip/buffer/seven_zip_bridge.rb +171 -0
- data/lib/omnizip/buffer.rb +187 -0
- data/lib/omnizip/checksum_registry.rb +41 -0
- data/lib/omnizip/checksums/crc32.rb +101 -0
- data/lib/omnizip/checksums/crc64.rb +102 -0
- data/lib/omnizip/checksums/crc_base.rb +158 -0
- data/lib/omnizip/checksums/registration.rb +16 -0
- data/lib/omnizip/checksums/verifier.rb +130 -0
- data/lib/omnizip/checksums.rb +11 -0
- data/lib/omnizip/chunked/memory_manager.rb +194 -0
- data/lib/omnizip/chunked/reader.rb +78 -0
- data/lib/omnizip/chunked/writer.rb +123 -0
- data/lib/omnizip/chunked.rb +123 -0
- data/lib/omnizip/cli/output_formatter.rb +112 -0
- data/lib/omnizip/cli.rb +604 -0
- data/lib/omnizip/commands/.keep +0 -0
- data/lib/omnizip/commands/archive_create_command.rb +245 -0
- data/lib/omnizip/commands/archive_extract_command.rb +231 -0
- data/lib/omnizip/commands/archive_list_command.rb +204 -0
- data/lib/omnizip/commands/archive_repair_command.rb +129 -0
- data/lib/omnizip/commands/archive_verify_command.rb +115 -0
- data/lib/omnizip/commands/compress_command.rb +115 -0
- data/lib/omnizip/commands/decompress_command.rb +149 -0
- data/lib/omnizip/commands/list_command.rb +51 -0
- data/lib/omnizip/commands/metadata_command.rb +215 -0
- data/lib/omnizip/commands/parity_create_command.rb +114 -0
- data/lib/omnizip/commands/parity_repair_command.rb +120 -0
- data/lib/omnizip/commands/parity_verify_command.rb +122 -0
- data/lib/omnizip/commands/profile_list_command.rb +54 -0
- data/lib/omnizip/commands/profile_show_command.rb +44 -0
- data/lib/omnizip/commands.rb +21 -0
- data/lib/omnizip/convenience.rb +389 -0
- data/lib/omnizip/converter/conversion_registry.rb +50 -0
- data/lib/omnizip/converter/conversion_strategy.rb +108 -0
- data/lib/omnizip/converter/extract_repack_strategy.rb +51 -0
- data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +43 -0
- data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +54 -0
- data/lib/omnizip/converter.rb +124 -0
- data/lib/omnizip/crypto/aes256/cipher.rb +104 -0
- data/lib/omnizip/crypto/aes256/constants.rb +28 -0
- data/lib/omnizip/crypto/aes256/key_derivation.rb +100 -0
- data/lib/omnizip/crypto/aes256.rb +102 -0
- data/lib/omnizip/crypto.rb +11 -0
- data/lib/omnizip/entry.rb +44 -0
- data/lib/omnizip/error.rb +110 -0
- data/lib/omnizip/eta/exponential_smoothing_estimator.rb +95 -0
- data/lib/omnizip/eta/moving_average_estimator.rb +96 -0
- data/lib/omnizip/eta/rate_calculator.rb +104 -0
- data/lib/omnizip/eta/sample_history.rb +143 -0
- data/lib/omnizip/eta/time_estimator.rb +106 -0
- data/lib/omnizip/eta.rb +68 -0
- data/lib/omnizip/extraction/filter_chain.rb +179 -0
- data/lib/omnizip/extraction/glob_pattern.rb +140 -0
- data/lib/omnizip/extraction/pattern_matcher.rb +66 -0
- data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
- data/lib/omnizip/extraction/regex_pattern.rb +50 -0
- data/lib/omnizip/extraction/selective_extractor.rb +247 -0
- data/lib/omnizip/extraction.rb +115 -0
- data/lib/omnizip/file_type/mime_classifier.rb +144 -0
- data/lib/omnizip/file_type.rb +117 -0
- data/lib/omnizip/filter.rb +141 -0
- data/lib/omnizip/filter_pipeline.rb +108 -0
- data/lib/omnizip/filter_registry.rb +113 -0
- data/lib/omnizip/filters/bcj.rb +277 -0
- data/lib/omnizip/filters/bcj2/constants.rb +53 -0
- data/lib/omnizip/filters/bcj2/decoder.rb +263 -0
- data/lib/omnizip/filters/bcj2/encoder.rb +58 -0
- data/lib/omnizip/filters/bcj2/stream_data.rb +91 -0
- data/lib/omnizip/filters/bcj2.rb +93 -0
- data/lib/omnizip/filters/bcj_arm.rb +174 -0
- data/lib/omnizip/filters/bcj_arm64.rb +242 -0
- data/lib/omnizip/filters/bcj_ia64.rb +194 -0
- data/lib/omnizip/filters/bcj_ppc.rb +188 -0
- data/lib/omnizip/filters/bcj_sparc.rb +174 -0
- data/lib/omnizip/filters/bcj_x86.rb +191 -0
- data/lib/omnizip/filters/delta.rb +195 -0
- data/lib/omnizip/filters/xz_delta.rb +258 -0
- data/lib/omnizip/filters.rb +20 -0
- data/lib/omnizip/format_detector.rb +166 -0
- data/lib/omnizip/formats/.keep +0 -0
- data/lib/omnizip/formats/bzip2_file.rb +159 -0
- data/lib/omnizip/formats/cpio/bounded_io.rb +66 -0
- data/lib/omnizip/formats/cpio/constants.rb +55 -0
- data/lib/omnizip/formats/cpio/entry.rb +389 -0
- data/lib/omnizip/formats/cpio/reader.rb +194 -0
- data/lib/omnizip/formats/cpio/writer.rb +232 -0
- data/lib/omnizip/formats/cpio.rb +132 -0
- data/lib/omnizip/formats/format_spec_loader.rb +228 -0
- data/lib/omnizip/formats/gzip.rb +236 -0
- data/lib/omnizip/formats/iso/directory_builder.rb +321 -0
- data/lib/omnizip/formats/iso/directory_record.rb +162 -0
- data/lib/omnizip/formats/iso/joliet.rb +204 -0
- data/lib/omnizip/formats/iso/path_table.rb +125 -0
- data/lib/omnizip/formats/iso/reader.rb +194 -0
- data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
- data/lib/omnizip/formats/iso/volume_builder.rb +319 -0
- data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
- data/lib/omnizip/formats/iso/writer.rb +543 -0
- data/lib/omnizip/formats/iso.rb +133 -0
- data/lib/omnizip/formats/lzip.rb +161 -0
- data/lib/omnizip/formats/lzma_alone.rb +149 -0
- data/lib/omnizip/formats/msi/cab_extractor.rb +181 -0
- data/lib/omnizip/formats/msi/constants.rb +157 -0
- data/lib/omnizip/formats/msi/directory_resolver.rb +188 -0
- data/lib/omnizip/formats/msi/entry.rb +134 -0
- data/lib/omnizip/formats/msi/reader.rb +301 -0
- data/lib/omnizip/formats/msi/string_pool.rb +246 -0
- data/lib/omnizip/formats/msi/table_parser.rb +244 -0
- data/lib/omnizip/formats/msi.rb +73 -0
- data/lib/omnizip/formats/ole/allocation_table.rb +263 -0
- data/lib/omnizip/formats/ole/constants.rb +61 -0
- data/lib/omnizip/formats/ole/dirent.rb +439 -0
- data/lib/omnizip/formats/ole/header.rb +199 -0
- data/lib/omnizip/formats/ole/ranges_io.rb +347 -0
- data/lib/omnizip/formats/ole/storage.rb +482 -0
- data/lib/omnizip/formats/ole/types/variant.rb +338 -0
- data/lib/omnizip/formats/ole.rb +143 -0
- data/lib/omnizip/formats/rar/archive_repairer.rb +240 -0
- data/lib/omnizip/formats/rar/archive_verifier.rb +192 -0
- data/lib/omnizip/formats/rar/block_parser.rb +282 -0
- data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
- data/lib/omnizip/formats/rar/compression/dispatcher.rb +210 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +212 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +154 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman.rb +25 -0
- data/lib/omnizip/formats/rar/compression/ppmd/context.rb +103 -0
- data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +238 -0
- data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +250 -0
- data/lib/omnizip/formats/rar/compression/ppmd.rb +16 -0
- data/lib/omnizip/formats/rar/compression.rb +17 -0
- data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
- data/lib/omnizip/formats/rar/constants.rb +88 -0
- data/lib/omnizip/formats/rar/decompressor.rb +316 -0
- data/lib/omnizip/formats/rar/external_writer.rb +311 -0
- data/lib/omnizip/formats/rar/header.rb +209 -0
- data/lib/omnizip/formats/rar/license_validator.rb +111 -0
- data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
- data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
- data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
- data/lib/omnizip/formats/rar/models.rb +14 -0
- data/lib/omnizip/formats/rar/parity_handler.rb +299 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +200 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +584 -0
- data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
- data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
- data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +96 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +162 -0
- data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
- data/lib/omnizip/formats/rar/rar5/header.rb +208 -0
- data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +260 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +176 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +108 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +139 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
- data/lib/omnizip/formats/rar/rar5/vint.rb +53 -0
- data/lib/omnizip/formats/rar/rar5/writer.rb +540 -0
- data/lib/omnizip/formats/rar/rar_format_base.rb +239 -0
- data/lib/omnizip/formats/rar/reader.rb +377 -0
- data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
- data/lib/omnizip/formats/rar/volume_manager.rb +166 -0
- data/lib/omnizip/formats/rar/writer.rb +437 -0
- data/lib/omnizip/formats/rar.rb +193 -0
- data/lib/omnizip/formats/rar3/compressor.rb +71 -0
- data/lib/omnizip/formats/rar3/decompressor.rb +64 -0
- data/lib/omnizip/formats/rar3/reader.rb +107 -0
- data/lib/omnizip/formats/rar3/writer.rb +220 -0
- data/lib/omnizip/formats/rar3.rb +15 -0
- data/lib/omnizip/formats/rar5/compressor.rb +71 -0
- data/lib/omnizip/formats/rar5/decompressor.rb +64 -0
- data/lib/omnizip/formats/rar5/reader.rb +130 -0
- data/lib/omnizip/formats/rar5/writer.rb +65 -0
- data/lib/omnizip/formats/rar5.rb +15 -0
- data/lib/omnizip/formats/rpm/constants.rb +58 -0
- data/lib/omnizip/formats/rpm/entry.rb +106 -0
- data/lib/omnizip/formats/rpm/header.rb +106 -0
- data/lib/omnizip/formats/rpm/lead.rb +132 -0
- data/lib/omnizip/formats/rpm/tag.rb +228 -0
- data/lib/omnizip/formats/rpm/writer.rb +652 -0
- data/lib/omnizip/formats/rpm.rb +458 -0
- data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +274 -0
- data/lib/omnizip/formats/seven_zip/coder_chain.rb +169 -0
- data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
- data/lib/omnizip/formats/seven_zip/encoded_header.rb +110 -0
- data/lib/omnizip/formats/seven_zip/encrypted_header.rb +139 -0
- data/lib/omnizip/formats/seven_zip/file_collector.rb +143 -0
- data/lib/omnizip/formats/seven_zip/header.rb +102 -0
- data/lib/omnizip/formats/seven_zip/header_encryptor.rb +132 -0
- data/lib/omnizip/formats/seven_zip/header_writer.rb +425 -0
- data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
- data/lib/omnizip/formats/seven_zip/models/file_entry.rb +65 -0
- data/lib/omnizip/formats/seven_zip/models/folder.rb +67 -0
- data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
- data/lib/omnizip/formats/seven_zip/models.rb +20 -0
- data/lib/omnizip/formats/seven_zip/parser.rb +671 -0
- data/lib/omnizip/formats/seven_zip/reader.rb +626 -0
- data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +611 -0
- data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +308 -0
- data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
- data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +166 -0
- data/lib/omnizip/formats/seven_zip/writer.rb +801 -0
- data/lib/omnizip/formats/seven_zip.rb +179 -0
- data/lib/omnizip/formats/tar/constants.rb +73 -0
- data/lib/omnizip/formats/tar/entry.rb +98 -0
- data/lib/omnizip/formats/tar/header.rb +206 -0
- data/lib/omnizip/formats/tar/reader.rb +119 -0
- data/lib/omnizip/formats/tar/writer.rb +212 -0
- data/lib/omnizip/formats/tar.rb +74 -0
- data/lib/omnizip/formats/xar/constants.rb +119 -0
- data/lib/omnizip/formats/xar/entry.rb +268 -0
- data/lib/omnizip/formats/xar/header.rb +223 -0
- data/lib/omnizip/formats/xar/reader.rb +400 -0
- data/lib/omnizip/formats/xar/toc.rb +570 -0
- data/lib/omnizip/formats/xar/writer.rb +461 -0
- data/lib/omnizip/formats/xar.rb +145 -0
- data/lib/omnizip/formats/xz/reader.rb +121 -0
- data/lib/omnizip/formats/xz/writer.rb +416 -0
- data/lib/omnizip/formats/xz.rb +210 -0
- data/lib/omnizip/formats/xz_const.rb +49 -0
- data/lib/omnizip/formats/xz_impl/block_decoder.rb +761 -0
- data/lib/omnizip/formats/xz_impl/block_encoder.rb +304 -0
- data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
- data/lib/omnizip/formats/xz_impl/block_header_parser.rb +182 -0
- data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
- data/lib/omnizip/formats/xz_impl/index_encoder.rb +120 -0
- data/lib/omnizip/formats/xz_impl/stream_decoder.rb +470 -0
- data/lib/omnizip/formats/xz_impl/stream_encoder.rb +95 -0
- data/lib/omnizip/formats/xz_impl/stream_footer.rb +79 -0
- data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +115 -0
- data/lib/omnizip/formats/xz_impl/stream_header.rb +53 -0
- data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +106 -0
- data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
- data/lib/omnizip/formats/xz_impl.rb +52 -0
- data/lib/omnizip/formats/zip/central_directory_header.rb +223 -0
- data/lib/omnizip/formats/zip/constants.rb +69 -0
- data/lib/omnizip/formats/zip/end_of_central_directory.rb +132 -0
- data/lib/omnizip/formats/zip/local_file_header.rb +136 -0
- data/lib/omnizip/formats/zip/reader.rb +376 -0
- data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
- data/lib/omnizip/formats/zip/writer.rb +489 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +102 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +64 -0
- data/lib/omnizip/formats/zip/zip64_extra_field.rb +112 -0
- data/lib/omnizip/formats/zip.rb +50 -0
- data/lib/omnizip/formats.rb +29 -0
- data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
- data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
- data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
- data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
- data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
- data/lib/omnizip/implementations/base.rb +19 -0
- data/lib/omnizip/implementations/rust/archive.rb +93 -0
- data/lib/omnizip/implementations/rust/library.rb +221 -0
- data/lib/omnizip/implementations/rust.rb +26 -0
- data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +428 -0
- data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +456 -0
- data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +285 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +197 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +194 -0
- data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +139 -0
- data/lib/omnizip/implementations/seven_zip/lzma.rb +21 -0
- data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +56 -0
- data/lib/omnizip/implementations/seven_zip/lzma2.rb +12 -0
- data/lib/omnizip/implementations/seven_zip.rb +11 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +547 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +748 -0
- data/lib/omnizip/implementations/xz_utils/lzma2.rb +13 -0
- data/lib/omnizip/implementations/xz_utils.rb +10 -0
- data/lib/omnizip/implementations.rb +25 -0
- data/lib/omnizip/io/buffered_input.rb +147 -0
- data/lib/omnizip/io/buffered_output.rb +106 -0
- data/lib/omnizip/io/source.rb +143 -0
- data/lib/omnizip/io/stream_manager.rb +117 -0
- data/lib/omnizip/io.rb +15 -0
- data/lib/omnizip/link_handler/hard_link.rb +79 -0
- data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
- data/lib/omnizip/link_handler.rb +129 -0
- data/lib/omnizip/metadata/archive_metadata.rb +114 -0
- data/lib/omnizip/metadata/entry_metadata.rb +153 -0
- data/lib/omnizip/metadata/metadata_editor.rb +169 -0
- data/lib/omnizip/metadata/metadata_registry.rb +71 -0
- data/lib/omnizip/metadata/metadata_validator.rb +101 -0
- data/lib/omnizip/metadata.rb +58 -0
- data/lib/omnizip/models/.keep +0 -0
- data/lib/omnizip/models/algorithm_metadata.rb +41 -0
- data/lib/omnizip/models/attribute_apply.rb +40 -0
- data/lib/omnizip/models/compression_options.rb +53 -0
- data/lib/omnizip/models/conversion_options.rb +79 -0
- data/lib/omnizip/models/conversion_result.rb +141 -0
- data/lib/omnizip/models/eta_result.rb +45 -0
- data/lib/omnizip/models/extraction_rule.rb +115 -0
- data/lib/omnizip/models/filter_chain.rb +142 -0
- data/lib/omnizip/models/filter_config.rb +148 -0
- data/lib/omnizip/models/match_result.rb +141 -0
- data/lib/omnizip/models/optimization_suggestion.rb +95 -0
- data/lib/omnizip/models/parallel_options.rb +116 -0
- data/lib/omnizip/models/performance_result.rb +85 -0
- data/lib/omnizip/models/profile_report.rb +116 -0
- data/lib/omnizip/models/progress_options.rb +39 -0
- data/lib/omnizip/models/split_options.rb +116 -0
- data/lib/omnizip/optimization_registry.rb +45 -0
- data/lib/omnizip/parallel/engine.rb +52 -0
- data/lib/omnizip/parallel/job_queue.rb +209 -0
- data/lib/omnizip/parallel/job_scheduler.rb +225 -0
- data/lib/omnizip/parallel/parallel_compressor.rb +326 -0
- data/lib/omnizip/parallel/parallel_extractor.rb +238 -0
- data/lib/omnizip/parallel/thread_pool.rb +60 -0
- data/lib/omnizip/parallel/worker_pool.rb +227 -0
- data/lib/omnizip/parallel.rb +156 -0
- data/lib/omnizip/parity/chunked_block_processor.rb +194 -0
- data/lib/omnizip/parity/galois16.rb +145 -0
- data/lib/omnizip/parity/models/creator_packet.rb +71 -0
- data/lib/omnizip/parity/models/file_description_packet.rb +131 -0
- data/lib/omnizip/parity/models/ifsc_packet.rb +111 -0
- data/lib/omnizip/parity/models/main_packet.rb +126 -0
- data/lib/omnizip/parity/models/packet.rb +156 -0
- data/lib/omnizip/parity/models/packet_registry.rb +102 -0
- data/lib/omnizip/parity/models/recovery_slice_packet.rb +76 -0
- data/lib/omnizip/parity/models.rb +27 -0
- data/lib/omnizip/parity/par2_creator.rb +496 -0
- data/lib/omnizip/parity/par2_repairer.rb +409 -0
- data/lib/omnizip/parity/par2_verifier.rb +373 -0
- data/lib/omnizip/parity/par2cmdline_algorithm.rb +108 -0
- data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
- data/lib/omnizip/parity/reed_solomon_decoder.rb +263 -0
- data/lib/omnizip/parity/reed_solomon_encoder.rb +108 -0
- data/lib/omnizip/parity/reed_solomon_matrix.rb +339 -0
- data/lib/omnizip/parity.rb +207 -0
- data/lib/omnizip/password/encryption_registry.rb +26 -0
- data/lib/omnizip/password/encryption_strategy.rb +96 -0
- data/lib/omnizip/password/password_validator.rb +129 -0
- data/lib/omnizip/password/winzip_aes_strategy.rb +190 -0
- data/lib/omnizip/password/zip_crypto_strategy.rb +135 -0
- data/lib/omnizip/password.rb +88 -0
- data/lib/omnizip/pipe/stream_compressor.rb +124 -0
- data/lib/omnizip/pipe/stream_decompressor.rb +173 -0
- data/lib/omnizip/pipe.rb +120 -0
- data/lib/omnizip/platform/ntfs_streams.rb +200 -0
- data/lib/omnizip/platform.rb +189 -0
- data/lib/omnizip/profile/archive_profile.rb +36 -0
- data/lib/omnizip/profile/balanced_profile.rb +31 -0
- data/lib/omnizip/profile/binary_profile.rb +33 -0
- data/lib/omnizip/profile/compression_profile.rb +157 -0
- data/lib/omnizip/profile/custom_profile.rb +155 -0
- data/lib/omnizip/profile/fast_profile.rb +31 -0
- data/lib/omnizip/profile/maximum_profile.rb +31 -0
- data/lib/omnizip/profile/profile_detector.rb +108 -0
- data/lib/omnizip/profile/profile_registry.rb +160 -0
- data/lib/omnizip/profile/text_profile.rb +33 -0
- data/lib/omnizip/profile.rb +261 -0
- data/lib/omnizip/profiler/memory_profiler.rb +66 -0
- data/lib/omnizip/profiler/method_profiler.rb +49 -0
- data/lib/omnizip/profiler/report_generator.rb +158 -0
- data/lib/omnizip/profiler.rb +192 -0
- data/lib/omnizip/progress/callback_reporter.rb +34 -0
- data/lib/omnizip/progress/console_reporter.rb +59 -0
- data/lib/omnizip/progress/log_reporter.rb +89 -0
- data/lib/omnizip/progress/operation_progress.rb +118 -0
- data/lib/omnizip/progress/progress_bar.rb +156 -0
- data/lib/omnizip/progress/progress_reporter.rb +40 -0
- data/lib/omnizip/progress/progress_tracker.rb +215 -0
- data/lib/omnizip/progress/silent_reporter.rb +22 -0
- data/lib/omnizip/progress.rb +131 -0
- data/lib/omnizip/registry.rb +111 -0
- data/lib/omnizip/rubyzip_compat.rb +61 -0
- data/lib/omnizip/temp/safe_extract.rb +124 -0
- data/lib/omnizip/temp/temp_file.rb +123 -0
- data/lib/omnizip/temp/temp_file_pool.rb +109 -0
- data/lib/omnizip/temp.rb +184 -0
- data/lib/omnizip/version.rb +5 -0
- data/lib/omnizip/zip/entry.rb +160 -0
- data/lib/omnizip/zip/file.rb +485 -0
- data/lib/omnizip/zip/input_stream.rb +270 -0
- data/lib/omnizip/zip/output_stream.rb +320 -0
- data/lib/omnizip/zip.rb +23 -0
- data/lib/omnizip.rb +157 -0
- data/lib/tasks/msi_test_files.rake +66 -0
- data/lib/tasks/platform_gems.rake +147 -0
- data/lib/tasks/rust_backend.rake +48 -0
- data/readme-docs/advanced-features.adoc +514 -0
- data/readme-docs/api-usage.adoc +445 -0
- data/readme-docs/architecture.adoc +450 -0
- data/readme-docs/archive-formats.adoc +479 -0
- data/readme-docs/cli-usage.adoc +222 -0
- data/readme-docs/compression-algorithms.adoc +446 -0
- data/readme-docs/compression-profiles.adoc +247 -0
- data/readme-docs/encryption-checksums.adoc +328 -0
- data/readme-docs/format-converter.adoc +316 -0
- data/readme-docs/installation.adoc +228 -0
- data/readme-docs/par2-archives.adoc +608 -0
- data/readme-docs/performance-profiler.adoc +389 -0
- data/readme-docs/preprocessing-filters.adoc +280 -0
- data/vendor/libomnizip_ffi.so +0 -0
- data/xz-file-format-1.2.1.txt +1174 -0
- metadata +768 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
# Byte-level codec backend resolution — THE tier switch
|
|
5
|
+
# (TODO.ref-parity/62). Both paths share the algorithm classes'
|
|
6
|
+
# IO plumbing; only the byte core swaps.
|
|
7
|
+
#
|
|
8
|
+
# Policy:
|
|
9
|
+
# OMNIZIP_BACKEND=ruby force pure Ruby everywhere
|
|
10
|
+
# OMNIZIP_BACKEND=rust require the Rust library (raises when absent)
|
|
11
|
+
# OMNIZIP_BACKEND=auto (default) Rust for directions marked
|
|
12
|
+
# safe, Ruby otherwise, whenever the
|
|
13
|
+
# cdylib is loadable
|
|
14
|
+
#
|
|
15
|
+
# Safety marks (owner guidance 2026-09-19: some Ruby cores are
|
|
16
|
+
# LESS accurate than the Rust ports — be careful which tier is
|
|
17
|
+
# trusted for what):
|
|
18
|
+
# - decompress -> :rust by default. Decode is output-invariant
|
|
19
|
+
# AND the Rust decoders carry fixes the Ruby cores lack;
|
|
20
|
+
# disagreements are treated as Ruby-side accuracy findings
|
|
21
|
+
# (see the cross-tier differential spec), not coin flips.
|
|
22
|
+
# - compress -> :ruby by default. Byte-stability for content
|
|
23
|
+
# addressing (DropId dedup assumes identical frames); the
|
|
24
|
+
# Rust encoders produce DIFFERENT valid streams (probed:
|
|
25
|
+
# bzip2 L6, Ruby 906 B vs Rust 874 B). OMNIZIP_BACKEND=rust
|
|
26
|
+
# opts into Rust encode where correctness-of-ratio is wanted
|
|
27
|
+
# over frame stability.
|
|
28
|
+
module Backends
|
|
29
|
+
# Codecs whose Rust encoder is BYTE-IDENTICAL to the pure-Ruby
|
|
30
|
+
# 2026-09-20 policy flip (owner directive): RUST IS THE AUTHORITY
|
|
31
|
+
# — its encoders/decoders are the ports validated against the
|
|
32
|
+
# reference C/C++ implementations (bzip2, xz/liblzma, zstd,
|
|
33
|
+
# libdeflate), and they are determinism-contracted (same input +
|
|
34
|
+
# level => same bytes on every machine). :auto therefore routes
|
|
35
|
+
# BOTH directions through Rust whenever the cdylib loads; encode
|
|
36
|
+
# falls back to the Ruby core on any Rust error, so :auto is
|
|
37
|
+
# never worse than pure Ruby. The pure-Ruby cores remain the
|
|
38
|
+
# portable fallback and the OMNIZIP_BACKEND=ruby escape hatch.
|
|
39
|
+
RUST_AUTHORITATIVE = true
|
|
40
|
+
|
|
41
|
+
# usize::MAX — the FFI's "caller does not know the plaintext
|
|
42
|
+
# size" sentinel (streaming decode contract).
|
|
43
|
+
UNKNOWN_LENGTH = 0xFFFF_FFFF_FFFF_FFFF
|
|
44
|
+
|
|
45
|
+
class << self
|
|
46
|
+
def for(codec, _direction)
|
|
47
|
+
mode = ENV.fetch("OMNIZIP_BACKEND", "auto")
|
|
48
|
+
|
|
49
|
+
return backend_rust if mode == "rust"
|
|
50
|
+
return backend_ruby if mode == "ruby"
|
|
51
|
+
|
|
52
|
+
return backend_ruby unless Implementations::Rust::Library.available?
|
|
53
|
+
return backend_ruby unless Implementations::Rust::Library.supports?(codec)
|
|
54
|
+
|
|
55
|
+
backend_rust
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Compress through the tier-selected backend. The block is
|
|
59
|
+
# the pure-Ruby core — evaluated ONLY on the Ruby path, so
|
|
60
|
+
# the accelerated path never pays for it. A Rust encode error
|
|
61
|
+
# falls back to the Ruby core (auto is never worse than pure
|
|
62
|
+
# Ruby); only the forced `rust` mode propagates.
|
|
63
|
+
def compress(codec, data, level, &ruby_core)
|
|
64
|
+
backend = Backends.for(codec, :encode)
|
|
65
|
+
return yield if backend == RubyBackend
|
|
66
|
+
|
|
67
|
+
begin
|
|
68
|
+
backend.compress(codec, data, level)
|
|
69
|
+
rescue Implementations::Rust::Error => e
|
|
70
|
+
raise if ENV.fetch("OMNIZIP_BACKEND", "auto") == "rust"
|
|
71
|
+
|
|
72
|
+
warn "omnizip: rust #{codec} encode failed (#{e.message}); using ruby" if ENV["OMNIZIP_BACKEND_DEBUG"]
|
|
73
|
+
yield
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Decompress through the tier-selected backend (output-
|
|
78
|
+
# invariant: :auto prefers Rust whenever loadable). A Rust
|
|
79
|
+
# failure falls back to the Ruby core — the Ruby readers are
|
|
80
|
+
# the tolerant superset (legacy container variants, malformed
|
|
81
|
+
# inputs they historically accept), so :auto must never be
|
|
82
|
+
# WORSE than pure Ruby. Only the forced `rust` mode propagates.
|
|
83
|
+
def decompress(codec, data, expected_len, &ruby_core)
|
|
84
|
+
backend = Backends.for(codec, :decode)
|
|
85
|
+
return yield if backend == RubyBackend
|
|
86
|
+
|
|
87
|
+
begin
|
|
88
|
+
backend.decompress(codec, data, expected_len)
|
|
89
|
+
rescue Implementations::Rust::Error => e
|
|
90
|
+
raise if ENV.fetch("OMNIZIP_BACKEND", "auto") == "rust"
|
|
91
|
+
|
|
92
|
+
warn "omnizip: rust #{codec} decode failed (#{e.message}); using ruby" if ENV["OMNIZIP_BACKEND_DEBUG"]
|
|
93
|
+
yield
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Whole-archive tier helpers: nil means "Rust unavailable or
|
|
98
|
+
# entry not found — caller falls back to the Ruby reader".
|
|
99
|
+
def archive_entry_names(path)
|
|
100
|
+
Omnizip::Implementations::Rust::Archive.open(File.binread(path)) { |a| return a.entry_names }
|
|
101
|
+
rescue Omnizip::Implementations::Rust::Archive::LibraryMissing, Omnizip::Implementations::Rust::Error, StandardError
|
|
102
|
+
nil
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# rubocop:disable-next Lint/ReturnInVoidContext
|
|
106
|
+
def archive_read_entry(path, entry_name)
|
|
107
|
+
Omnizip::Implementations::Rust::Archive.open(File.binread(path)) do |a|
|
|
108
|
+
idx = a.entry_names.index(entry_name)
|
|
109
|
+
return nil if idx.nil?
|
|
110
|
+
|
|
111
|
+
return a.read_entry(idx)
|
|
112
|
+
end
|
|
113
|
+
rescue Omnizip::Implementations::Rust::Archive::LibraryMissing, Omnizip::Implementations::Rust::Error, StandardError
|
|
114
|
+
nil
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
private
|
|
118
|
+
|
|
119
|
+
def backend_rust
|
|
120
|
+
RustBackend
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def backend_ruby
|
|
124
|
+
RubyBackend
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# The pure-Ruby path: a no-op backend — callers fall back to
|
|
129
|
+
# their own in-tree cores, which ARE the reference. Kept as an
|
|
130
|
+
# object for symmetry with the Rust side.
|
|
131
|
+
module RubyBackend
|
|
132
|
+
module_function
|
|
133
|
+
|
|
134
|
+
# :nocov:
|
|
135
|
+
def compress(codec, _data, _level)
|
|
136
|
+
raise Error, "#{codec}: ruby core not wired through Backends (call it directly)"
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def decompress(codec, _data, _expected_len)
|
|
140
|
+
raise Error, "#{codec}: ruby core not wired through Backends (call it directly)"
|
|
141
|
+
end
|
|
142
|
+
# :nocov:
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# The Rust-accelerated path over the Fiddle handle.
|
|
146
|
+
module RustBackend
|
|
147
|
+
module_function
|
|
148
|
+
|
|
149
|
+
def compress(codec, data, level)
|
|
150
|
+
Implementations::Rust::Library.instance.compress(codec, data, level)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def decompress(codec, data, expected_len)
|
|
154
|
+
Implementations::Rust::Library.instance.decompress(codec, data, expected_len)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
class Error < StandardError; end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Buffer
|
|
5
|
+
# Wrapper for in-memory archive operations
|
|
6
|
+
#
|
|
7
|
+
# Provides unified interface for adding entries to and reading entries
|
|
8
|
+
# from archives stored in memory (StringIO). Works with both OutputStream
|
|
9
|
+
# (for creating) and InputStream (for reading).
|
|
10
|
+
#
|
|
11
|
+
# @example Creating an archive
|
|
12
|
+
# writer = Formats::Zip::Writer.new(nil)
|
|
13
|
+
# archive = MemoryArchive.new(writer, :zip)
|
|
14
|
+
# archive.add('file.txt', 'content')
|
|
15
|
+
# writer.write_to_io(buffer)
|
|
16
|
+
#
|
|
17
|
+
# @example Reading an archive
|
|
18
|
+
# archive = MemoryArchive.new(Formats::Zip::Reader.new(path), :zip)
|
|
19
|
+
# archive.each_entry do |entry|
|
|
20
|
+
# puts entry.name
|
|
21
|
+
# end
|
|
22
|
+
class MemoryArchive
|
|
23
|
+
attr_reader :format, :stream
|
|
24
|
+
|
|
25
|
+
# Initialize memory archive wrapper
|
|
26
|
+
#
|
|
27
|
+
# @param stream [Formats::Zip::Writer, Formats::Zip::Reader]
|
|
28
|
+
# Native writer (write mode) or reader (read mode)
|
|
29
|
+
# @param format [Symbol] Archive format (:zip)
|
|
30
|
+
def initialize(stream, format)
|
|
31
|
+
@stream = stream
|
|
32
|
+
@format = format
|
|
33
|
+
@entries_cache = nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Add file from memory (write mode only)
|
|
37
|
+
#
|
|
38
|
+
# @param name [String] Entry name (path within archive)
|
|
39
|
+
# @param data [String] Entry content
|
|
40
|
+
# @param options [Hash] Entry options
|
|
41
|
+
# @option options [Time] :time Modification time (default: now)
|
|
42
|
+
# @option options [String] :comment Entry comment
|
|
43
|
+
# @option options [Symbol] :compression Compression method
|
|
44
|
+
# (:store, :deflate)
|
|
45
|
+
# @option options [Integer] :level Compression level (1-9)
|
|
46
|
+
# @return [self] For method chaining
|
|
47
|
+
#
|
|
48
|
+
# @example Add multiple files
|
|
49
|
+
# archive.add('file1.txt', 'content1')
|
|
50
|
+
# .add('file2.txt', 'content2')
|
|
51
|
+
# .add('dir/', '') # Directory entry
|
|
52
|
+
#
|
|
53
|
+
# @raise [RuntimeError] If stream is not an OutputStream
|
|
54
|
+
def add(name, data, **options)
|
|
55
|
+
ensure_write_mode!
|
|
56
|
+
|
|
57
|
+
if name.end_with?("/") && data.to_s.empty?
|
|
58
|
+
stream.add_directory(name)
|
|
59
|
+
else
|
|
60
|
+
method = if options[:compression] == :store
|
|
61
|
+
Formats::Zip::Constants::COMPRESSION_STORE
|
|
62
|
+
end
|
|
63
|
+
stream.add_data(name, data, nil, compression_method: method)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
self
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Add data with block (write mode only)
|
|
70
|
+
#
|
|
71
|
+
# @param name [String] Entry name
|
|
72
|
+
# @param options [Hash] Entry options
|
|
73
|
+
# @yield Block that returns content
|
|
74
|
+
# @yieldreturn [String] Entry content
|
|
75
|
+
# @return [self] For method chaining
|
|
76
|
+
#
|
|
77
|
+
# @example Add with block
|
|
78
|
+
# archive.add_data('file.txt') { File.read('source.txt') }
|
|
79
|
+
def add_data(name, **options)
|
|
80
|
+
ensure_write_mode!
|
|
81
|
+
data = yield
|
|
82
|
+
add(name, data, **options)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Iterate entries (read mode only)
|
|
86
|
+
#
|
|
87
|
+
# @yield [entry] Block called for each entry
|
|
88
|
+
# @yieldparam entry [Entry] Archive entry
|
|
89
|
+
# @return [void]
|
|
90
|
+
#
|
|
91
|
+
# @example Process all entries
|
|
92
|
+
# archive.each_entry do |entry|
|
|
93
|
+
# puts "#{entry.name}: #{entry.size} bytes"
|
|
94
|
+
# content = entry.read unless entry.directory?
|
|
95
|
+
# end
|
|
96
|
+
#
|
|
97
|
+
# @raise [RuntimeError] If stream is not an InputStream
|
|
98
|
+
def each_entry
|
|
99
|
+
ensure_read_mode!
|
|
100
|
+
|
|
101
|
+
stream.entries.each do |zip_entry|
|
|
102
|
+
yield(Entry.new(zip_entry, stream))
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Extract all entries to memory (read mode only)
|
|
107
|
+
#
|
|
108
|
+
# @return [Hash<String, String>] Filename => content mapping
|
|
109
|
+
#
|
|
110
|
+
# @example Extract all
|
|
111
|
+
# files = archive.extract_all_to_memory
|
|
112
|
+
# files.each { |name, content| puts "#{name}: #{content.size}" }
|
|
113
|
+
def extract_all_to_memory
|
|
114
|
+
ensure_read_mode!
|
|
115
|
+
|
|
116
|
+
result = {}
|
|
117
|
+
each_entry do |entry|
|
|
118
|
+
result[entry.name] = entry.read unless entry.directory?
|
|
119
|
+
end
|
|
120
|
+
result
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Get underlying buffer as string (write mode only)
|
|
124
|
+
#
|
|
125
|
+
# @return [String] Complete archive as binary string
|
|
126
|
+
#
|
|
127
|
+
# @example Get archive data
|
|
128
|
+
# archive_data = archive.to_s
|
|
129
|
+
# File.binwrite('output.zip', archive_data)
|
|
130
|
+
#
|
|
131
|
+
# @raise [RuntimeError] If stream is not an OutputStream
|
|
132
|
+
def to_s
|
|
133
|
+
ensure_write_mode!
|
|
134
|
+
|
|
135
|
+
# The buffer is owned by Buffer.create; this method should be
|
|
136
|
+
# called on the StringIO it returns instead.
|
|
137
|
+
raise NotImplementedError,
|
|
138
|
+
"Use Buffer.create return value instead"
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Entry wrapper with read capability
|
|
142
|
+
#
|
|
143
|
+
# Wraps underlying ZIP entry to provide consistent interface
|
|
144
|
+
# for reading entry data from the stream.
|
|
145
|
+
class Entry
|
|
146
|
+
attr_reader :name, :size, :compressed_size, :time, :comment
|
|
147
|
+
|
|
148
|
+
# Initialize entry wrapper
|
|
149
|
+
#
|
|
150
|
+
# @param entry [Formats::Zip::CentralDirectoryHeader] entry
|
|
151
|
+
# @param reader [Formats::Zip::Reader] Native archive reader
|
|
152
|
+
def initialize(entry, reader)
|
|
153
|
+
@entry = entry
|
|
154
|
+
@reader = reader
|
|
155
|
+
@name = entry.filename
|
|
156
|
+
@size = entry.uncompressed_size
|
|
157
|
+
@compressed_size = entry.compressed_size
|
|
158
|
+
@time = entry.time
|
|
159
|
+
@comment = entry.comment.to_s
|
|
160
|
+
@directory = entry.directory?
|
|
161
|
+
@content = nil
|
|
162
|
+
@pos = 0
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Read entry content
|
|
166
|
+
#
|
|
167
|
+
# @param size [Integer, nil] Number of bytes to read (nil for all)
|
|
168
|
+
# @return [String, nil] Entry data or nil if EOF
|
|
169
|
+
#
|
|
170
|
+
# @example Read entire entry
|
|
171
|
+
# content = entry.read
|
|
172
|
+
#
|
|
173
|
+
# @example Read in chunks
|
|
174
|
+
# while (chunk = entry.read(8192))
|
|
175
|
+
# process_chunk(chunk)
|
|
176
|
+
# end
|
|
177
|
+
def read(size = nil)
|
|
178
|
+
# IO-like streaming semantics: successive reads return
|
|
179
|
+
# successive chunks, nil at end-of-content. Callers like
|
|
180
|
+
# Pipe::StreamDecompressor loop on this — a read that
|
|
181
|
+
# always returns data would loop forever.
|
|
182
|
+
@content ||= @reader.read_entry(@name)
|
|
183
|
+
return nil if @pos >= @content.bytesize
|
|
184
|
+
|
|
185
|
+
chunk = if size
|
|
186
|
+
@content.byteslice(@pos, size)
|
|
187
|
+
else
|
|
188
|
+
@content.byteslice(@pos, @content.bytesize - @pos)
|
|
189
|
+
end
|
|
190
|
+
@pos += chunk.bytesize
|
|
191
|
+
chunk
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Check if entry is a directory
|
|
195
|
+
#
|
|
196
|
+
# @return [Boolean] True if directory entry
|
|
197
|
+
def directory?
|
|
198
|
+
@directory
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Check if entry is a file
|
|
202
|
+
#
|
|
203
|
+
# @return [Boolean] True if file entry
|
|
204
|
+
def file?
|
|
205
|
+
!@directory
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Get compression method
|
|
209
|
+
#
|
|
210
|
+
# @return [Symbol] Compression method (:store, :deflate, etc.)
|
|
211
|
+
def compression_method
|
|
212
|
+
@entry.compression_method
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Get CRC32 checksum
|
|
216
|
+
#
|
|
217
|
+
# @return [Integer] CRC32 value
|
|
218
|
+
def crc32
|
|
219
|
+
@entry.crc32
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
private
|
|
224
|
+
|
|
225
|
+
# Ensure stream is in write mode (native Writer)
|
|
226
|
+
#
|
|
227
|
+
# @raise [Omnizip::IOError] If not in write mode
|
|
228
|
+
def ensure_write_mode!
|
|
229
|
+
return if stream.is_a?(Omnizip::Formats::Zip::Writer)
|
|
230
|
+
|
|
231
|
+
raise Omnizip::IOError,
|
|
232
|
+
"Operation requires write mode (Formats::Zip::Writer)"
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# Ensure stream is in read mode (native Reader)
|
|
236
|
+
#
|
|
237
|
+
# @raise [Omnizip::IOError] If not in read mode
|
|
238
|
+
def ensure_read_mode!
|
|
239
|
+
return if stream.is_a?(Omnizip::Formats::Zip::Reader)
|
|
240
|
+
|
|
241
|
+
raise Omnizip::IOError,
|
|
242
|
+
"Operation requires read mode (Formats::Zip::Reader)"
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "stringio"
|
|
4
|
+
require "tmpdir"
|
|
5
|
+
|
|
6
|
+
module Omnizip
|
|
7
|
+
module Buffer
|
|
8
|
+
# Extract archive contents to memory
|
|
9
|
+
#
|
|
10
|
+
# Provides efficient extraction of archive entries to Hash without
|
|
11
|
+
# loading all files at once. Uses lazy evaluation where possible.
|
|
12
|
+
#
|
|
13
|
+
# @example Extract all files
|
|
14
|
+
# extractor = MemoryExtractor.new(zip_data)
|
|
15
|
+
# files = extractor.extract_all
|
|
16
|
+
# # => {"file1.txt" => "content1", "file2.txt" => "content2"}
|
|
17
|
+
#
|
|
18
|
+
# @example Extract single file
|
|
19
|
+
# extractor = MemoryExtractor.new(zip_data)
|
|
20
|
+
# content = extractor.extract_entry('file1.txt')
|
|
21
|
+
# # => "content1"
|
|
22
|
+
class MemoryExtractor
|
|
23
|
+
attr_reader :format
|
|
24
|
+
|
|
25
|
+
# Initialize extractor
|
|
26
|
+
#
|
|
27
|
+
# @param data [String, StringIO] Archive data
|
|
28
|
+
# @param format [Symbol, nil] Archive format (auto-detected if nil)
|
|
29
|
+
#
|
|
30
|
+
# @example Create extractor
|
|
31
|
+
# extractor = MemoryExtractor.new(zip_data)
|
|
32
|
+
# extractor = MemoryExtractor.new(zip_buffer, format: :zip)
|
|
33
|
+
def initialize(data, format: nil)
|
|
34
|
+
@buffer = data.is_a?(StringIO) ? data : StringIO.new(data.b)
|
|
35
|
+
@format = format || detect_format
|
|
36
|
+
@extracted_cache = {}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Extract all entries to Hash
|
|
40
|
+
#
|
|
41
|
+
# @return [Hash<String, String>] Filename => content mapping
|
|
42
|
+
#
|
|
43
|
+
# @example Extract everything
|
|
44
|
+
# files = extractor.extract_all
|
|
45
|
+
# files.keys # => ["file1.txt", "file2.txt", "dir/file3.txt"]
|
|
46
|
+
def extract_all
|
|
47
|
+
result = {}
|
|
48
|
+
|
|
49
|
+
case @format
|
|
50
|
+
when :zip
|
|
51
|
+
extract_all_zip(result)
|
|
52
|
+
when :seven_zip, :"7z"
|
|
53
|
+
extract_all_seven_zip(result)
|
|
54
|
+
else
|
|
55
|
+
raise ArgumentError, "Unsupported format: #{@format}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
result
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Extract single entry by name
|
|
62
|
+
#
|
|
63
|
+
# @param name [String] Entry name to extract
|
|
64
|
+
# @return [String, nil] Entry content or nil if not found
|
|
65
|
+
#
|
|
66
|
+
# @example Extract specific file
|
|
67
|
+
# content = extractor.extract_entry('readme.txt')
|
|
68
|
+
# # => "Hello World"
|
|
69
|
+
def extract_entry(name)
|
|
70
|
+
# Check cache first
|
|
71
|
+
return @extracted_cache[name] if @extracted_cache.key?(name)
|
|
72
|
+
|
|
73
|
+
# Extract from archive
|
|
74
|
+
content = nil
|
|
75
|
+
|
|
76
|
+
case @format
|
|
77
|
+
when :zip
|
|
78
|
+
content = extract_entry_zip(name)
|
|
79
|
+
when :seven_zip, :"7z"
|
|
80
|
+
content = extract_entry_seven_zip(name)
|
|
81
|
+
else
|
|
82
|
+
raise ArgumentError, "Unsupported format: #{@format}"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Cache the result
|
|
86
|
+
@extracted_cache[name] = content if content
|
|
87
|
+
content
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# List all entry names without extracting
|
|
91
|
+
#
|
|
92
|
+
# @return [Array<String>] Entry names
|
|
93
|
+
#
|
|
94
|
+
# @example List files
|
|
95
|
+
# extractor.list_entries
|
|
96
|
+
# # => ["file1.txt", "dir/", "dir/file2.txt"]
|
|
97
|
+
def list_entries
|
|
98
|
+
names = []
|
|
99
|
+
|
|
100
|
+
case @format
|
|
101
|
+
when :zip
|
|
102
|
+
list_entries_zip(names)
|
|
103
|
+
when :seven_zip, :"7z"
|
|
104
|
+
SevenZipBridge.open(@buffer) { |archive| names.concat(archive.entry_names) }
|
|
105
|
+
else
|
|
106
|
+
raise ArgumentError, "Unsupported format: #{@format}"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
names
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Check if entry exists in archive
|
|
113
|
+
#
|
|
114
|
+
# @param name [String] Entry name
|
|
115
|
+
# @return [Boolean] True if entry exists
|
|
116
|
+
#
|
|
117
|
+
# @example Check existence
|
|
118
|
+
# extractor.entry_exists?('file.txt') # => true
|
|
119
|
+
def entry_exists?(name)
|
|
120
|
+
list_entries.include?(name)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Get total number of entries
|
|
124
|
+
#
|
|
125
|
+
# @return [Integer] Number of entries
|
|
126
|
+
def entry_count
|
|
127
|
+
list_entries.size
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Extract entries matching pattern
|
|
131
|
+
#
|
|
132
|
+
# @param pattern [Regexp, String] Pattern to match
|
|
133
|
+
# @return [Hash<String, String>] Matching entries
|
|
134
|
+
#
|
|
135
|
+
# @example Extract by pattern
|
|
136
|
+
# extractor.extract_matching(/\.txt$/)
|
|
137
|
+
# # => {"file1.txt" => "content1", "file2.txt" => "content2"}
|
|
138
|
+
def extract_matching(pattern)
|
|
139
|
+
pattern = Regexp.new(pattern) if pattern.is_a?(String)
|
|
140
|
+
result = {}
|
|
141
|
+
|
|
142
|
+
list_entries.each do |name|
|
|
143
|
+
next unless name&.match?(pattern)
|
|
144
|
+
next if name.end_with?("/") # Skip directories
|
|
145
|
+
|
|
146
|
+
content = extract_entry(name)
|
|
147
|
+
result[name] = content if content
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
result
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
private
|
|
154
|
+
|
|
155
|
+
# Delegate to the shared buffer-side sniffer
|
|
156
|
+
#
|
|
157
|
+
# @return [Symbol] Detected format
|
|
158
|
+
# @raise [Omnizip::FormatError] If format cannot be detected
|
|
159
|
+
def detect_format
|
|
160
|
+
Omnizip::Buffer.detect_format(@buffer)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# The native ZIP reader parses from a path; spill the buffer to
|
|
164
|
+
# a temporary file and yield a reader over it.
|
|
165
|
+
def with_zip_reader
|
|
166
|
+
@buffer.rewind
|
|
167
|
+
Dir.mktmpdir("omnizip_extractor_zip") do |tmp|
|
|
168
|
+
path = File.join(tmp, "buffer.zip")
|
|
169
|
+
File.binwrite(path, @buffer.read)
|
|
170
|
+
yield Omnizip::Formats::Zip::Reader.new(path)
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Extract all entries from ZIP through the native reader
|
|
175
|
+
#
|
|
176
|
+
# @param result [Hash] Hash to populate with entries
|
|
177
|
+
def extract_all_zip(result)
|
|
178
|
+
with_zip_reader do |reader|
|
|
179
|
+
reader.entries.each do |entry|
|
|
180
|
+
next if entry.directory?
|
|
181
|
+
|
|
182
|
+
content = reader.read_entry(entry.filename)
|
|
183
|
+
result[entry.filename] = content
|
|
184
|
+
@extracted_cache[entry.filename] = content
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Extract every file entry from 7z
|
|
190
|
+
#
|
|
191
|
+
# @param result [Hash] Hash to populate with entries
|
|
192
|
+
def extract_all_seven_zip(result)
|
|
193
|
+
@buffer.rewind
|
|
194
|
+
SevenZipBridge.open(@buffer) do |archive|
|
|
195
|
+
archive.extract_all_to_memory.each do |name, content|
|
|
196
|
+
result[name] = content
|
|
197
|
+
@extracted_cache[name] = content
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Extract single entry from 7z
|
|
203
|
+
#
|
|
204
|
+
# @param name [String] Entry name
|
|
205
|
+
# @return [String, nil] Entry content or nil if not found
|
|
206
|
+
def extract_entry_seven_zip(name)
|
|
207
|
+
@buffer.rewind
|
|
208
|
+
SevenZipBridge.open(@buffer) do |archive|
|
|
209
|
+
archive.read_entry(name)
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Extract single entry from ZIP through the native reader
|
|
214
|
+
#
|
|
215
|
+
# @param name [String] Entry name
|
|
216
|
+
# @return [String, nil] Entry content or nil if not found
|
|
217
|
+
def extract_entry_zip(name)
|
|
218
|
+
with_zip_reader do |reader|
|
|
219
|
+
entry = reader.entries.find { |e| e.filename == name }
|
|
220
|
+
reader.read_entry(name) if entry && !entry.directory?
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# List all entry names from ZIP through the native reader
|
|
225
|
+
#
|
|
226
|
+
# @param names [Array] Array to populate with names
|
|
227
|
+
def list_entries_zip(names)
|
|
228
|
+
with_zip_reader do |reader|
|
|
229
|
+
reader.entries.each { |entry| names << entry.filename }
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|