omnizip 0.3.1
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 +754 -0
- data/COPYING +502 -0
- data/Gemfile +17 -0
- data/LICENSE +12 -0
- data/README.adoc +1045 -0
- data/Rakefile +12 -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 +91 -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 +271 -0
- data/docs/getting-started/index.adoc +42 -0
- data/docs/getting-started/installation.adoc +138 -0
- data/docs/getting-started/quick-start.adoc +185 -0
- data/docs/getting-started/your-first-archive.adoc +218 -0
- data/docs/guides/advanced-features/encryption.adoc +300 -0
- data/docs/guides/advanced-features/index.adoc +49 -0
- data/docs/guides/advanced-features/parallel-processing.adoc +246 -0
- data/docs/guides/advanced-features/progress-tracking.adoc +320 -0
- data/docs/guides/advanced-features/streaming.adoc +212 -0
- data/docs/guides/archive-formats/gzip-format.adoc +107 -0
- data/docs/guides/archive-formats/index.adoc +130 -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/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 +113 -0
- data/docs/guides/compression-algorithms/deflate.adoc +319 -0
- data/docs/guides/compression-algorithms/index.adoc +190 -0
- data/docs/guides/compression-algorithms/lzma.adoc +398 -0
- data/docs/guides/compression-algorithms/lzma2.adoc +327 -0
- data/docs/guides/compression-algorithms/ppmd.adoc +316 -0
- data/docs/guides/compression-algorithms/zstandard.adoc +361 -0
- data/docs/guides/creating-archives.adoc +354 -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 +218 -0
- data/docs/lychee.toml +67 -0
- data/docs/reference/api/overview.adoc +188 -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/troubleshooting/index.adoc +208 -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 +130 -0
- data/lib/omnizip/algorithm_registry.rb +86 -0
- data/lib/omnizip/algorithms/.keep +0 -0
- data/lib/omnizip/algorithms/bzip2/bwt.rb +225 -0
- data/lib/omnizip/algorithms/bzip2/decoder.rb +193 -0
- data/lib/omnizip/algorithms/bzip2/encoder.rb +237 -0
- data/lib/omnizip/algorithms/bzip2/huffman.rb +206 -0
- data/lib/omnizip/algorithms/bzip2/mtf.rb +101 -0
- data/lib/omnizip/algorithms/bzip2/rle.rb +151 -0
- data/lib/omnizip/algorithms/bzip2.rb +130 -0
- data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
- data/lib/omnizip/algorithms/deflate/decoder.rb +38 -0
- data/lib/omnizip/algorithms/deflate/encoder.rb +46 -0
- data/lib/omnizip/algorithms/deflate.rb +128 -0
- data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
- data/lib/omnizip/algorithms/deflate64/decoder.rb +153 -0
- data/lib/omnizip/algorithms/deflate64/encoder.rb +98 -0
- data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +354 -0
- data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +142 -0
- data/lib/omnizip/algorithms/deflate64.rb +109 -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 +148 -0
- data/lib/omnizip/algorithms/lzma/dictionary.rb +69 -0
- data/lib/omnizip/algorithms/lzma/distance_coder.rb +415 -0
- data/lib/omnizip/algorithms/lzma/encoder.rb +142 -0
- data/lib/omnizip/algorithms/lzma/length_coder.rb +260 -0
- data/lib/omnizip/algorithms/lzma/literal_decoder.rb +320 -0
- data/lib/omnizip/algorithms/lzma/literal_encoder.rb +210 -0
- data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +341 -0
- data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +192 -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 +205 -0
- data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
- data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +88 -0
- data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +130 -0
- data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
- data/lib/omnizip/algorithms/lzma/range_coder.rb +85 -0
- data/lib/omnizip/algorithms/lzma/range_decoder.rb +434 -0
- data/lib/omnizip/algorithms/lzma/range_encoder.rb +194 -0
- data/lib/omnizip/algorithms/lzma/state.rb +127 -0
- data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +325 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder.rb +426 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +645 -0
- data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +227 -0
- data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +169 -0
- data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +261 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +331 -0
- data/lib/omnizip/algorithms/lzma/xz_state.rb +116 -0
- data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +2055 -0
- data/lib/omnizip/algorithms/lzma.rb +238 -0
- data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +182 -0
- data/lib/omnizip/algorithms/lzma2/constants.rb +41 -0
- data/lib/omnizip/algorithms/lzma2/encoder.rb +147 -0
- data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +161 -0
- data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
- data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +127 -0
- data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
- data/lib/omnizip/algorithms/lzma2.rb +141 -0
- data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
- data/lib/omnizip/algorithms/ppmd7/context.rb +154 -0
- data/lib/omnizip/algorithms/ppmd7/decoder.rb +126 -0
- data/lib/omnizip/algorithms/ppmd7/encoder.rb +163 -0
- data/lib/omnizip/algorithms/ppmd7/model.rb +248 -0
- data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
- data/lib/omnizip/algorithms/ppmd7.rb +116 -0
- data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
- data/lib/omnizip/algorithms/ppmd8/context.rb +34 -0
- data/lib/omnizip/algorithms/ppmd8/decoder.rb +107 -0
- data/lib/omnizip/algorithms/ppmd8/encoder.rb +138 -0
- data/lib/omnizip/algorithms/ppmd8/model.rb +250 -0
- data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
- data/lib/omnizip/algorithms/ppmd8.rb +82 -0
- data/lib/omnizip/algorithms/ppmd_base.rb +138 -0
- data/lib/omnizip/algorithms/sevenzip_lzma2.rb +123 -0
- data/lib/omnizip/algorithms/xz_lzma2.rb +118 -0
- data/lib/omnizip/algorithms/zstandard/constants.rb +25 -0
- data/lib/omnizip/algorithms/zstandard/decoder.rb +46 -0
- data/lib/omnizip/algorithms/zstandard/encoder.rb +51 -0
- data/lib/omnizip/algorithms/zstandard.rb +138 -0
- data/lib/omnizip/buffer/memory_archive.rb +251 -0
- data/lib/omnizip/buffer/memory_extractor.rb +224 -0
- data/lib/omnizip/buffer.rb +176 -0
- data/lib/omnizip/checksum_registry.rb +114 -0
- data/lib/omnizip/checksums/crc32.rb +100 -0
- data/lib/omnizip/checksums/crc64.rb +101 -0
- data/lib/omnizip/checksums/crc_base.rb +158 -0
- data/lib/omnizip/checksums/verifier.rb +131 -0
- data/lib/omnizip/chunked/memory_manager.rb +194 -0
- data/lib/omnizip/chunked/reader.rb +78 -0
- data/lib/omnizip/chunked/writer.rb +120 -0
- data/lib/omnizip/chunked.rb +129 -0
- data/lib/omnizip/cli/output_formatter.rb +104 -0
- data/lib/omnizip/cli.rb +572 -0
- data/lib/omnizip/commands/.keep +0 -0
- data/lib/omnizip/commands/archive_create_command.rb +427 -0
- data/lib/omnizip/commands/archive_extract_command.rb +272 -0
- data/lib/omnizip/commands/archive_list_command.rb +218 -0
- data/lib/omnizip/commands/archive_repair_command.rb +131 -0
- data/lib/omnizip/commands/archive_verify_command.rb +117 -0
- data/lib/omnizip/commands/compress_command.rb +117 -0
- data/lib/omnizip/commands/decompress_command.rb +120 -0
- data/lib/omnizip/commands/list_command.rb +53 -0
- data/lib/omnizip/commands/metadata_command.rb +153 -0
- data/lib/omnizip/commands/parity_create_command.rb +122 -0
- data/lib/omnizip/commands/parity_repair_command.rb +122 -0
- data/lib/omnizip/commands/parity_verify_command.rb +124 -0
- data/lib/omnizip/commands/profile_list_command.rb +56 -0
- data/lib/omnizip/commands/profile_show_command.rb +44 -0
- data/lib/omnizip/convenience.rb +359 -0
- data/lib/omnizip/converter/conversion_registry.rb +49 -0
- data/lib/omnizip/converter/conversion_strategy.rb +121 -0
- data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +97 -0
- data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +112 -0
- data/lib/omnizip/converter.rb +105 -0
- data/lib/omnizip/crypto/aes256/cipher.rb +100 -0
- data/lib/omnizip/crypto/aes256/constants.rb +28 -0
- data/lib/omnizip/crypto/aes256/key_derivation.rb +101 -0
- data/lib/omnizip/crypto/aes256.rb +102 -0
- data/lib/omnizip/error.rb +106 -0
- data/lib/omnizip/eta/exponential_smoothing_estimator.rb +98 -0
- data/lib/omnizip/eta/moving_average_estimator.rb +99 -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 +63 -0
- data/lib/omnizip/extraction/filter_chain.rb +177 -0
- data/lib/omnizip/extraction/glob_pattern.rb +140 -0
- data/lib/omnizip/extraction/pattern_matcher.rb +70 -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 +240 -0
- data/lib/omnizip/extraction.rb +111 -0
- data/lib/omnizip/file_type/mime_classifier.rb +144 -0
- data/lib/omnizip/file_type.rb +113 -0
- data/lib/omnizip/filter.rb +139 -0
- data/lib/omnizip/filter_pipeline.rb +108 -0
- data/lib/omnizip/filter_registry.rb +166 -0
- data/lib/omnizip/filters/bcj.rb +279 -0
- data/lib/omnizip/filters/bcj2/constants.rb +53 -0
- data/lib/omnizip/filters/bcj2/decoder.rb +200 -0
- data/lib/omnizip/filters/bcj2/encoder.rb +61 -0
- data/lib/omnizip/filters/bcj2/stream_data.rb +93 -0
- data/lib/omnizip/filters/bcj2.rb +99 -0
- data/lib/omnizip/filters/bcj_arm.rb +176 -0
- data/lib/omnizip/filters/bcj_arm64.rb +244 -0
- data/lib/omnizip/filters/bcj_ia64.rb +196 -0
- data/lib/omnizip/filters/bcj_ppc.rb +190 -0
- data/lib/omnizip/filters/bcj_sparc.rb +176 -0
- data/lib/omnizip/filters/bcj_x86.rb +193 -0
- data/lib/omnizip/filters/delta.rb +196 -0
- data/lib/omnizip/filters/filter_base.rb +72 -0
- data/lib/omnizip/filters/registry.rb +123 -0
- data/lib/omnizip/filters/xz_delta.rb +258 -0
- data/lib/omnizip/format_detector.rb +162 -0
- data/lib/omnizip/format_registry.rb +59 -0
- data/lib/omnizip/formats/.keep +0 -0
- data/lib/omnizip/formats/bzip2_file.rb +172 -0
- data/lib/omnizip/formats/cpio/constants.rb +55 -0
- data/lib/omnizip/formats/cpio/entry.rb +385 -0
- data/lib/omnizip/formats/cpio/reader.rb +196 -0
- data/lib/omnizip/formats/cpio/writer.rb +234 -0
- data/lib/omnizip/formats/cpio.rb +140 -0
- data/lib/omnizip/formats/format_spec_loader.rb +230 -0
- data/lib/omnizip/formats/gzip.rb +238 -0
- data/lib/omnizip/formats/iso/directory_builder.rb +297 -0
- data/lib/omnizip/formats/iso/directory_record.rb +152 -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 +197 -0
- data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
- data/lib/omnizip/formats/iso/volume_builder.rb +320 -0
- data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
- data/lib/omnizip/formats/iso/writer.rb +530 -0
- data/lib/omnizip/formats/iso.rb +140 -0
- data/lib/omnizip/formats/lzip.rb +175 -0
- data/lib/omnizip/formats/lzma_alone.rb +171 -0
- data/lib/omnizip/formats/rar/archive_repairer.rb +243 -0
- data/lib/omnizip/formats/rar/archive_verifier.rb +195 -0
- data/lib/omnizip/formats/rar/block_parser.rb +243 -0
- data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
- data/lib/omnizip/formats/rar/compression/dispatcher.rb +217 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +216 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +158 -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/ppmd/context.rb +105 -0
- data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +219 -0
- data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +262 -0
- data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
- data/lib/omnizip/formats/rar/constants.rb +82 -0
- data/lib/omnizip/formats/rar/decompressor.rb +238 -0
- data/lib/omnizip/formats/rar/external_writer.rb +312 -0
- data/lib/omnizip/formats/rar/header.rb +192 -0
- data/lib/omnizip/formats/rar/license_validator.rb +109 -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/parity_handler.rb +292 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +202 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +578 -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 +97 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +166 -0
- data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
- data/lib/omnizip/formats/rar/rar5/header.rb +187 -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 +264 -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 +194 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +109 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +142 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
- data/lib/omnizip/formats/rar/rar5/vint.rb +65 -0
- data/lib/omnizip/formats/rar/rar5/writer.rb +466 -0
- data/lib/omnizip/formats/rar/rar_format_base.rb +241 -0
- data/lib/omnizip/formats/rar/reader.rb +366 -0
- data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
- data/lib/omnizip/formats/rar/volume_manager.rb +168 -0
- data/lib/omnizip/formats/rar/writer.rb +431 -0
- data/lib/omnizip/formats/rar.rb +205 -0
- data/lib/omnizip/formats/rar3/compressor.rb +73 -0
- data/lib/omnizip/formats/rar3/decompressor.rb +66 -0
- data/lib/omnizip/formats/rar3/reader.rb +386 -0
- data/lib/omnizip/formats/rar3/writer.rb +219 -0
- data/lib/omnizip/formats/rar5/compressor.rb +73 -0
- data/lib/omnizip/formats/rar5/decompressor.rb +66 -0
- data/lib/omnizip/formats/rar5/reader.rb +342 -0
- data/lib/omnizip/formats/rar5/writer.rb +214 -0
- data/lib/omnizip/formats/seven_zip/coder_chain.rb +150 -0
- data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
- data/lib/omnizip/formats/seven_zip/encoded_header.rb +114 -0
- data/lib/omnizip/formats/seven_zip/encrypted_header.rb +142 -0
- data/lib/omnizip/formats/seven_zip/file_collector.rb +144 -0
- data/lib/omnizip/formats/seven_zip/header.rb +106 -0
- data/lib/omnizip/formats/seven_zip/header_encryptor.rb +134 -0
- data/lib/omnizip/formats/seven_zip/header_writer.rb +466 -0
- data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
- data/lib/omnizip/formats/seven_zip/models/file_entry.rb +58 -0
- data/lib/omnizip/formats/seven_zip/models/folder.rb +69 -0
- data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
- data/lib/omnizip/formats/seven_zip/parser.rb +660 -0
- data/lib/omnizip/formats/seven_zip/reader.rb +458 -0
- data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +632 -0
- data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +315 -0
- data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
- data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +162 -0
- data/lib/omnizip/formats/seven_zip/writer.rb +740 -0
- data/lib/omnizip/formats/seven_zip.rb +93 -0
- data/lib/omnizip/formats/tar/constants.rb +73 -0
- data/lib/omnizip/formats/tar/entry.rb +94 -0
- data/lib/omnizip/formats/tar/header.rb +168 -0
- data/lib/omnizip/formats/tar/reader.rb +121 -0
- data/lib/omnizip/formats/tar/writer.rb +216 -0
- data/lib/omnizip/formats/tar.rb +84 -0
- data/lib/omnizip/formats/xz/reader.rb +116 -0
- data/lib/omnizip/formats/xz.rb +237 -0
- data/lib/omnizip/formats/xz_impl/block_decoder.rb +754 -0
- data/lib/omnizip/formats/xz_impl/block_encoder.rb +306 -0
- data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
- data/lib/omnizip/formats/xz_impl/block_header_parser.rb +186 -0
- data/lib/omnizip/formats/xz_impl/constants.rb +49 -0
- data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
- data/lib/omnizip/formats/xz_impl/index_encoder.rb +122 -0
- data/lib/omnizip/formats/xz_impl/stream_decoder.rb +468 -0
- data/lib/omnizip/formats/xz_impl/stream_encoder.rb +99 -0
- data/lib/omnizip/formats/xz_impl/stream_footer.rb +81 -0
- data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +117 -0
- data/lib/omnizip/formats/xz_impl/stream_header.rb +55 -0
- data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +108 -0
- data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
- data/lib/omnizip/formats/xz_impl/writer.rb +421 -0
- data/lib/omnizip/formats/zip/central_directory_header.rb +195 -0
- data/lib/omnizip/formats/zip/constants.rb +69 -0
- data/lib/omnizip/formats/zip/end_of_central_directory.rb +133 -0
- data/lib/omnizip/formats/zip/local_file_header.rb +138 -0
- data/lib/omnizip/formats/zip/reader.rb +250 -0
- data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
- data/lib/omnizip/formats/zip/writer.rb +375 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +104 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +66 -0
- data/lib/omnizip/formats/zip/zip64_extra_field.rb +114 -0
- data/lib/omnizip/formats/zip.rb +50 -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/seven_zip/lzma/decoder.rb +421 -0
- data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +465 -0
- data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +288 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +200 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +197 -0
- data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +141 -0
- data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +519 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +723 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +750 -0
- data/lib/omnizip/io/buffered_input.rb +146 -0
- data/lib/omnizip/io/buffered_output.rb +105 -0
- data/lib/omnizip/io/stream_manager.rb +115 -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 +124 -0
- data/lib/omnizip/metadata/archive_metadata.rb +114 -0
- data/lib/omnizip/metadata/entry_metadata.rb +146 -0
- data/lib/omnizip/metadata/metadata_editor.rb +171 -0
- data/lib/omnizip/metadata/metadata_registry.rb +64 -0
- data/lib/omnizip/metadata/metadata_validator.rb +99 -0
- data/lib/omnizip/metadata.rb +57 -0
- data/lib/omnizip/models/.keep +0 -0
- data/lib/omnizip/models/algorithm_metadata.rb +73 -0
- data/lib/omnizip/models/compression_options.rb +71 -0
- data/lib/omnizip/models/conversion_options.rb +87 -0
- data/lib/omnizip/models/conversion_result.rb +135 -0
- data/lib/omnizip/models/eta_result.rb +46 -0
- data/lib/omnizip/models/extraction_rule.rb +115 -0
- data/lib/omnizip/models/filter_chain.rb +144 -0
- data/lib/omnizip/models/filter_config.rb +183 -0
- data/lib/omnizip/models/match_result.rb +124 -0
- data/lib/omnizip/models/optimization_suggestion.rb +91 -0
- data/lib/omnizip/models/parallel_options.rb +104 -0
- data/lib/omnizip/models/performance_result.rb +79 -0
- data/lib/omnizip/models/profile_report.rb +82 -0
- data/lib/omnizip/models/progress_options.rb +38 -0
- data/lib/omnizip/models/split_options.rb +116 -0
- data/lib/omnizip/optimization_registry.rb +81 -0
- data/lib/omnizip/parallel/job_queue.rb +209 -0
- data/lib/omnizip/parallel/job_scheduler.rb +203 -0
- data/lib/omnizip/parallel/parallel_compressor.rb +347 -0
- data/lib/omnizip/parallel/parallel_extractor.rb +329 -0
- data/lib/omnizip/parallel/worker_pool.rb +223 -0
- data/lib/omnizip/parallel.rb +149 -0
- data/lib/omnizip/parity/chunked_block_processor.rb +196 -0
- data/lib/omnizip/parity/galois16.rb +145 -0
- data/lib/omnizip/parity/models/creator_packet.rb +73 -0
- data/lib/omnizip/parity/models/file_description_packet.rb +133 -0
- data/lib/omnizip/parity/models/ifsc_packet.rb +123 -0
- data/lib/omnizip/parity/models/main_packet.rb +128 -0
- data/lib/omnizip/parity/models/packet.rb +156 -0
- data/lib/omnizip/parity/models/packet_registry.rb +109 -0
- data/lib/omnizip/parity/models/recovery_slice_packet.rb +78 -0
- data/lib/omnizip/parity/par2_creator.rb +531 -0
- data/lib/omnizip/parity/par2_repairer.rb +407 -0
- data/lib/omnizip/parity/par2_verifier.rb +364 -0
- data/lib/omnizip/parity/par2cmdline_algorithm.rb +110 -0
- data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
- data/lib/omnizip/parity/reed_solomon_decoder.rb +266 -0
- data/lib/omnizip/parity/reed_solomon_encoder.rb +111 -0
- data/lib/omnizip/parity/reed_solomon_matrix.rb +342 -0
- data/lib/omnizip/parity.rb +186 -0
- data/lib/omnizip/password/encryption_registry.rb +65 -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 +192 -0
- data/lib/omnizip/password/zip_crypto_strategy.rb +141 -0
- data/lib/omnizip/password.rb +87 -0
- data/lib/omnizip/pipe/stream_compressor.rb +124 -0
- data/lib/omnizip/pipe/stream_decompressor.rb +174 -0
- data/lib/omnizip/pipe.rb +121 -0
- data/lib/omnizip/platform/ntfs_streams.rb +201 -0
- data/lib/omnizip/platform.rb +189 -0
- data/lib/omnizip/profile/archive_profile.rb +39 -0
- data/lib/omnizip/profile/balanced_profile.rb +33 -0
- data/lib/omnizip/profile/binary_profile.rb +36 -0
- data/lib/omnizip/profile/compression_profile.rb +158 -0
- data/lib/omnizip/profile/custom_profile.rb +157 -0
- data/lib/omnizip/profile/fast_profile.rb +33 -0
- data/lib/omnizip/profile/maximum_profile.rb +33 -0
- data/lib/omnizip/profile/profile_detector.rb +110 -0
- data/lib/omnizip/profile/profile_registry.rb +161 -0
- data/lib/omnizip/profile/text_profile.rb +36 -0
- data/lib/omnizip/profile.rb +190 -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 +169 -0
- data/lib/omnizip/profiler.rb +204 -0
- data/lib/omnizip/progress/callback_reporter.rb +36 -0
- data/lib/omnizip/progress/console_reporter.rb +62 -0
- data/lib/omnizip/progress/log_reporter.rb +91 -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 +190 -0
- data/lib/omnizip/progress/silent_reporter.rb +24 -0
- data/lib/omnizip/progress.rb +127 -0
- data/lib/omnizip/rubyzip_compat.rb +63 -0
- data/lib/omnizip/temp/safe_extract.rb +168 -0
- data/lib/omnizip/temp/temp_file.rb +124 -0
- data/lib/omnizip/temp/temp_file_pool.rb +109 -0
- data/lib/omnizip/temp.rb +181 -0
- data/lib/omnizip/version.rb +5 -0
- data/lib/omnizip/zip/entry.rb +156 -0
- data/lib/omnizip/zip/file.rb +485 -0
- data/lib/omnizip/zip/input_stream.rb +273 -0
- data/lib/omnizip/zip/output_stream.rb +324 -0
- data/lib/omnizip.rb +156 -0
- data/readme-docs/advanced-features.adoc +515 -0
- data/readme-docs/api-usage.adoc +444 -0
- data/readme-docs/architecture.adoc +449 -0
- data/readme-docs/archive-formats.adoc +479 -0
- data/readme-docs/cli-usage.adoc +222 -0
- data/readme-docs/compression-algorithms.adoc +442 -0
- data/readme-docs/compression-profiles.adoc +247 -0
- data/readme-docs/encryption-checksums.adoc +328 -0
- data/readme-docs/format-converter.adoc +325 -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/xz-file-format-1.2.1.txt +1174 -0
- metadata +617 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
6
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
7
|
+
# to deal in the Software without restriction, including without limitation
|
|
8
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
9
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
10
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
|
13
|
+
# all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
20
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
21
|
+
# DEALINGS IN THE SOFTWARE.
|
|
22
|
+
|
|
23
|
+
module Omnizip
|
|
24
|
+
module Implementations
|
|
25
|
+
module Base
|
|
26
|
+
# Abstract base class for LZMA2 decoders.
|
|
27
|
+
#
|
|
28
|
+
# This class defines the common interface and shared functionality
|
|
29
|
+
# for all LZMA2 decoder implementations (XZ Utils, 7-Zip, etc.).
|
|
30
|
+
#
|
|
31
|
+
# Subclasses must implement the {#decode} method.
|
|
32
|
+
#
|
|
33
|
+
# @abstract Subclasses must implement {#decode}
|
|
34
|
+
class LZMA2DecoderBase
|
|
35
|
+
attr_reader :dict_size
|
|
36
|
+
|
|
37
|
+
# Initialize the LZMA2 decoder.
|
|
38
|
+
#
|
|
39
|
+
# @param input [IO] Input stream of compressed data
|
|
40
|
+
# @param options [Hash] Decoding options
|
|
41
|
+
# @option options [Integer] :dict_size Dictionary size (read from properties)
|
|
42
|
+
def initialize(input, options = {})
|
|
43
|
+
@input = input
|
|
44
|
+
# Dictionary size will be read from LZMA2 property byte by subclasses
|
|
45
|
+
@dict_size = options.fetch(:dict_size, nil)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Decode LZMA2 compressed data.
|
|
49
|
+
#
|
|
50
|
+
# Subclasses must implement this method to provide the specific
|
|
51
|
+
# decoding logic for their implementation (XZ Utils, 7-Zip, etc.).
|
|
52
|
+
#
|
|
53
|
+
# @param output [IO] Output stream for decompressed data
|
|
54
|
+
# @raise [NotImplementedError] Always raised in base class
|
|
55
|
+
# @return [void]
|
|
56
|
+
def decode(output = nil)
|
|
57
|
+
raise NotImplementedError,
|
|
58
|
+
"#{self.class} must implement #decode"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Get the implementation identifier.
|
|
62
|
+
#
|
|
63
|
+
# Subclasses must implement this to return a symbol identifying
|
|
64
|
+
# their implementation (e.g., :xz_utils, :seven_zip).
|
|
65
|
+
#
|
|
66
|
+
# @raise [NotImplementedError] Always raised in base class
|
|
67
|
+
# @return [Symbol] Implementation identifier
|
|
68
|
+
def implementation_name
|
|
69
|
+
raise NotImplementedError,
|
|
70
|
+
"#{self.class} must implement #implementation_name"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
6
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
7
|
+
# to deal in the Software without restriction, including without limitation
|
|
8
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
9
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
10
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
|
13
|
+
# all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
20
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
21
|
+
# DEALINGS IN THE SOFTWARE.
|
|
22
|
+
|
|
23
|
+
module Omnizip
|
|
24
|
+
module Implementations
|
|
25
|
+
module Base
|
|
26
|
+
# Abstract base class for LZMA2 encoders.
|
|
27
|
+
#
|
|
28
|
+
# This class defines the common interface and shared functionality
|
|
29
|
+
# for all LZMA2 encoder implementations (XZ Utils, 7-Zip, etc.).
|
|
30
|
+
#
|
|
31
|
+
# LZMA2 is an improved version of LZMA that supports:
|
|
32
|
+
# - Uncompressed chunks for incompressible data
|
|
33
|
+
# - Dictionary/state resets for better compression
|
|
34
|
+
# - Simpler chunk format
|
|
35
|
+
#
|
|
36
|
+
# Subclasses must implement the {#encode} method.
|
|
37
|
+
#
|
|
38
|
+
# @abstract Subclasses must implement {#encode}
|
|
39
|
+
class LZMA2EncoderBase
|
|
40
|
+
attr_reader :dict_size, :lc, :lp, :pb
|
|
41
|
+
|
|
42
|
+
# Maximum uncompressed size per LZMA2 chunk (2MB)
|
|
43
|
+
UNCOMPRESSED_MAX = 1 << 21
|
|
44
|
+
# Maximum compressed size per LZMA2 chunk (64KB)
|
|
45
|
+
COMPRESSED_MAX = 1 << 16
|
|
46
|
+
|
|
47
|
+
# Initialize the LZMA2 encoder.
|
|
48
|
+
#
|
|
49
|
+
# @param options [Hash] Encoding options
|
|
50
|
+
# @option options [Integer] :dict_size Dictionary size (default: 8MB)
|
|
51
|
+
# @option options [Integer] :lc Literal context bits (default: 3)
|
|
52
|
+
# @option options [Integer] :lp Literal position bits (default: 0)
|
|
53
|
+
# @option options [Integer] :pb Position bits (default: 2)
|
|
54
|
+
# @option options [Boolean] :standalone Write property byte at start (default: true)
|
|
55
|
+
def initialize(options = {})
|
|
56
|
+
@dict_size = options.fetch(:dict_size, 8 * 1024 * 1024)
|
|
57
|
+
@lc = options.fetch(:lc, 3)
|
|
58
|
+
@lp = options.fetch(:lp, 0)
|
|
59
|
+
@pb = options.fetch(:pb, 2)
|
|
60
|
+
@standalone = options.fetch(:standalone, true)
|
|
61
|
+
|
|
62
|
+
validate_parameters!
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Encode data using LZMA2.
|
|
66
|
+
#
|
|
67
|
+
# Subclasses must implement this method to provide the specific
|
|
68
|
+
# encoding logic for their implementation (XZ Utils, 7-Zip, etc.).
|
|
69
|
+
#
|
|
70
|
+
# @param data [String] Input data to compress
|
|
71
|
+
# @raise [NotImplementedError] Always raised in base class
|
|
72
|
+
# @return [String] Compressed data
|
|
73
|
+
def encode(data)
|
|
74
|
+
raise NotImplementedError,
|
|
75
|
+
"#{self.class} must implement #encode"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Get the implementation identifier.
|
|
79
|
+
#
|
|
80
|
+
# Subclasses must implement this to return a symbol identifying
|
|
81
|
+
# their implementation (e.g., :xz_utils, :seven_zip).
|
|
82
|
+
#
|
|
83
|
+
# @raise [NotImplementedError] Always raised in base class
|
|
84
|
+
# @return [Symbol] Implementation identifier
|
|
85
|
+
def implementation_name
|
|
86
|
+
raise NotImplementedError,
|
|
87
|
+
"#{self.class} must implement #implementation_name"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Check if standalone mode is enabled.
|
|
91
|
+
#
|
|
92
|
+
# @return [Boolean] true if property byte should be written
|
|
93
|
+
def standalone?
|
|
94
|
+
@standalone
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
private
|
|
98
|
+
|
|
99
|
+
# Validate LZMA2 parameters.
|
|
100
|
+
#
|
|
101
|
+
# @raise [ArgumentError] If any parameter is out of valid range
|
|
102
|
+
# @return [void]
|
|
103
|
+
def validate_parameters!
|
|
104
|
+
unless @lc.between?(0, 8)
|
|
105
|
+
raise ArgumentError, "lc must be between 0 and 8, got #{@lc}"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
unless @lp.between?(0, 4)
|
|
109
|
+
raise ArgumentError, "lp must be between 0 and 4, got #{@lp}"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
unless @pb.between?(0, 4)
|
|
113
|
+
raise ArgumentError, "pb must be between 0 and 4, got #{@pb}"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# LZMA2 dictionary size constraints (from XZ Utils)
|
|
117
|
+
min_dict = 4096
|
|
118
|
+
max_dict = 1 << 28
|
|
119
|
+
|
|
120
|
+
unless @dict_size.between?(min_dict, max_dict)
|
|
121
|
+
raise ArgumentError,
|
|
122
|
+
"dict_size must be between #{min_dict} and #{max_dict}, got #{@dict_size}"
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
6
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
7
|
+
# to deal in the Software without restriction, including without limitation
|
|
8
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
9
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
10
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
|
13
|
+
# all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
20
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
21
|
+
# DEALINGS IN THE SOFTWARE.
|
|
22
|
+
|
|
23
|
+
module Omnizip
|
|
24
|
+
module Implementations
|
|
25
|
+
module Base
|
|
26
|
+
# Abstract base class for LZMA decoders.
|
|
27
|
+
#
|
|
28
|
+
# This class defines the common interface and shared functionality
|
|
29
|
+
# for all LZMA decoder implementations (XZ Utils, 7-Zip SDK, etc.).
|
|
30
|
+
#
|
|
31
|
+
# Subclasses must implement the {#decode_stream} method.
|
|
32
|
+
#
|
|
33
|
+
# @abstract Subclasses must implement {#decode_stream}
|
|
34
|
+
class LZMADecoderBase
|
|
35
|
+
attr_reader :lc, :lp, :pb, :dict_size, :uncompressed_size, :input
|
|
36
|
+
|
|
37
|
+
# Initialize the LZMA decoder.
|
|
38
|
+
#
|
|
39
|
+
# @param input [IO] Input stream of compressed data
|
|
40
|
+
# @param options [Hash] Decoding options
|
|
41
|
+
# @option options [Integer] :lc Literal context bits (read from header)
|
|
42
|
+
# @option options [Integer] :lp Literal position bits (read from header)
|
|
43
|
+
# @option options [Integer] :pb Position bits (read from header)
|
|
44
|
+
# @option options [Integer] :dict_size Dictionary size (read from header)
|
|
45
|
+
# @option options [Integer] :uncompressed_size Uncompressed size
|
|
46
|
+
def initialize(input, options = {})
|
|
47
|
+
@input = input
|
|
48
|
+
# Parameters will be read from LZMA header by subclasses
|
|
49
|
+
@lc = options.fetch(:lc, nil)
|
|
50
|
+
@lp = options.fetch(:lp, nil)
|
|
51
|
+
@pb = options.fetch(:pb, nil)
|
|
52
|
+
@dict_size = options.fetch(:dict_size, nil)
|
|
53
|
+
@uncompressed_size = options.fetch(:uncompressed_size, nil)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Decode a stream of compressed data.
|
|
57
|
+
#
|
|
58
|
+
# Subclasses must implement this method to provide the specific
|
|
59
|
+
# decoding logic for their implementation (XZ Utils, 7-Zip, etc.).
|
|
60
|
+
#
|
|
61
|
+
# @param output [IO] Output stream for decompressed data
|
|
62
|
+
# @raise [NotImplementedError] Always raised in base class
|
|
63
|
+
# @return [void]
|
|
64
|
+
def decode_stream(output = nil)
|
|
65
|
+
raise NotImplementedError,
|
|
66
|
+
"#{self.class} must implement #decode_stream"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Get the implementation identifier.
|
|
70
|
+
#
|
|
71
|
+
# Subclasses must implement this to return a symbol identifying
|
|
72
|
+
# their implementation (e.g., :xz_utils, :seven_zip).
|
|
73
|
+
#
|
|
74
|
+
# @raise [NotImplementedError] Always raised in base class
|
|
75
|
+
# @return [Symbol] Implementation identifier
|
|
76
|
+
def implementation_name
|
|
77
|
+
raise NotImplementedError,
|
|
78
|
+
"#{self.class} must implement #implementation_name"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
6
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
7
|
+
# to deal in the Software without restriction, including without limitation
|
|
8
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
9
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
10
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
|
13
|
+
# all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
20
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
21
|
+
# DEALINGS IN THE SOFTWARE.
|
|
22
|
+
|
|
23
|
+
module Omnizip
|
|
24
|
+
module Implementations
|
|
25
|
+
module Base
|
|
26
|
+
# Abstract base class for LZMA encoders.
|
|
27
|
+
#
|
|
28
|
+
# This class defines the common interface and shared functionality
|
|
29
|
+
# for all LZMA encoder implementations (XZ Utils, 7-Zip SDK, etc.).
|
|
30
|
+
#
|
|
31
|
+
# Subclasses must implement the {#encode_stream} method.
|
|
32
|
+
#
|
|
33
|
+
# @abstract Subclasses must implement {#encode_stream}
|
|
34
|
+
class LZMAEncoderBase
|
|
35
|
+
attr_reader :lc, :lp, :pb, :dict_size, :output
|
|
36
|
+
|
|
37
|
+
# Initialize the LZMA encoder.
|
|
38
|
+
#
|
|
39
|
+
# @param output [IO] Output stream for compressed data
|
|
40
|
+
# @param options [Hash] Encoding options
|
|
41
|
+
# @option options [Integer] :lc Literal context bits (0-8, default: 3)
|
|
42
|
+
# @option options [Integer] :lp Literal position bits (0-4, default: 0)
|
|
43
|
+
# @option options [Integer] :pb Position bits (0-4, default: 2)
|
|
44
|
+
# @option options [Integer] :dict_size Dictionary size (default: 64KB)
|
|
45
|
+
# @raise [ArgumentError] If parameters are invalid
|
|
46
|
+
def initialize(output, options = {})
|
|
47
|
+
@output = output
|
|
48
|
+
@lc = options.fetch(:lc, 3)
|
|
49
|
+
@lp = options.fetch(:lp, 0)
|
|
50
|
+
@pb = options.fetch(:pb, 2)
|
|
51
|
+
@dict_size = options.fetch(:dict_size, 1 << 16) # 64KB default
|
|
52
|
+
|
|
53
|
+
validate_parameters!
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Encode a stream of data.
|
|
57
|
+
#
|
|
58
|
+
# Subclasses must implement this method to provide the specific
|
|
59
|
+
# encoding logic for their implementation (XZ Utils, 7-Zip, etc.).
|
|
60
|
+
#
|
|
61
|
+
# @param data [String] Input data to compress
|
|
62
|
+
# @raise [NotImplementedError] Always raised in base class
|
|
63
|
+
# @return [void]
|
|
64
|
+
def encode_stream(data)
|
|
65
|
+
raise NotImplementedError,
|
|
66
|
+
"#{self.class} must implement #encode_stream"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Get the implementation identifier.
|
|
70
|
+
#
|
|
71
|
+
# Subclasses must implement this to return a symbol identifying
|
|
72
|
+
# their implementation (e.g., :xz_utils, :seven_zip).
|
|
73
|
+
#
|
|
74
|
+
# @raise [NotImplementedError] Always raised in base class
|
|
75
|
+
# @return [Symbol] Implementation identifier
|
|
76
|
+
def implementation_name
|
|
77
|
+
raise NotImplementedError,
|
|
78
|
+
"#{self.class} must implement #implementation_name"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
# Validate LZMA parameters.
|
|
84
|
+
#
|
|
85
|
+
# @raise [ArgumentError] If any parameter is out of valid range
|
|
86
|
+
# @return [void]
|
|
87
|
+
def validate_parameters!
|
|
88
|
+
unless @lc.between?(0, 8)
|
|
89
|
+
raise ArgumentError, "lc must be between 0 and 8, got #{@lc}"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
unless @lp.between?(0, 4)
|
|
93
|
+
raise ArgumentError, "lp must be between 0 and 4, got #{@lp}"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
unless @pb.between?(0, 4)
|
|
97
|
+
raise ArgumentError, "pb must be between 0 and 4, got #{@pb}"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
unless @dict_size.between?(4096, 1 << 28)
|
|
101
|
+
raise ArgumentError,
|
|
102
|
+
"dict_size must be between 4096 and 268435456, got #{@dict_size}"
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
6
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
7
|
+
# to deal in the Software without restriction, including without limitation
|
|
8
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
9
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
10
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
|
13
|
+
# all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
20
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
21
|
+
# DEALINGS IN THE SOFTWARE.
|
|
22
|
+
|
|
23
|
+
module Omnizip
|
|
24
|
+
module Implementations
|
|
25
|
+
module Base
|
|
26
|
+
# Abstract base class for LZMA state machines.
|
|
27
|
+
#
|
|
28
|
+
# Both XZ Utils and 7-Zip use a 12-state finite state machine (FSM)
|
|
29
|
+
# for tracking the encoding context. However, they have different
|
|
30
|
+
# transition tables between states.
|
|
31
|
+
#
|
|
32
|
+
# The 12 states are:
|
|
33
|
+
# - States 0-6: Literal mode (last symbol was a literal)
|
|
34
|
+
# - States 7-9: Match mode (last symbol was a match)
|
|
35
|
+
# - States 10-11: Short rep match mode (last symbol was a rep match of length 1)
|
|
36
|
+
#
|
|
37
|
+
# State transitions depend on whether the current symbol is:
|
|
38
|
+
# - A literal (byte)
|
|
39
|
+
# - A match (length + distance)
|
|
40
|
+
# - A repeated match (using rep0-rep3)
|
|
41
|
+
#
|
|
42
|
+
# Subclasses must provide their specific transition table via
|
|
43
|
+
# the {#update!} method.
|
|
44
|
+
#
|
|
45
|
+
# @abstract Subclasses must implement {#update!}
|
|
46
|
+
class StateMachineBase
|
|
47
|
+
# All valid LZMA states (0-11)
|
|
48
|
+
STATES = (0..11)
|
|
49
|
+
|
|
50
|
+
# States where literal encoding should use matched literal mode
|
|
51
|
+
# (i.e., compare with match byte at rep0)
|
|
52
|
+
LITERAL_MATCHED_STATES = [7, 8, 9, 10, 11].freeze
|
|
53
|
+
|
|
54
|
+
attr_reader :state
|
|
55
|
+
|
|
56
|
+
# Initialize the state machine.
|
|
57
|
+
#
|
|
58
|
+
# @param initial_state [Integer] Initial state value (default: 0)
|
|
59
|
+
def initialize(initial_state = 0)
|
|
60
|
+
unless STATES.include?(initial_state)
|
|
61
|
+
raise ArgumentError,
|
|
62
|
+
"Invalid initial state: #{initial_state}, must be 0-11"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
@state = initial_state
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Reset to initial state.
|
|
69
|
+
#
|
|
70
|
+
# @return [void]
|
|
71
|
+
def reset!
|
|
72
|
+
@state = 0
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Update state based on encoding decision.
|
|
76
|
+
#
|
|
77
|
+
# Both XZ Utils and 7-Zip use different transition tables.
|
|
78
|
+
# Subclasses must implement this with their specific table.
|
|
79
|
+
#
|
|
80
|
+
# @param is_match [Boolean] true if last symbol was a match, false if literal
|
|
81
|
+
# @param is_short_rep [Boolean] true if last symbol was a short rep (length=1)
|
|
82
|
+
# @raise [NotImplementedError] Always raised in base class
|
|
83
|
+
# @return [void]
|
|
84
|
+
def update!(is_match, is_short_rep: false)
|
|
85
|
+
raise NotImplementedError,
|
|
86
|
+
"#{self.class} must implement #update!"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Update state for literal encoding.
|
|
90
|
+
#
|
|
91
|
+
# This is a convenience method that calls {#update!} with is_match=false.
|
|
92
|
+
#
|
|
93
|
+
# @return [void]
|
|
94
|
+
def update_literal!
|
|
95
|
+
update!(false)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Update state for match encoding.
|
|
99
|
+
#
|
|
100
|
+
# This is a convenience method that calls {#update!} with is_match=true.
|
|
101
|
+
#
|
|
102
|
+
# @return [void]
|
|
103
|
+
def update_match!(_distance = nil)
|
|
104
|
+
update!(true)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Update state for short rep match (length=1).
|
|
108
|
+
#
|
|
109
|
+
# This is a convenience method that calls {#update!} with appropriate params.
|
|
110
|
+
#
|
|
111
|
+
# @return [void]
|
|
112
|
+
def update_short_rep!
|
|
113
|
+
update!(true, is_short_rep: true)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Update state for long rep match (length>1).
|
|
117
|
+
#
|
|
118
|
+
# This is a convenience method that calls {#update!} with appropriate params.
|
|
119
|
+
#
|
|
120
|
+
# @return [void]
|
|
121
|
+
def update_long_rep!
|
|
122
|
+
update!(true, is_short_rep: false)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Check if currently in literal mode.
|
|
126
|
+
#
|
|
127
|
+
# States 0-6 are considered "literal mode" where the last symbol
|
|
128
|
+
# was a literal byte.
|
|
129
|
+
#
|
|
130
|
+
# @return [Boolean] true if in literal mode (states 0-6)
|
|
131
|
+
def literal_mode?
|
|
132
|
+
@state < 7
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Check if currently in match mode.
|
|
136
|
+
#
|
|
137
|
+
# States 7-11 are considered "match mode" where the last symbol
|
|
138
|
+
# was a match of some kind.
|
|
139
|
+
#
|
|
140
|
+
# @return [Boolean] true if in match mode (states 7-11)
|
|
141
|
+
def match_mode?
|
|
142
|
+
@state >= 7
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Check if matched literal encoding should be used.
|
|
146
|
+
#
|
|
147
|
+
# In states 7-11, literal encoding should compare with the match byte
|
|
148
|
+
# at rep0 for better compression.
|
|
149
|
+
#
|
|
150
|
+
# @return [Boolean] true if matched literal should be used
|
|
151
|
+
def use_matched_literal?
|
|
152
|
+
LITERAL_MATCHED_STATES.include?(@state)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Get state as integer.
|
|
156
|
+
#
|
|
157
|
+
# This is used for probability model indexing.
|
|
158
|
+
#
|
|
159
|
+
# @return [Integer] Current state value (0-11)
|
|
160
|
+
def value
|
|
161
|
+
@state
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Set state directly.
|
|
165
|
+
#
|
|
166
|
+
# This is useful for initialization or testing.
|
|
167
|
+
#
|
|
168
|
+
# @param new_state [Integer] New state value (0-11)
|
|
169
|
+
# @raise [ArgumentError] If state is invalid
|
|
170
|
+
# @return [void]
|
|
171
|
+
def state=(new_state)
|
|
172
|
+
unless STATES.include?(new_state)
|
|
173
|
+
raise ArgumentError,
|
|
174
|
+
"Invalid state: #{new_state}, must be 0-11"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
@state = new_state
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|