omnizip 0.4.7-aarch64-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,274 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "stringio"
|
|
4
|
+
|
|
5
|
+
module Omnizip
|
|
6
|
+
module Formats
|
|
7
|
+
module SevenZip
|
|
8
|
+
# Decompresses BCJ2 multi-stream folders
|
|
9
|
+
#
|
|
10
|
+
# BCJ2 archives have 4 separate pack streams that need to be:
|
|
11
|
+
# 1. Read separately
|
|
12
|
+
# 2. Decompressed individually (main is LZMA, others are usually COPY)
|
|
13
|
+
# 3. Combined via BCJ2 decoder
|
|
14
|
+
class Bcj2StreamDecompressor
|
|
15
|
+
include Omnizip::Formats::SevenZip::Constants
|
|
16
|
+
|
|
17
|
+
# Initialize BCJ2 decompressor
|
|
18
|
+
#
|
|
19
|
+
# @param archive_io [IO] Archive file handle
|
|
20
|
+
# @param folder [Models::Folder] Folder with BCJ2 coder
|
|
21
|
+
# @param pack_pos [Integer] Base position of packed data
|
|
22
|
+
# @param pack_sizes [Array<Integer>] Sizes of each pack stream
|
|
23
|
+
# @param stream_info [Models::StreamInfo] Stream info for unpack sizes
|
|
24
|
+
def initialize(archive_io, folder, pack_pos, pack_sizes, stream_info)
|
|
25
|
+
@archive_io = archive_io
|
|
26
|
+
@folder = folder
|
|
27
|
+
@pack_pos = pack_pos
|
|
28
|
+
@pack_sizes = pack_sizes
|
|
29
|
+
@stream_info = stream_info
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Check if a folder contains BCJ2 coder
|
|
33
|
+
#
|
|
34
|
+
# @param folder [Models::Folder] Folder to check
|
|
35
|
+
# @return [Boolean] true if folder has BCJ2
|
|
36
|
+
def self.bcj2_folder?(folder)
|
|
37
|
+
folder.coders.any? { |c| c.method_id == FilterId::BCJ2 }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Decompress BCJ2 multi-stream folder
|
|
41
|
+
#
|
|
42
|
+
# @param expected_size [Integer] Expected final output size
|
|
43
|
+
# @return [String] Decompressed and BCJ2-decoded data
|
|
44
|
+
def decompress(expected_size)
|
|
45
|
+
# Find BCJ2 coder and compression coder
|
|
46
|
+
bcj2_coder = @folder.coders.find { |c| c.method_id == FilterId::BCJ2 }
|
|
47
|
+
compression_coder = find_compression_coder
|
|
48
|
+
|
|
49
|
+
raise Omnizip::InvalidArchiveError, "BCJ2 coder not found" unless bcj2_coder
|
|
50
|
+
|
|
51
|
+
# Determine stream layout based on folder structure
|
|
52
|
+
# BCJ2 has 4 input streams: main, call, jump, rc
|
|
53
|
+
stream_layout = determine_stream_layout(bcj2_coder, compression_coder)
|
|
54
|
+
|
|
55
|
+
# Read and decompress each of the 4 streams
|
|
56
|
+
streams = read_bcj2_streams(stream_layout)
|
|
57
|
+
|
|
58
|
+
# Apply BCJ2 decoder
|
|
59
|
+
bcj2_data = Omnizip::Filters::Bcj2StreamData.new
|
|
60
|
+
bcj2_data.main = streams[:main]
|
|
61
|
+
bcj2_data.call = streams[:call]
|
|
62
|
+
bcj2_data.jump = streams[:jump]
|
|
63
|
+
bcj2_data.rc = streams[:rc]
|
|
64
|
+
|
|
65
|
+
decoder = Omnizip::Filters::Bcj2Decoder.new(bcj2_data)
|
|
66
|
+
decoder.decode(expected_size)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
# Find the compression coder (LZMA/LZMA2/etc) in the folder
|
|
72
|
+
#
|
|
73
|
+
# @return [Models::CoderInfo, nil] Compression coder
|
|
74
|
+
def find_compression_coder
|
|
75
|
+
@folder.coders.find do |c|
|
|
76
|
+
[MethodId::LZMA, MethodId::LZMA2, MethodId::BZIP2,
|
|
77
|
+
MethodId::DEFLATE, MethodId::DEFLATE64, MethodId::PPMD].include?(c.method_id)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Determine how streams are laid out based on folder structure
|
|
82
|
+
#
|
|
83
|
+
# Analyzes bind pairs to determine which pack stream feeds which
|
|
84
|
+
# BCJ2 input, and which coder (if any) decompresses it.
|
|
85
|
+
#
|
|
86
|
+
# BCJ2 has 4 inputs: main(0), call(1), jump(2), rc(3)
|
|
87
|
+
# Each input is either:
|
|
88
|
+
# - Bound: fed by another coder's output (needs decompression)
|
|
89
|
+
# - Unbound: a direct pack stream (raw data, typically rc)
|
|
90
|
+
#
|
|
91
|
+
# @param bcj2_coder [Models::CoderInfo] BCJ2 coder
|
|
92
|
+
# @param _compression_coder [Models::CoderInfo] (unused, kept for API compat)
|
|
93
|
+
# @return [Hash] Stream layout specification
|
|
94
|
+
def determine_stream_layout(_bcj2_coder, _compression_coder)
|
|
95
|
+
# Compute composite in/out stream base indices for each coder
|
|
96
|
+
in_bases = []
|
|
97
|
+
out_bases = []
|
|
98
|
+
in_pos = 0
|
|
99
|
+
out_pos = 0
|
|
100
|
+
@folder.coders.each do |coder|
|
|
101
|
+
in_bases << in_pos
|
|
102
|
+
out_bases << out_pos
|
|
103
|
+
in_pos += coder.num_in_streams
|
|
104
|
+
out_pos += coder.num_out_streams
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Find the BCJ2 coder index and its input stream base
|
|
108
|
+
bcj2_idx = @folder.coders.index { |c| c.method_id == FilterId::BCJ2 }
|
|
109
|
+
bcj2_in_base = in_bases[bcj2_idx]
|
|
110
|
+
|
|
111
|
+
# BCJ2's 4 input streams: main, call, jump, rc
|
|
112
|
+
bcj2_in_streams = (0...4).map { |i| bcj2_in_base + i }
|
|
113
|
+
|
|
114
|
+
# Build bind map: in_stream -> out_stream
|
|
115
|
+
bind_map = {}
|
|
116
|
+
@folder.bind_pairs.each { |pair| bind_map[pair[0]] = pair[1] }
|
|
117
|
+
|
|
118
|
+
# Build out_stream -> coder_index map
|
|
119
|
+
out_to_coder = {}
|
|
120
|
+
@folder.coders.each_with_index do |coder, ci|
|
|
121
|
+
coder.num_out_streams.times do |j|
|
|
122
|
+
out_to_coder[out_bases[ci] + j] = ci
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Map unbound input streams to pack streams using pack_stream_indices
|
|
127
|
+
# pack_stream_indices[i] = unbound_input_stream for pack stream i
|
|
128
|
+
# This mapping is NOT necessarily sorted order!
|
|
129
|
+
unbound_to_pack = {}
|
|
130
|
+
@folder.pack_stream_indices.each_with_index do |input_stream, pack_idx|
|
|
131
|
+
unbound_to_pack[input_stream] = pack_idx
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# For each BCJ2 input, determine its source
|
|
135
|
+
stream_names = %i[main call jump rc]
|
|
136
|
+
layout = { type: :generic }
|
|
137
|
+
|
|
138
|
+
bcj2_in_streams.each_with_index do |in_stream, i|
|
|
139
|
+
name = stream_names[i]
|
|
140
|
+
|
|
141
|
+
if bind_map.key?(in_stream)
|
|
142
|
+
# Bound: fed by a coder's output
|
|
143
|
+
source_out = bind_map[in_stream]
|
|
144
|
+
source_coder_idx = out_to_coder[source_out]
|
|
145
|
+
source_coder = @folder.coders[source_coder_idx]
|
|
146
|
+
|
|
147
|
+
# Find the source coder's pack stream (its unbound input)
|
|
148
|
+
source_in_base = in_bases[source_coder_idx]
|
|
149
|
+
source_pack_in = (source_in_base...(source_in_base + source_coder.num_in_streams))
|
|
150
|
+
.find do |s|
|
|
151
|
+
unbound_to_pack.key?(s)
|
|
152
|
+
end
|
|
153
|
+
pack_idx = unbound_to_pack[source_pack_in]
|
|
154
|
+
|
|
155
|
+
layout[name] =
|
|
156
|
+
{ pack_idx: pack_idx, coder: source_coder,
|
|
157
|
+
unpack_idx: source_out }
|
|
158
|
+
else
|
|
159
|
+
# Unbound: direct pack stream (no decompression)
|
|
160
|
+
pack_idx = unbound_to_pack[in_stream]
|
|
161
|
+
layout[name] = { pack_idx: pack_idx, coder: nil }
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
layout
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Read and decompress BCJ2 streams
|
|
169
|
+
#
|
|
170
|
+
# @param layout [Hash] Stream layout specification
|
|
171
|
+
# @return [Hash] Decompressed stream data
|
|
172
|
+
def read_bcj2_streams(layout)
|
|
173
|
+
# Precompute absolute positions for each pack stream
|
|
174
|
+
pack_positions = []
|
|
175
|
+
pos = @pack_pos
|
|
176
|
+
@pack_sizes.each do |size|
|
|
177
|
+
pack_positions << pos
|
|
178
|
+
pos += size
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
streams = {}
|
|
182
|
+
|
|
183
|
+
%i[main call jump rc].each do |stream_name|
|
|
184
|
+
spec = layout[stream_name]
|
|
185
|
+
pack_idx = spec[:pack_idx]
|
|
186
|
+
pack_size = @pack_sizes[pack_idx] || 0
|
|
187
|
+
|
|
188
|
+
# Use absolute position for this pack stream
|
|
189
|
+
abs_pos = pack_positions[pack_idx]
|
|
190
|
+
@archive_io.seek(abs_pos)
|
|
191
|
+
packed_data = @archive_io.read(pack_size)
|
|
192
|
+
|
|
193
|
+
# Decompress if needed
|
|
194
|
+
streams[stream_name] = if spec[:coder]
|
|
195
|
+
unpack_idx = spec[:unpack_idx]
|
|
196
|
+
unpack_size = @folder.unpack_sizes[unpack_idx] if unpack_idx
|
|
197
|
+
decompress_stream(packed_data, spec[:coder], unpack_size)
|
|
198
|
+
else
|
|
199
|
+
# COPY - no decompression needed
|
|
200
|
+
packed_data || "".b
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
streams
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Decompress a single stream
|
|
208
|
+
#
|
|
209
|
+
# @param packed_data [String] Compressed data
|
|
210
|
+
# @param coder [Models::CoderInfo] Coder specification
|
|
211
|
+
# @param unpack_size [Integer, nil] Expected decompressed size
|
|
212
|
+
# @return [String] Decompressed data
|
|
213
|
+
def decompress_stream(packed_data, coder, unpack_size = nil)
|
|
214
|
+
return packed_data if coder.nil?
|
|
215
|
+
|
|
216
|
+
algo_sym = CoderChain.algorithm_for_method(coder.method_id)
|
|
217
|
+
return packed_data unless algo_sym
|
|
218
|
+
|
|
219
|
+
algo_class = Omnizip::AlgorithmRegistry.get(algo_sym)
|
|
220
|
+
raise Omnizip::AlgorithmNotFoundError, "Algorithm not found: #{algo_sym}" unless algo_class
|
|
221
|
+
|
|
222
|
+
# Build decoder options
|
|
223
|
+
options = build_decoder_options(coder, algo_sym)
|
|
224
|
+
|
|
225
|
+
# Decompress
|
|
226
|
+
input_io = StringIO.new(packed_data)
|
|
227
|
+
output_io = StringIO.new
|
|
228
|
+
output_io.set_encoding("BINARY")
|
|
229
|
+
|
|
230
|
+
decoder = algo_class.new(options)
|
|
231
|
+
|
|
232
|
+
# Use provided unpack size or estimate
|
|
233
|
+
unpack_size ||= packed_data.bytesize * 10
|
|
234
|
+
|
|
235
|
+
decoder.decompress(input_io, output_io, size: unpack_size)
|
|
236
|
+
output_io.string
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Build decoder options from coder properties
|
|
240
|
+
#
|
|
241
|
+
# @param coder [Models::CoderInfo] Coder with properties
|
|
242
|
+
# @param algo_sym [Symbol] Algorithm symbol
|
|
243
|
+
# @return [Hash] Decoder options
|
|
244
|
+
def build_decoder_options(coder, algo_sym)
|
|
245
|
+
options = {}
|
|
246
|
+
properties = coder.properties
|
|
247
|
+
|
|
248
|
+
return options if properties.nil? || properties.empty?
|
|
249
|
+
|
|
250
|
+
case algo_sym
|
|
251
|
+
when :lzma2
|
|
252
|
+
prop_byte = properties.getbyte(0)
|
|
253
|
+
dict_size = Omnizip::Algorithms::LZMA2::Properties.decode_dict_size(prop_byte)
|
|
254
|
+
options[:raw_mode] = true
|
|
255
|
+
options[:dict_size] = dict_size
|
|
256
|
+
when :lzma
|
|
257
|
+
if properties.bytesize >= 5
|
|
258
|
+
props_byte = properties.getbyte(0)
|
|
259
|
+
dict_size = properties[1, 4].unpack1("V")
|
|
260
|
+
options[:lzma2_mode] = true
|
|
261
|
+
options[:lc] = props_byte % 9
|
|
262
|
+
remainder = props_byte / 9
|
|
263
|
+
options[:lp] = remainder % 5
|
|
264
|
+
options[:pb] = remainder / 5
|
|
265
|
+
options[:dict_size] = dict_size
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
options
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Formats
|
|
5
|
+
module SevenZip
|
|
6
|
+
# Builds coder chains from .7z folder specifications
|
|
7
|
+
# Maps method IDs to algorithms and filters, reconstructing the
|
|
8
|
+
# decompression pipeline
|
|
9
|
+
class CoderChain
|
|
10
|
+
include Omnizip::Formats::SevenZip::Constants
|
|
11
|
+
|
|
12
|
+
# Build coder chain from folder specification
|
|
13
|
+
#
|
|
14
|
+
# @param folder [Models::Folder] Folder specification
|
|
15
|
+
# @return [Hash] Coder chain configuration
|
|
16
|
+
# @raise [RuntimeError] if unsupported method encountered
|
|
17
|
+
def self.build_from_folder(folder)
|
|
18
|
+
return nil if folder.coders.empty?
|
|
19
|
+
|
|
20
|
+
# Find the compression method (not a filter) among coders
|
|
21
|
+
# Filters like BCJ, BCJ2 have specific method IDs
|
|
22
|
+
main_coder = find_compression_coder(folder.coders)
|
|
23
|
+
raise Omnizip::InvalidArchiveError, "No compression method found in folder" unless main_coder
|
|
24
|
+
|
|
25
|
+
algorithm = algorithm_for_method(main_coder.method_id)
|
|
26
|
+
|
|
27
|
+
# Check for filters (all coders except the compression method)
|
|
28
|
+
filters = []
|
|
29
|
+
folder.coders.each do |coder|
|
|
30
|
+
next if coder == main_coder
|
|
31
|
+
|
|
32
|
+
filter = filter_for_method(coder.method_id)
|
|
33
|
+
filters << filter if filter
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
{
|
|
37
|
+
algorithm: algorithm,
|
|
38
|
+
filters: filters,
|
|
39
|
+
properties: main_coder.properties,
|
|
40
|
+
unpack_size: folder.unpack_sizes.last,
|
|
41
|
+
}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Find the compression coder among all coders
|
|
45
|
+
#
|
|
46
|
+
# @param coders [Array<Models::CoderInfo>] All coders in the folder
|
|
47
|
+
# @return [Models::CoderInfo, nil] The compression coder or nil
|
|
48
|
+
def self.find_compression_coder(coders)
|
|
49
|
+
# Try to find a known compression method
|
|
50
|
+
coders.each do |coder|
|
|
51
|
+
case coder.method_id
|
|
52
|
+
when MethodId::LZMA, MethodId::LZMA2, MethodId::BZIP2,
|
|
53
|
+
MethodId::DEFLATE, MethodId::DEFLATE64, MethodId::PPMD,
|
|
54
|
+
MethodId::COPY
|
|
55
|
+
return coder
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Fall back to last coder if no known compression method found
|
|
60
|
+
coders.last
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Map method ID to algorithm
|
|
64
|
+
#
|
|
65
|
+
# @param method_id [Integer] Method ID from .7z file
|
|
66
|
+
# @return [Symbol] Algorithm identifier
|
|
67
|
+
# @raise [RuntimeError] if method not supported
|
|
68
|
+
def self.algorithm_for_method(method_id)
|
|
69
|
+
case method_id
|
|
70
|
+
when MethodId::COPY
|
|
71
|
+
nil # No decompression needed
|
|
72
|
+
when MethodId::LZMA
|
|
73
|
+
:lzma
|
|
74
|
+
when MethodId::LZMA2
|
|
75
|
+
:lzma2
|
|
76
|
+
when MethodId::PPMD
|
|
77
|
+
:ppmd7
|
|
78
|
+
when MethodId::BZIP2
|
|
79
|
+
:bzip2
|
|
80
|
+
when MethodId::DEFLATE
|
|
81
|
+
:deflate
|
|
82
|
+
when MethodId::DEFLATE64
|
|
83
|
+
:deflate64
|
|
84
|
+
else
|
|
85
|
+
raise Omnizip::UnsupportedFormatError, "Unsupported compression method: " \
|
|
86
|
+
"0x#{method_id.to_s(16)}"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Map method ID to filter
|
|
91
|
+
#
|
|
92
|
+
# @param method_id [Integer] Method ID from .7z file
|
|
93
|
+
# @return [Symbol, nil] Filter identifier or nil
|
|
94
|
+
def self.filter_for_method(method_id)
|
|
95
|
+
case method_id
|
|
96
|
+
when FilterId::BCJ_X86
|
|
97
|
+
:bcj_x86
|
|
98
|
+
when FilterId::BCJ_PPC
|
|
99
|
+
:bcj_ppc
|
|
100
|
+
when FilterId::BCJ_IA64
|
|
101
|
+
:bcj_ia64
|
|
102
|
+
when FilterId::BCJ_ARM
|
|
103
|
+
:bcj_arm
|
|
104
|
+
when FilterId::BCJ_ARMT
|
|
105
|
+
:bcj_armt
|
|
106
|
+
when FilterId::BCJ_SPARC
|
|
107
|
+
:bcj_sparc
|
|
108
|
+
when FilterId::ARM64
|
|
109
|
+
:bcj_arm64
|
|
110
|
+
when FilterId::DELTA
|
|
111
|
+
:delta
|
|
112
|
+
when FilterId::BCJ2
|
|
113
|
+
:bcj2
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Create decompressor for coder chain
|
|
118
|
+
#
|
|
119
|
+
# @param chain_config [Hash] Chain configuration
|
|
120
|
+
# @param input_io [IO] Input stream
|
|
121
|
+
# @return [Object] Decompressor instance
|
|
122
|
+
def self.create_decompressor(chain_config, input_io)
|
|
123
|
+
return nil unless chain_config
|
|
124
|
+
return input_io unless chain_config[:algorithm]
|
|
125
|
+
|
|
126
|
+
# Get algorithm
|
|
127
|
+
algo_class = AlgorithmRegistry.get(chain_config[:algorithm])
|
|
128
|
+
unless algo_class
|
|
129
|
+
raise Omnizip::AlgorithmNotFoundError, "Algorithm not found: #{chain_config[:algorithm]}"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Create algorithm instance
|
|
133
|
+
decompressor = algo_class.new
|
|
134
|
+
# Pass properties if algorithm supports them
|
|
135
|
+
# Some algorithms (LZMA2) need properties
|
|
136
|
+
if chain_config[:properties] && !chain_config[:properties].empty? && decompressor.is_a?(Omnizip::Algorithms::LZMA2)
|
|
137
|
+
decompressor.properties = chain_config[:properties]
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Apply filters if present
|
|
141
|
+
if chain_config[:filters] && !chain_config[:filters].empty?
|
|
142
|
+
# Build filter pipeline
|
|
143
|
+
pipeline = FilterPipeline.new
|
|
144
|
+
chain_config[:filters].each do |filter_sym|
|
|
145
|
+
filter_class = FilterRegistry.get(filter_sym)
|
|
146
|
+
raise Omnizip::UnknownFilterError, "Filter not found: #{filter_sym}" unless filter_class
|
|
147
|
+
|
|
148
|
+
pipeline.add_filter(filter_class.new)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Return composite: input -> algorithm -> filters
|
|
152
|
+
{
|
|
153
|
+
decompressor: decompressor,
|
|
154
|
+
pipeline: pipeline,
|
|
155
|
+
input: input_io,
|
|
156
|
+
}
|
|
157
|
+
else
|
|
158
|
+
# Just algorithm
|
|
159
|
+
{
|
|
160
|
+
decompressor: decompressor,
|
|
161
|
+
pipeline: nil,
|
|
162
|
+
input: input_io,
|
|
163
|
+
}
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Formats
|
|
5
|
+
module SevenZip
|
|
6
|
+
# Constants for .7z archive format
|
|
7
|
+
# Based on 7-Zip specification
|
|
8
|
+
module Constants
|
|
9
|
+
# Archive signature and header
|
|
10
|
+
SIGNATURE = "7z\xBC\xAF\x27\x1C".b.freeze
|
|
11
|
+
SIGNATURE_SIZE = 6
|
|
12
|
+
START_HEADER_SIZE = 32 # 0x20
|
|
13
|
+
MAJOR_VERSION = 0
|
|
14
|
+
MINOR_VERSION = 4
|
|
15
|
+
|
|
16
|
+
# Property IDs for .7z format structure
|
|
17
|
+
module PropertyId
|
|
18
|
+
K_END = 0x00
|
|
19
|
+
HEADER = 0x01
|
|
20
|
+
ARCHIVE_PROPERTIES = 0x02
|
|
21
|
+
ADDITIONAL_STREAMS_INFO = 0x03
|
|
22
|
+
MAIN_STREAMS_INFO = 0x04
|
|
23
|
+
FILES_INFO = 0x05
|
|
24
|
+
PACK_INFO = 0x06
|
|
25
|
+
UNPACK_INFO = 0x07
|
|
26
|
+
SUBSTREAMS_INFO = 0x08
|
|
27
|
+
SIZE = 0x09
|
|
28
|
+
CRC = 0x0A
|
|
29
|
+
FOLDER = 0x0B
|
|
30
|
+
CODERS_UNPACK_SIZE = 0x0C
|
|
31
|
+
NUM_UNPACK_STREAM = 0x0D
|
|
32
|
+
EMPTY_STREAM = 0x0E
|
|
33
|
+
EMPTY_FILE = 0x0F
|
|
34
|
+
ANTI = 0x10
|
|
35
|
+
NAME = 0x11
|
|
36
|
+
CTIME = 0x12
|
|
37
|
+
ATIME = 0x13
|
|
38
|
+
MTIME = 0x14
|
|
39
|
+
WIN_ATTRIB = 0x15
|
|
40
|
+
COMMENT = 0x16
|
|
41
|
+
ENCODED_HEADER = 0x17
|
|
42
|
+
START_POS = 0x18
|
|
43
|
+
DUMMY = 0x19
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Method IDs for compression algorithms
|
|
47
|
+
module MethodId
|
|
48
|
+
# Compression methods
|
|
49
|
+
COPY = 0x00
|
|
50
|
+
LZMA = 0x030101
|
|
51
|
+
LZMA2 = 0x21
|
|
52
|
+
PPMD = 0x030401
|
|
53
|
+
BZIP2 = 0x040202
|
|
54
|
+
DEFLATE = 0x040108
|
|
55
|
+
DEFLATE64 = 0x040109
|
|
56
|
+
|
|
57
|
+
# Crypto methods
|
|
58
|
+
AES = 0x06F10701
|
|
59
|
+
|
|
60
|
+
def self.name(id)
|
|
61
|
+
case id
|
|
62
|
+
when COPY then "Copy"
|
|
63
|
+
when LZMA then "LZMA"
|
|
64
|
+
when LZMA2 then "LZMA2"
|
|
65
|
+
when PPMD then "PPMd"
|
|
66
|
+
when BZIP2 then "BZip2"
|
|
67
|
+
when DEFLATE then "Deflate"
|
|
68
|
+
when DEFLATE64 then "Deflate64"
|
|
69
|
+
when AES then "AES256"
|
|
70
|
+
else "Unknown(0x#{id.to_s(16)})"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Filter IDs
|
|
76
|
+
module FilterId
|
|
77
|
+
# BCJ filters for executable files
|
|
78
|
+
BCJ_X86 = 0x03030103
|
|
79
|
+
BCJ_PPC = 0x03030205
|
|
80
|
+
BCJ_IA64 = 0x03030401
|
|
81
|
+
BCJ_ARM = 0x03030501
|
|
82
|
+
BCJ_ARMT = 0x03030701
|
|
83
|
+
BCJ_SPARC = 0x03030805
|
|
84
|
+
ARM64 = 0x03030601
|
|
85
|
+
|
|
86
|
+
# BCJ2 filter
|
|
87
|
+
BCJ2 = 0x0303011B
|
|
88
|
+
|
|
89
|
+
# Swap filters for byte order conversion
|
|
90
|
+
SWAP2 = 0x03030204
|
|
91
|
+
SWAP4 = 0x03030208
|
|
92
|
+
|
|
93
|
+
# Delta filter
|
|
94
|
+
DELTA = 0x03
|
|
95
|
+
|
|
96
|
+
def self.name(id)
|
|
97
|
+
case id
|
|
98
|
+
when BCJ_X86 then "BCJ-x86"
|
|
99
|
+
when BCJ_PPC then "BCJ-PPC"
|
|
100
|
+
when BCJ_IA64 then "BCJ-IA64"
|
|
101
|
+
when BCJ_ARM then "BCJ-ARM"
|
|
102
|
+
when BCJ_ARMT then "BCJ-ARMT"
|
|
103
|
+
when BCJ_SPARC then "BCJ-SPARC"
|
|
104
|
+
when DELTA then "Delta"
|
|
105
|
+
when ARM64 then "BCJ-ARM64"
|
|
106
|
+
when BCJ2 then "BCJ2"
|
|
107
|
+
when SWAP2 then "Swap2"
|
|
108
|
+
when SWAP4 then "Swap4"
|
|
109
|
+
else "Unknown(0x#{id.to_s(16)})"
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def self.bcj_filter?(id)
|
|
114
|
+
[BCJ_X86, BCJ_PPC, BCJ_IA64, BCJ_ARM, BCJ_ARMT, BCJ_SPARC,
|
|
115
|
+
ARM64].include?(id)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Maximum limits
|
|
120
|
+
MAX_NUM_CODERS = 4
|
|
121
|
+
MAX_NUM_BONDS = 3
|
|
122
|
+
MAX_NUM_PACK_STREAMS = 4
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Formats
|
|
5
|
+
module SevenZip
|
|
6
|
+
# Handles 7-Zip encoded headers
|
|
7
|
+
#
|
|
8
|
+
# 7-Zip can compress the Next Header metadata with LZMA2 to save space.
|
|
9
|
+
# This module provides functionality to encode and decode headers.
|
|
10
|
+
module EncodedHeader
|
|
11
|
+
include Omnizip::Formats::SevenZip::Constants
|
|
12
|
+
|
|
13
|
+
module_function
|
|
14
|
+
|
|
15
|
+
# Encode next header with LZMA2 compression
|
|
16
|
+
#
|
|
17
|
+
# @param header_data [String] Uncompressed header data
|
|
18
|
+
# @return [String] Encoded header property with compressed data
|
|
19
|
+
def encode(header_data)
|
|
20
|
+
# Compress header with LZMA2
|
|
21
|
+
compressed = compress_header(header_data)
|
|
22
|
+
|
|
23
|
+
# Build encoded header property
|
|
24
|
+
encoded = String.new(encoding: "BINARY")
|
|
25
|
+
encoded << [PropertyId::ENCODED_HEADER].pack("C")
|
|
26
|
+
|
|
27
|
+
# Write pack info for compressed header
|
|
28
|
+
encoded << [PropertyId::PACK_INFO].pack("C")
|
|
29
|
+
encoded << encode_uint64(0) # Pack position
|
|
30
|
+
encoded << encode_uint64(1) # Number of pack streams
|
|
31
|
+
|
|
32
|
+
# Write size
|
|
33
|
+
encoded << [PropertyId::SIZE].pack("C")
|
|
34
|
+
encoded << encode_uint64(compressed.bytesize)
|
|
35
|
+
|
|
36
|
+
encoded << [PropertyId::K_END].pack("C")
|
|
37
|
+
|
|
38
|
+
# Write coder info (LZMA2)
|
|
39
|
+
encoded << [PropertyId::UNPACK_INFO].pack("C")
|
|
40
|
+
encoded << [PropertyId::FOLDER].pack("C")
|
|
41
|
+
encoded << encode_uint64(1) # Number of folders
|
|
42
|
+
encoded << [0].pack("C") # External flag (0 = inline)
|
|
43
|
+
|
|
44
|
+
# Number of coders
|
|
45
|
+
encoded << encode_uint64(1)
|
|
46
|
+
|
|
47
|
+
# Coder info for LZMA2
|
|
48
|
+
# Method ID: LZMA2 = 0x21
|
|
49
|
+
encoded << [1].pack("C") # Main byte (1 byte for ID, no properties)
|
|
50
|
+
encoded << [0x21].pack("C") # LZMA2 method ID
|
|
51
|
+
|
|
52
|
+
# Unpack size
|
|
53
|
+
encoded << [PropertyId::CODERS_UNPACK_SIZE].pack("C")
|
|
54
|
+
encoded << encode_uint64(header_data.bytesize)
|
|
55
|
+
|
|
56
|
+
encoded << [PropertyId::K_END].pack("C")
|
|
57
|
+
|
|
58
|
+
# Append compressed data
|
|
59
|
+
encoded << compressed
|
|
60
|
+
|
|
61
|
+
encoded
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Compress header data with LZMA2
|
|
65
|
+
#
|
|
66
|
+
# @param header_data [String] Uncompressed header
|
|
67
|
+
# @return [String] Compressed header
|
|
68
|
+
def compress_header(header_data)
|
|
69
|
+
# Use 7-Zip SDK LZMA2 encoder for 7-Zip format
|
|
70
|
+
encoder = Omnizip::Implementations::SevenZip::LZMA2::Encoder.new(
|
|
71
|
+
dict_size: 4096, # Small dictionary for headers
|
|
72
|
+
lc: 3,
|
|
73
|
+
lp: 0,
|
|
74
|
+
pb: 2,
|
|
75
|
+
standalone: false, # No property byte
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
encoder.encode(header_data)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Encode unsigned 64-bit integer in 7-Zip variable-length format
|
|
82
|
+
#
|
|
83
|
+
# @param value [Integer] Value to encode
|
|
84
|
+
# @return [String] Encoded bytes
|
|
85
|
+
def encode_uint64(value)
|
|
86
|
+
return [value].pack("C") if value < 0x80
|
|
87
|
+
|
|
88
|
+
result = String.new(encoding: "BINARY")
|
|
89
|
+
shift = 0
|
|
90
|
+
|
|
91
|
+
loop do
|
|
92
|
+
byte = value & 0x7F
|
|
93
|
+
value >>= 7
|
|
94
|
+
|
|
95
|
+
if value.zero?
|
|
96
|
+
result << [byte].pack("C")
|
|
97
|
+
break
|
|
98
|
+
else
|
|
99
|
+
result << [byte | 0x80].pack("C")
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
shift += 7
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
result
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|