omnizip 0.4.7-arm-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +32 -0
- data/.rubocop_todo.yml +293 -0
- data/CHANGELOG.md +1647 -0
- data/CONTEXT.md +68 -0
- data/COPYING +502 -0
- data/Gemfile +19 -0
- data/LICENSE +12 -0
- data/README.adoc +1327 -0
- data/Rakefile +15 -0
- data/TODO.refactor/00-overview.md +67 -0
- data/TODO.refactor/01-registry-base-class.md +81 -0
- data/TODO.refactor/02-error-hierarchy.md +57 -0
- data/TODO.refactor/03-autoload-entry-point.md +69 -0
- data/TODO.refactor/04-filter-base-consolidation.md +49 -0
- data/TODO.refactor/05-send-private-methods.md +64 -0
- data/TODO.refactor/06-instance-variable-access.md +69 -0
- data/TODO.refactor/07-respond-to-replacement.md +237 -0
- data/TODO.refactor/08-spec-doubles.md +27 -0
- data/TODO.refactor/09-cli-shared-module.md +35 -0
- data/TODO.refactor/10-format-detector-ocp.md +34 -0
- data/TODO.refactor/11-convenience-decoupling.md +38 -0
- data/TODO.refactor/12-thread-safety.md +8 -0
- data/TODO.refactor/13-lutaml-model-migration.md +158 -0
- data/TODO.refactor/14-add-missing-specs.md +25 -0
- data/benchmark/README.md +260 -0
- data/benchmark/benchmark_suite.rb +125 -0
- data/benchmark/compression_bench.rb +181 -0
- data/benchmark/filter_bench.rb +180 -0
- data/benchmark/models/benchmark_result.rb +59 -0
- data/benchmark/models/comparison_result.rb +69 -0
- data/benchmark/profile_suite.rb +167 -0
- data/benchmark/reporter.rb +150 -0
- data/benchmark/run_benchmarks.rb +66 -0
- data/benchmark/test_data.rb +137 -0
- data/config/formats/rar3_spec.yml +92 -0
- data/config/formats/rar5_spec.yml +102 -0
- data/docs/.github/workflows/docs.yml +142 -0
- data/docs/.gitignore +21 -0
- data/docs/.lychee.toml +67 -0
- data/docs/Gemfile +13 -0
- data/docs/RAR_WRITE_SUPPORT.md +26 -0
- data/docs/README.md +101 -0
- data/docs/_config.yml +112 -0
- data/docs/assets/logo.svg +1 -0
- data/docs/assets/omnizip-logo.pdf +1540 -11
- data/docs/comparison/feature-matrix.adoc +694 -0
- data/docs/comparison/index.adoc +113 -0
- data/docs/comparison/vs-7zip.adoc +309 -0
- data/docs/comparison/vs-peazip.adoc +77 -0
- data/docs/comparison/vs-rubyzip.adoc +342 -0
- data/docs/comparison/vs-winrar.adoc +100 -0
- data/docs/compatibility.adoc +579 -0
- data/docs/concepts/index.adoc +129 -0
- data/docs/developer/architecture.adoc +256 -0
- data/docs/developer/contributing.adoc +158 -0
- data/docs/developer/index.adoc +25 -0
- data/docs/developer/testing.adoc +212 -0
- data/docs/getting-started/basic-usage.adoc +263 -0
- data/docs/getting-started/index.adoc +42 -0
- data/docs/getting-started/installation.adoc +138 -0
- data/docs/getting-started/quick-start.adoc +183 -0
- data/docs/getting-started/your-first-archive.adoc +219 -0
- data/docs/guides/advanced-features/encryption.adoc +277 -0
- data/docs/guides/advanced-features/index.adoc +59 -0
- data/docs/guides/advanced-features/parallel-processing.adoc +144 -0
- data/docs/guides/advanced-features/progress-tracking.adoc +124 -0
- data/docs/guides/advanced-features/streaming.adoc +142 -0
- data/docs/guides/archive-formats/gzip-format.adoc +105 -0
- data/docs/guides/archive-formats/index.adoc +160 -0
- data/docs/guides/archive-formats/ole-format.adoc +151 -0
- data/docs/guides/archive-formats/rar-format.adoc +104 -0
- data/docs/guides/archive-formats/rar5.adoc +521 -0
- data/docs/guides/archive-formats/rpm-format.adoc +108 -0
- data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
- data/docs/guides/archive-formats/tar-format.adoc +106 -0
- data/docs/guides/archive-formats/xz-format.adoc +118 -0
- data/docs/guides/archive-formats/zip-format.adoc +35 -0
- data/docs/guides/compression-algorithms/bzip2.adoc +114 -0
- data/docs/guides/compression-algorithms/deflate.adoc +313 -0
- data/docs/guides/compression-algorithms/index.adoc +190 -0
- data/docs/guides/compression-algorithms/lzma.adoc +394 -0
- data/docs/guides/compression-algorithms/lzma2.adoc +244 -0
- data/docs/guides/compression-algorithms/ppmd.adoc +313 -0
- data/docs/guides/compression-algorithms/zstandard.adoc +296 -0
- data/docs/guides/creating-archives.adoc +348 -0
- data/docs/guides/extracting-archives.adoc +53 -0
- data/docs/guides/format-conversion.adoc +64 -0
- data/docs/guides/index.adoc +49 -0
- data/docs/guides/migration-rubyzip.adoc +217 -0
- data/docs/guides/parity-archives.adoc +605 -0
- data/docs/guides/performance-tuning.adoc +88 -0
- data/docs/index.adoc +228 -0
- data/docs/lychee.toml +67 -0
- data/docs/reference/api/overview.adoc +187 -0
- data/docs/reference/cli/compress-command.adoc +114 -0
- data/docs/reference/cli/overview.adoc +140 -0
- data/docs/reference/index.adoc +26 -0
- data/docs/resources/faq.adoc +185 -0
- data/docs/resources/quick-reference.adoc +222 -0
- data/docs/rust-backend.md +0 -0
- data/docs/troubleshooting/index.adoc +207 -0
- data/docs/xar_format.md +216 -0
- data/examples/api_comparison.rb +205 -0
- data/examples/deflate64_example.rb +96 -0
- data/examples/par2_demo.rb +121 -0
- data/examples/quick_start_native.rb +150 -0
- data/examples/quick_start_rubyzip.rb +115 -0
- data/examples/rubyzip_compatibility_demo.rb +194 -0
- data/exe/omnizip +27 -0
- data/lib/omnizip/algorithm.rb +176 -0
- data/lib/omnizip/algorithm_registry.rb +65 -0
- data/lib/omnizip/algorithms/.keep +0 -0
- data/lib/omnizip/algorithms/bzip2/bwt.rb +236 -0
- data/lib/omnizip/algorithms/bzip2/bz2.rb +687 -0
- data/lib/omnizip/algorithms/bzip2/rle.rb +146 -0
- data/lib/omnizip/algorithms/bzip2.rb +108 -0
- data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
- data/lib/omnizip/algorithms/deflate/decoder.rb +37 -0
- data/lib/omnizip/algorithms/deflate/encoder.rb +45 -0
- data/lib/omnizip/algorithms/deflate.rb +135 -0
- data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
- data/lib/omnizip/algorithms/deflate64/decoder.rb +151 -0
- data/lib/omnizip/algorithms/deflate64/encoder.rb +95 -0
- data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +352 -0
- data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +140 -0
- data/lib/omnizip/algorithms/deflate64.rb +118 -0
- data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
- data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
- data/lib/omnizip/algorithms/lzma/decoder.rb +146 -0
- data/lib/omnizip/algorithms/lzma/dictionary.rb +70 -0
- data/lib/omnizip/algorithms/lzma/distance_coder.rb +326 -0
- data/lib/omnizip/algorithms/lzma/encoder.rb +139 -0
- data/lib/omnizip/algorithms/lzma/length_coder.rb +172 -0
- data/lib/omnizip/algorithms/lzma/literal_decoder.rb +204 -0
- data/lib/omnizip/algorithms/lzma/literal_encoder.rb +208 -0
- data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +368 -0
- data/lib/omnizip/algorithms/lzma/lzma1_encoder.rb +105 -0
- data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +194 -0
- data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
- data/lib/omnizip/algorithms/lzma/match.rb +32 -0
- data/lib/omnizip/algorithms/lzma/match_finder.rb +233 -0
- data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
- data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +84 -0
- data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +159 -0
- data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
- data/lib/omnizip/algorithms/lzma/range_coder.rb +82 -0
- data/lib/omnizip/algorithms/lzma/range_decoder.rb +274 -0
- data/lib/omnizip/algorithms/lzma/range_encoder.rb +202 -0
- data/lib/omnizip/algorithms/lzma/state.rb +127 -0
- data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +323 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder.rb +420 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +640 -0
- data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +224 -0
- data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +167 -0
- data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +258 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +314 -0
- data/lib/omnizip/algorithms/lzma/xz_state.rb +108 -0
- data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +1311 -0
- data/lib/omnizip/algorithms/lzma.rb +266 -0
- data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +180 -0
- data/lib/omnizip/algorithms/lzma2/constants.rb +38 -0
- data/lib/omnizip/algorithms/lzma2/encoder.rb +145 -0
- data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +165 -0
- data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
- data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +122 -0
- data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
- data/lib/omnizip/algorithms/lzma2.rb +133 -0
- data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
- data/lib/omnizip/algorithms/ppmd7/context.rb +151 -0
- data/lib/omnizip/algorithms/ppmd7/decoder.rb +127 -0
- data/lib/omnizip/algorithms/ppmd7/encoder.rb +153 -0
- data/lib/omnizip/algorithms/ppmd7/model.rb +245 -0
- data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
- data/lib/omnizip/algorithms/ppmd7.rb +146 -0
- data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
- data/lib/omnizip/algorithms/ppmd8/context.rb +32 -0
- data/lib/omnizip/algorithms/ppmd8/decoder.rb +104 -0
- data/lib/omnizip/algorithms/ppmd8/encoder.rb +135 -0
- data/lib/omnizip/algorithms/ppmd8/model.rb +246 -0
- data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
- data/lib/omnizip/algorithms/ppmd8.rb +122 -0
- data/lib/omnizip/algorithms/ppmd_base.rb +142 -0
- data/lib/omnizip/algorithms/registration.rb +28 -0
- data/lib/omnizip/algorithms/zstandard/constants.rb +158 -0
- data/lib/omnizip/algorithms/zstandard/decoder.rb +249 -0
- data/lib/omnizip/algorithms/zstandard/dictionary.rb +73 -0
- data/lib/omnizip/algorithms/zstandard/encoder.rb +294 -0
- data/lib/omnizip/algorithms/zstandard/frame/block.rb +143 -0
- data/lib/omnizip/algorithms/zstandard/frame/header.rb +233 -0
- data/lib/omnizip/algorithms/zstandard/frame.rb +33 -0
- data/lib/omnizip/algorithms/zstandard/fse/bitstream.rb +183 -0
- data/lib/omnizip/algorithms/zstandard/fse/encoder.rb +534 -0
- data/lib/omnizip/algorithms/zstandard/fse/interleaved.rb +92 -0
- data/lib/omnizip/algorithms/zstandard/fse/table.rb +188 -0
- data/lib/omnizip/algorithms/zstandard/fse/table_description.rb +203 -0
- data/lib/omnizip/algorithms/zstandard/fse.rb +53 -0
- data/lib/omnizip/algorithms/zstandard/huffman.rb +276 -0
- data/lib/omnizip/algorithms/zstandard/huffman_encoder.rb +327 -0
- data/lib/omnizip/algorithms/zstandard/ldm.rb +121 -0
- data/lib/omnizip/algorithms/zstandard/literals.rb +241 -0
- data/lib/omnizip/algorithms/zstandard/literals_encoder.rb +96 -0
- data/lib/omnizip/algorithms/zstandard/match_finder.rb +483 -0
- data/lib/omnizip/algorithms/zstandard/sequences.rb +350 -0
- data/lib/omnizip/algorithms/zstandard/sequences_encoder.rb +333 -0
- data/lib/omnizip/algorithms/zstandard/xxhash.rb +159 -0
- data/lib/omnizip/algorithms/zstandard.rb +210 -0
- data/lib/omnizip/algorithms.rb +35 -0
- data/lib/omnizip/archive/builder.rb +48 -0
- data/lib/omnizip/archive/reader_session.rb +67 -0
- data/lib/omnizip/archive.rb +86 -0
- data/lib/omnizip/archive_handler.rb +82 -0
- data/lib/omnizip/archive_handlers/cpio_handler.rb +47 -0
- data/lib/omnizip/archive_handlers/iso_handler.rb +54 -0
- data/lib/omnizip/archive_handlers/ole_handler.rb +37 -0
- data/lib/omnizip/archive_handlers/rar_handler.rb +96 -0
- data/lib/omnizip/archive_handlers/rpm_handler.rb +45 -0
- data/lib/omnizip/archive_handlers/seven_zip_handler.rb +89 -0
- data/lib/omnizip/archive_handlers/tar_handler.rb +75 -0
- data/lib/omnizip/archive_handlers/xar_handler.rb +49 -0
- data/lib/omnizip/archive_handlers/zip_handler.rb +115 -0
- data/lib/omnizip/archive_handlers.rb +18 -0
- data/lib/omnizip/backends.rb +160 -0
- data/lib/omnizip/buffer/memory_archive.rb +246 -0
- data/lib/omnizip/buffer/memory_extractor.rb +234 -0
- data/lib/omnizip/buffer/seven_zip_bridge.rb +171 -0
- data/lib/omnizip/buffer.rb +187 -0
- data/lib/omnizip/checksum_registry.rb +41 -0
- data/lib/omnizip/checksums/crc32.rb +101 -0
- data/lib/omnizip/checksums/crc64.rb +102 -0
- data/lib/omnizip/checksums/crc_base.rb +158 -0
- data/lib/omnizip/checksums/registration.rb +16 -0
- data/lib/omnizip/checksums/verifier.rb +130 -0
- data/lib/omnizip/checksums.rb +11 -0
- data/lib/omnizip/chunked/memory_manager.rb +194 -0
- data/lib/omnizip/chunked/reader.rb +78 -0
- data/lib/omnizip/chunked/writer.rb +123 -0
- data/lib/omnizip/chunked.rb +123 -0
- data/lib/omnizip/cli/output_formatter.rb +112 -0
- data/lib/omnizip/cli.rb +604 -0
- data/lib/omnizip/commands/.keep +0 -0
- data/lib/omnizip/commands/archive_create_command.rb +245 -0
- data/lib/omnizip/commands/archive_extract_command.rb +231 -0
- data/lib/omnizip/commands/archive_list_command.rb +204 -0
- data/lib/omnizip/commands/archive_repair_command.rb +129 -0
- data/lib/omnizip/commands/archive_verify_command.rb +115 -0
- data/lib/omnizip/commands/compress_command.rb +115 -0
- data/lib/omnizip/commands/decompress_command.rb +149 -0
- data/lib/omnizip/commands/list_command.rb +51 -0
- data/lib/omnizip/commands/metadata_command.rb +215 -0
- data/lib/omnizip/commands/parity_create_command.rb +114 -0
- data/lib/omnizip/commands/parity_repair_command.rb +120 -0
- data/lib/omnizip/commands/parity_verify_command.rb +122 -0
- data/lib/omnizip/commands/profile_list_command.rb +54 -0
- data/lib/omnizip/commands/profile_show_command.rb +44 -0
- data/lib/omnizip/commands.rb +21 -0
- data/lib/omnizip/convenience.rb +389 -0
- data/lib/omnizip/converter/conversion_registry.rb +50 -0
- data/lib/omnizip/converter/conversion_strategy.rb +108 -0
- data/lib/omnizip/converter/extract_repack_strategy.rb +51 -0
- data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +43 -0
- data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +54 -0
- data/lib/omnizip/converter.rb +124 -0
- data/lib/omnizip/crypto/aes256/cipher.rb +104 -0
- data/lib/omnizip/crypto/aes256/constants.rb +28 -0
- data/lib/omnizip/crypto/aes256/key_derivation.rb +100 -0
- data/lib/omnizip/crypto/aes256.rb +102 -0
- data/lib/omnizip/crypto.rb +11 -0
- data/lib/omnizip/entry.rb +44 -0
- data/lib/omnizip/error.rb +110 -0
- data/lib/omnizip/eta/exponential_smoothing_estimator.rb +95 -0
- data/lib/omnizip/eta/moving_average_estimator.rb +96 -0
- data/lib/omnizip/eta/rate_calculator.rb +104 -0
- data/lib/omnizip/eta/sample_history.rb +143 -0
- data/lib/omnizip/eta/time_estimator.rb +106 -0
- data/lib/omnizip/eta.rb +68 -0
- data/lib/omnizip/extraction/filter_chain.rb +179 -0
- data/lib/omnizip/extraction/glob_pattern.rb +140 -0
- data/lib/omnizip/extraction/pattern_matcher.rb +66 -0
- data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
- data/lib/omnizip/extraction/regex_pattern.rb +50 -0
- data/lib/omnizip/extraction/selective_extractor.rb +247 -0
- data/lib/omnizip/extraction.rb +115 -0
- data/lib/omnizip/file_type/mime_classifier.rb +144 -0
- data/lib/omnizip/file_type.rb +117 -0
- data/lib/omnizip/filter.rb +141 -0
- data/lib/omnizip/filter_pipeline.rb +108 -0
- data/lib/omnizip/filter_registry.rb +113 -0
- data/lib/omnizip/filters/bcj.rb +277 -0
- data/lib/omnizip/filters/bcj2/constants.rb +53 -0
- data/lib/omnizip/filters/bcj2/decoder.rb +263 -0
- data/lib/omnizip/filters/bcj2/encoder.rb +58 -0
- data/lib/omnizip/filters/bcj2/stream_data.rb +91 -0
- data/lib/omnizip/filters/bcj2.rb +93 -0
- data/lib/omnizip/filters/bcj_arm.rb +174 -0
- data/lib/omnizip/filters/bcj_arm64.rb +242 -0
- data/lib/omnizip/filters/bcj_ia64.rb +194 -0
- data/lib/omnizip/filters/bcj_ppc.rb +188 -0
- data/lib/omnizip/filters/bcj_sparc.rb +174 -0
- data/lib/omnizip/filters/bcj_x86.rb +191 -0
- data/lib/omnizip/filters/delta.rb +195 -0
- data/lib/omnizip/filters/xz_delta.rb +258 -0
- data/lib/omnizip/filters.rb +20 -0
- data/lib/omnizip/format_detector.rb +166 -0
- data/lib/omnizip/formats/.keep +0 -0
- data/lib/omnizip/formats/bzip2_file.rb +159 -0
- data/lib/omnizip/formats/cpio/bounded_io.rb +66 -0
- data/lib/omnizip/formats/cpio/constants.rb +55 -0
- data/lib/omnizip/formats/cpio/entry.rb +389 -0
- data/lib/omnizip/formats/cpio/reader.rb +194 -0
- data/lib/omnizip/formats/cpio/writer.rb +232 -0
- data/lib/omnizip/formats/cpio.rb +132 -0
- data/lib/omnizip/formats/format_spec_loader.rb +228 -0
- data/lib/omnizip/formats/gzip.rb +236 -0
- data/lib/omnizip/formats/iso/directory_builder.rb +321 -0
- data/lib/omnizip/formats/iso/directory_record.rb +162 -0
- data/lib/omnizip/formats/iso/joliet.rb +204 -0
- data/lib/omnizip/formats/iso/path_table.rb +125 -0
- data/lib/omnizip/formats/iso/reader.rb +194 -0
- data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
- data/lib/omnizip/formats/iso/volume_builder.rb +319 -0
- data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
- data/lib/omnizip/formats/iso/writer.rb +543 -0
- data/lib/omnizip/formats/iso.rb +133 -0
- data/lib/omnizip/formats/lzip.rb +161 -0
- data/lib/omnizip/formats/lzma_alone.rb +149 -0
- data/lib/omnizip/formats/msi/cab_extractor.rb +181 -0
- data/lib/omnizip/formats/msi/constants.rb +157 -0
- data/lib/omnizip/formats/msi/directory_resolver.rb +188 -0
- data/lib/omnizip/formats/msi/entry.rb +134 -0
- data/lib/omnizip/formats/msi/reader.rb +301 -0
- data/lib/omnizip/formats/msi/string_pool.rb +246 -0
- data/lib/omnizip/formats/msi/table_parser.rb +244 -0
- data/lib/omnizip/formats/msi.rb +73 -0
- data/lib/omnizip/formats/ole/allocation_table.rb +263 -0
- data/lib/omnizip/formats/ole/constants.rb +61 -0
- data/lib/omnizip/formats/ole/dirent.rb +439 -0
- data/lib/omnizip/formats/ole/header.rb +199 -0
- data/lib/omnizip/formats/ole/ranges_io.rb +347 -0
- data/lib/omnizip/formats/ole/storage.rb +482 -0
- data/lib/omnizip/formats/ole/types/variant.rb +338 -0
- data/lib/omnizip/formats/ole.rb +143 -0
- data/lib/omnizip/formats/rar/archive_repairer.rb +240 -0
- data/lib/omnizip/formats/rar/archive_verifier.rb +192 -0
- data/lib/omnizip/formats/rar/block_parser.rb +282 -0
- data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
- data/lib/omnizip/formats/rar/compression/dispatcher.rb +210 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +212 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +154 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman.rb +25 -0
- data/lib/omnizip/formats/rar/compression/ppmd/context.rb +103 -0
- data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +238 -0
- data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +250 -0
- data/lib/omnizip/formats/rar/compression/ppmd.rb +16 -0
- data/lib/omnizip/formats/rar/compression.rb +17 -0
- data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
- data/lib/omnizip/formats/rar/constants.rb +88 -0
- data/lib/omnizip/formats/rar/decompressor.rb +316 -0
- data/lib/omnizip/formats/rar/external_writer.rb +311 -0
- data/lib/omnizip/formats/rar/header.rb +209 -0
- data/lib/omnizip/formats/rar/license_validator.rb +111 -0
- data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
- data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
- data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
- data/lib/omnizip/formats/rar/models.rb +14 -0
- data/lib/omnizip/formats/rar/parity_handler.rb +299 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +200 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +584 -0
- data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
- data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
- data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +96 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +162 -0
- data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
- data/lib/omnizip/formats/rar/rar5/header.rb +208 -0
- data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +260 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +176 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +108 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +139 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
- data/lib/omnizip/formats/rar/rar5/vint.rb +53 -0
- data/lib/omnizip/formats/rar/rar5/writer.rb +540 -0
- data/lib/omnizip/formats/rar/rar_format_base.rb +239 -0
- data/lib/omnizip/formats/rar/reader.rb +377 -0
- data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
- data/lib/omnizip/formats/rar/volume_manager.rb +166 -0
- data/lib/omnizip/formats/rar/writer.rb +437 -0
- data/lib/omnizip/formats/rar.rb +193 -0
- data/lib/omnizip/formats/rar3/compressor.rb +71 -0
- data/lib/omnizip/formats/rar3/decompressor.rb +64 -0
- data/lib/omnizip/formats/rar3/reader.rb +107 -0
- data/lib/omnizip/formats/rar3/writer.rb +220 -0
- data/lib/omnizip/formats/rar3.rb +15 -0
- data/lib/omnizip/formats/rar5/compressor.rb +71 -0
- data/lib/omnizip/formats/rar5/decompressor.rb +64 -0
- data/lib/omnizip/formats/rar5/reader.rb +130 -0
- data/lib/omnizip/formats/rar5/writer.rb +65 -0
- data/lib/omnizip/formats/rar5.rb +15 -0
- data/lib/omnizip/formats/rpm/constants.rb +58 -0
- data/lib/omnizip/formats/rpm/entry.rb +106 -0
- data/lib/omnizip/formats/rpm/header.rb +106 -0
- data/lib/omnizip/formats/rpm/lead.rb +132 -0
- data/lib/omnizip/formats/rpm/tag.rb +228 -0
- data/lib/omnizip/formats/rpm/writer.rb +652 -0
- data/lib/omnizip/formats/rpm.rb +458 -0
- data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +274 -0
- data/lib/omnizip/formats/seven_zip/coder_chain.rb +169 -0
- data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
- data/lib/omnizip/formats/seven_zip/encoded_header.rb +110 -0
- data/lib/omnizip/formats/seven_zip/encrypted_header.rb +139 -0
- data/lib/omnizip/formats/seven_zip/file_collector.rb +143 -0
- data/lib/omnizip/formats/seven_zip/header.rb +102 -0
- data/lib/omnizip/formats/seven_zip/header_encryptor.rb +132 -0
- data/lib/omnizip/formats/seven_zip/header_writer.rb +425 -0
- data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
- data/lib/omnizip/formats/seven_zip/models/file_entry.rb +65 -0
- data/lib/omnizip/formats/seven_zip/models/folder.rb +67 -0
- data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
- data/lib/omnizip/formats/seven_zip/models.rb +20 -0
- data/lib/omnizip/formats/seven_zip/parser.rb +671 -0
- data/lib/omnizip/formats/seven_zip/reader.rb +626 -0
- data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +611 -0
- data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +308 -0
- data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
- data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +166 -0
- data/lib/omnizip/formats/seven_zip/writer.rb +801 -0
- data/lib/omnizip/formats/seven_zip.rb +179 -0
- data/lib/omnizip/formats/tar/constants.rb +73 -0
- data/lib/omnizip/formats/tar/entry.rb +98 -0
- data/lib/omnizip/formats/tar/header.rb +206 -0
- data/lib/omnizip/formats/tar/reader.rb +119 -0
- data/lib/omnizip/formats/tar/writer.rb +212 -0
- data/lib/omnizip/formats/tar.rb +74 -0
- data/lib/omnizip/formats/xar/constants.rb +119 -0
- data/lib/omnizip/formats/xar/entry.rb +268 -0
- data/lib/omnizip/formats/xar/header.rb +223 -0
- data/lib/omnizip/formats/xar/reader.rb +400 -0
- data/lib/omnizip/formats/xar/toc.rb +570 -0
- data/lib/omnizip/formats/xar/writer.rb +461 -0
- data/lib/omnizip/formats/xar.rb +145 -0
- data/lib/omnizip/formats/xz/reader.rb +121 -0
- data/lib/omnizip/formats/xz/writer.rb +416 -0
- data/lib/omnizip/formats/xz.rb +210 -0
- data/lib/omnizip/formats/xz_const.rb +49 -0
- data/lib/omnizip/formats/xz_impl/block_decoder.rb +761 -0
- data/lib/omnizip/formats/xz_impl/block_encoder.rb +304 -0
- data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
- data/lib/omnizip/formats/xz_impl/block_header_parser.rb +182 -0
- data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
- data/lib/omnizip/formats/xz_impl/index_encoder.rb +120 -0
- data/lib/omnizip/formats/xz_impl/stream_decoder.rb +470 -0
- data/lib/omnizip/formats/xz_impl/stream_encoder.rb +95 -0
- data/lib/omnizip/formats/xz_impl/stream_footer.rb +79 -0
- data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +115 -0
- data/lib/omnizip/formats/xz_impl/stream_header.rb +53 -0
- data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +106 -0
- data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
- data/lib/omnizip/formats/xz_impl.rb +52 -0
- data/lib/omnizip/formats/zip/central_directory_header.rb +223 -0
- data/lib/omnizip/formats/zip/constants.rb +69 -0
- data/lib/omnizip/formats/zip/end_of_central_directory.rb +132 -0
- data/lib/omnizip/formats/zip/local_file_header.rb +136 -0
- data/lib/omnizip/formats/zip/reader.rb +376 -0
- data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
- data/lib/omnizip/formats/zip/writer.rb +489 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +102 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +64 -0
- data/lib/omnizip/formats/zip/zip64_extra_field.rb +112 -0
- data/lib/omnizip/formats/zip.rb +50 -0
- data/lib/omnizip/formats.rb +29 -0
- data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
- data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
- data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
- data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
- data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
- data/lib/omnizip/implementations/base.rb +19 -0
- data/lib/omnizip/implementations/rust/archive.rb +93 -0
- data/lib/omnizip/implementations/rust/library.rb +221 -0
- data/lib/omnizip/implementations/rust.rb +26 -0
- data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +428 -0
- data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +456 -0
- data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +285 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +197 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +194 -0
- data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +139 -0
- data/lib/omnizip/implementations/seven_zip/lzma.rb +21 -0
- data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +56 -0
- data/lib/omnizip/implementations/seven_zip/lzma2.rb +12 -0
- data/lib/omnizip/implementations/seven_zip.rb +11 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +547 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +748 -0
- data/lib/omnizip/implementations/xz_utils/lzma2.rb +13 -0
- data/lib/omnizip/implementations/xz_utils.rb +10 -0
- data/lib/omnizip/implementations.rb +25 -0
- data/lib/omnizip/io/buffered_input.rb +147 -0
- data/lib/omnizip/io/buffered_output.rb +106 -0
- data/lib/omnizip/io/source.rb +143 -0
- data/lib/omnizip/io/stream_manager.rb +117 -0
- data/lib/omnizip/io.rb +15 -0
- data/lib/omnizip/link_handler/hard_link.rb +79 -0
- data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
- data/lib/omnizip/link_handler.rb +129 -0
- data/lib/omnizip/metadata/archive_metadata.rb +114 -0
- data/lib/omnizip/metadata/entry_metadata.rb +153 -0
- data/lib/omnizip/metadata/metadata_editor.rb +169 -0
- data/lib/omnizip/metadata/metadata_registry.rb +71 -0
- data/lib/omnizip/metadata/metadata_validator.rb +101 -0
- data/lib/omnizip/metadata.rb +58 -0
- data/lib/omnizip/models/.keep +0 -0
- data/lib/omnizip/models/algorithm_metadata.rb +41 -0
- data/lib/omnizip/models/attribute_apply.rb +40 -0
- data/lib/omnizip/models/compression_options.rb +53 -0
- data/lib/omnizip/models/conversion_options.rb +79 -0
- data/lib/omnizip/models/conversion_result.rb +141 -0
- data/lib/omnizip/models/eta_result.rb +45 -0
- data/lib/omnizip/models/extraction_rule.rb +115 -0
- data/lib/omnizip/models/filter_chain.rb +142 -0
- data/lib/omnizip/models/filter_config.rb +148 -0
- data/lib/omnizip/models/match_result.rb +141 -0
- data/lib/omnizip/models/optimization_suggestion.rb +95 -0
- data/lib/omnizip/models/parallel_options.rb +116 -0
- data/lib/omnizip/models/performance_result.rb +85 -0
- data/lib/omnizip/models/profile_report.rb +116 -0
- data/lib/omnizip/models/progress_options.rb +39 -0
- data/lib/omnizip/models/split_options.rb +116 -0
- data/lib/omnizip/optimization_registry.rb +45 -0
- data/lib/omnizip/parallel/engine.rb +52 -0
- data/lib/omnizip/parallel/job_queue.rb +209 -0
- data/lib/omnizip/parallel/job_scheduler.rb +225 -0
- data/lib/omnizip/parallel/parallel_compressor.rb +326 -0
- data/lib/omnizip/parallel/parallel_extractor.rb +238 -0
- data/lib/omnizip/parallel/thread_pool.rb +60 -0
- data/lib/omnizip/parallel/worker_pool.rb +227 -0
- data/lib/omnizip/parallel.rb +156 -0
- data/lib/omnizip/parity/chunked_block_processor.rb +194 -0
- data/lib/omnizip/parity/galois16.rb +145 -0
- data/lib/omnizip/parity/models/creator_packet.rb +71 -0
- data/lib/omnizip/parity/models/file_description_packet.rb +131 -0
- data/lib/omnizip/parity/models/ifsc_packet.rb +111 -0
- data/lib/omnizip/parity/models/main_packet.rb +126 -0
- data/lib/omnizip/parity/models/packet.rb +156 -0
- data/lib/omnizip/parity/models/packet_registry.rb +102 -0
- data/lib/omnizip/parity/models/recovery_slice_packet.rb +76 -0
- data/lib/omnizip/parity/models.rb +27 -0
- data/lib/omnizip/parity/par2_creator.rb +496 -0
- data/lib/omnizip/parity/par2_repairer.rb +409 -0
- data/lib/omnizip/parity/par2_verifier.rb +373 -0
- data/lib/omnizip/parity/par2cmdline_algorithm.rb +108 -0
- data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
- data/lib/omnizip/parity/reed_solomon_decoder.rb +263 -0
- data/lib/omnizip/parity/reed_solomon_encoder.rb +108 -0
- data/lib/omnizip/parity/reed_solomon_matrix.rb +339 -0
- data/lib/omnizip/parity.rb +207 -0
- data/lib/omnizip/password/encryption_registry.rb +26 -0
- data/lib/omnizip/password/encryption_strategy.rb +96 -0
- data/lib/omnizip/password/password_validator.rb +129 -0
- data/lib/omnizip/password/winzip_aes_strategy.rb +190 -0
- data/lib/omnizip/password/zip_crypto_strategy.rb +135 -0
- data/lib/omnizip/password.rb +88 -0
- data/lib/omnizip/pipe/stream_compressor.rb +124 -0
- data/lib/omnizip/pipe/stream_decompressor.rb +173 -0
- data/lib/omnizip/pipe.rb +120 -0
- data/lib/omnizip/platform/ntfs_streams.rb +200 -0
- data/lib/omnizip/platform.rb +189 -0
- data/lib/omnizip/profile/archive_profile.rb +36 -0
- data/lib/omnizip/profile/balanced_profile.rb +31 -0
- data/lib/omnizip/profile/binary_profile.rb +33 -0
- data/lib/omnizip/profile/compression_profile.rb +157 -0
- data/lib/omnizip/profile/custom_profile.rb +155 -0
- data/lib/omnizip/profile/fast_profile.rb +31 -0
- data/lib/omnizip/profile/maximum_profile.rb +31 -0
- data/lib/omnizip/profile/profile_detector.rb +108 -0
- data/lib/omnizip/profile/profile_registry.rb +160 -0
- data/lib/omnizip/profile/text_profile.rb +33 -0
- data/lib/omnizip/profile.rb +261 -0
- data/lib/omnizip/profiler/memory_profiler.rb +66 -0
- data/lib/omnizip/profiler/method_profiler.rb +49 -0
- data/lib/omnizip/profiler/report_generator.rb +158 -0
- data/lib/omnizip/profiler.rb +192 -0
- data/lib/omnizip/progress/callback_reporter.rb +34 -0
- data/lib/omnizip/progress/console_reporter.rb +59 -0
- data/lib/omnizip/progress/log_reporter.rb +89 -0
- data/lib/omnizip/progress/operation_progress.rb +118 -0
- data/lib/omnizip/progress/progress_bar.rb +156 -0
- data/lib/omnizip/progress/progress_reporter.rb +40 -0
- data/lib/omnizip/progress/progress_tracker.rb +215 -0
- data/lib/omnizip/progress/silent_reporter.rb +22 -0
- data/lib/omnizip/progress.rb +131 -0
- data/lib/omnizip/registry.rb +111 -0
- data/lib/omnizip/rubyzip_compat.rb +61 -0
- data/lib/omnizip/temp/safe_extract.rb +124 -0
- data/lib/omnizip/temp/temp_file.rb +123 -0
- data/lib/omnizip/temp/temp_file_pool.rb +109 -0
- data/lib/omnizip/temp.rb +184 -0
- data/lib/omnizip/version.rb +5 -0
- data/lib/omnizip/zip/entry.rb +160 -0
- data/lib/omnizip/zip/file.rb +485 -0
- data/lib/omnizip/zip/input_stream.rb +270 -0
- data/lib/omnizip/zip/output_stream.rb +320 -0
- data/lib/omnizip/zip.rb +23 -0
- data/lib/omnizip.rb +157 -0
- data/lib/tasks/msi_test_files.rake +66 -0
- data/lib/tasks/platform_gems.rake +147 -0
- data/lib/tasks/rust_backend.rake +48 -0
- data/readme-docs/advanced-features.adoc +514 -0
- data/readme-docs/api-usage.adoc +445 -0
- data/readme-docs/architecture.adoc +450 -0
- data/readme-docs/archive-formats.adoc +479 -0
- data/readme-docs/cli-usage.adoc +222 -0
- data/readme-docs/compression-algorithms.adoc +446 -0
- data/readme-docs/compression-profiles.adoc +247 -0
- data/readme-docs/encryption-checksums.adoc +328 -0
- data/readme-docs/format-converter.adoc +316 -0
- data/readme-docs/installation.adoc +228 -0
- data/readme-docs/par2-archives.adoc +608 -0
- data/readme-docs/performance-profiler.adoc +389 -0
- data/readme-docs/preprocessing-filters.adoc +280 -0
- data/vendor/libomnizip_ffi.so +0 -0
- data/xz-file-format-1.2.1.txt +1174 -0
- metadata +768 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Algorithms
|
|
5
|
+
class LZMA < Algorithm
|
|
6
|
+
# Optimal encoder - chooses best encoding
|
|
7
|
+
# Ported from lzma_encoder_optimum_fast.c
|
|
8
|
+
class OptimalEncoder
|
|
9
|
+
attr_reader :mode
|
|
10
|
+
|
|
11
|
+
def initialize(mode: :fast)
|
|
12
|
+
@mode = mode
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Find optimal encoding for current position
|
|
16
|
+
def find_optimal(position, match_finder, state, reps, models)
|
|
17
|
+
case @mode
|
|
18
|
+
when :fast
|
|
19
|
+
optimum_fast(position, match_finder, state, reps, models)
|
|
20
|
+
else
|
|
21
|
+
raise ArgumentError, "Unknown mode: #{@mode}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
# Fast mode: repeated-match scan plus first normal match. The
|
|
28
|
+
# unused state/models parameters keep the signature shared with
|
|
29
|
+
# a future normal (optimal-parse) mode.
|
|
30
|
+
def optimum_fast(position, match_finder, _state, reps, _models)
|
|
31
|
+
buf = match_finder.buffer # CRITICAL: Use match_finder.buffer, NOT dictionary.buffer!
|
|
32
|
+
buf_pos = position
|
|
33
|
+
buf_avail = [buf.bytesize - buf_pos, MATCH_LEN_MAX].min
|
|
34
|
+
|
|
35
|
+
# Not enough input for a match
|
|
36
|
+
return [UINT32_MAX, 1] if buf_avail < 2
|
|
37
|
+
|
|
38
|
+
# CRITICAL: Check repeated matches FIRST (before normal matches)
|
|
39
|
+
# This matches XZ Utils lzma_lzma_optimum_fast behavior
|
|
40
|
+
rep_len = 0
|
|
41
|
+
rep_index = 0
|
|
42
|
+
|
|
43
|
+
# For level 9, nice_len = MATCH_LEN_MAX = 273
|
|
44
|
+
nice_len = MATCH_LEN_MAX
|
|
45
|
+
|
|
46
|
+
# Look for repeated matches; scan the previous four match distances
|
|
47
|
+
reps.each_with_index do |rep_dist, i|
|
|
48
|
+
# Pointer to the beginning of the match candidate
|
|
49
|
+
# In XZ: buf_back = buf - coder->reps[i] - 1
|
|
50
|
+
# In Ruby: buf_back_index = buf_pos - rep_dist - 1
|
|
51
|
+
buf_back_index = buf_pos - rep_dist - 1
|
|
52
|
+
|
|
53
|
+
# Skip if out of bounds
|
|
54
|
+
next if buf_back_index.negative? || buf_back_index >= buf.bytesize
|
|
55
|
+
|
|
56
|
+
# If the first two bytes (2 == MATCH_LEN_MIN) do not match,
|
|
57
|
+
# this rep is not useful.
|
|
58
|
+
next if buf.getbyte(buf_pos) != buf.getbyte(buf_back_index) ||
|
|
59
|
+
buf.getbyte(buf_pos + 1) != buf.getbyte(buf_back_index + 1)
|
|
60
|
+
|
|
61
|
+
# The first two bytes matched. Calculate the length of the match.
|
|
62
|
+
# Use 64-bit integer comparison for speed (no string allocation)
|
|
63
|
+
max_match_len = [
|
|
64
|
+
buf.bytesize - buf_pos,
|
|
65
|
+
buf.bytesize - buf_back_index,
|
|
66
|
+
MATCH_LEN_MAX,
|
|
67
|
+
buf_avail,
|
|
68
|
+
].min
|
|
69
|
+
|
|
70
|
+
len = 2
|
|
71
|
+
# Compare 8 bytes at a time using 64-bit integers read
|
|
72
|
+
# without intermediate strings (byteslice + unpack1
|
|
73
|
+
# allocates two Strings per step and dominated GC time).
|
|
74
|
+
while len + 8 <= max_match_len
|
|
75
|
+
v1 = read8(buf, buf_pos + len)
|
|
76
|
+
v2 = read8(buf, buf_back_index + len)
|
|
77
|
+
break if v1 != v2
|
|
78
|
+
|
|
79
|
+
len += 8
|
|
80
|
+
end
|
|
81
|
+
# Finalize with byte-by-byte for remaining bytes
|
|
82
|
+
while len < max_match_len &&
|
|
83
|
+
buf.getbyte(buf_pos + len) == buf.getbyte(buf_back_index + len)
|
|
84
|
+
len += 1
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# If we have found a repeated match that is at least
|
|
88
|
+
# nice_len long, return it immediately.
|
|
89
|
+
if len >= nice_len
|
|
90
|
+
# Return rep index (0-3 for rep0-rep3)
|
|
91
|
+
return [i, len]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
if len > rep_len
|
|
95
|
+
rep_index = i
|
|
96
|
+
rep_len = len
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Find normal matches from match finder
|
|
101
|
+
matches = match_finder.find_matches(position)
|
|
102
|
+
|
|
103
|
+
# We didn't find a long enough repeated match.
|
|
104
|
+
# Encode it as a normal match if the match length is at least nice_len
|
|
105
|
+
# AND the match distance stays within the data decoded so far.
|
|
106
|
+
# A match may reference anything before `position`: bytes already
|
|
107
|
+
# committed to the dictionary *and* bytes decoded earlier within
|
|
108
|
+
# the chunk currently being encoded.
|
|
109
|
+
best_normal = nil
|
|
110
|
+
matches.each do |m|
|
|
111
|
+
next if best_normal &&
|
|
112
|
+
(m.length < best_normal.length ||
|
|
113
|
+
(m.length == best_normal.length &&
|
|
114
|
+
m.distance <= best_normal.distance))
|
|
115
|
+
|
|
116
|
+
best_normal = m
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
if best_normal && best_normal.length >= nice_len &&
|
|
120
|
+
best_normal.distance <= position
|
|
121
|
+
# Use normal match
|
|
122
|
+
return [best_normal.distance + REPS, best_normal.length]
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Compare best rep match vs best normal match
|
|
126
|
+
# Prefer longer match, for equal length prefer rep match (XZ behavior)
|
|
127
|
+
if rep_len >= 2 && rep_len >= (best_normal&.length || 0)
|
|
128
|
+
# Use repeated match
|
|
129
|
+
[rep_index, rep_len]
|
|
130
|
+
elsif best_normal && best_normal.distance <= position
|
|
131
|
+
# Use normal match (any length beats encoding literals)
|
|
132
|
+
[best_normal.distance + REPS, best_normal.length]
|
|
133
|
+
else
|
|
134
|
+
# Use literal - return UINT32_MAX to indicate literal (not 0!)
|
|
135
|
+
[UINT32_MAX, 1]
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Allocation-free little-endian 8-byte read.
|
|
140
|
+
def read8(buf, pos)
|
|
141
|
+
buf.getbyte(pos) |
|
|
142
|
+
(buf.getbyte(pos + 1) << 8) |
|
|
143
|
+
(buf.getbyte(pos + 2) << 16) |
|
|
144
|
+
(buf.getbyte(pos + 3) << 24) |
|
|
145
|
+
(buf.getbyte(pos + 4) << 32) |
|
|
146
|
+
(buf.getbyte(pos + 5) << 40) |
|
|
147
|
+
(buf.getbyte(pos + 6) << 48) |
|
|
148
|
+
(buf.getbyte(pos + 7) << 56)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Constants
|
|
152
|
+
REPS = 4
|
|
153
|
+
MATCH_LEN_MAX = 273 # From lzma.h
|
|
154
|
+
MATCH_LEN_MIN = 2
|
|
155
|
+
UINT32_MAX = 0xFFFFFFFF
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Algorithms
|
|
5
|
+
class LZMA < Algorithm
|
|
6
|
+
# Container for all LZMA probability models
|
|
7
|
+
# Ported from lzma_encoder_private.h
|
|
8
|
+
class ProbabilityModels
|
|
9
|
+
# Constants
|
|
10
|
+
STATES = 12
|
|
11
|
+
POS_STATES_MAX = 16
|
|
12
|
+
LEN_LOW_SYMBOLS = 8
|
|
13
|
+
LEN_MID_SYMBOLS = 8
|
|
14
|
+
LEN_HIGH_SYMBOLS = 16
|
|
15
|
+
LEN_SYMBOLS = 272
|
|
16
|
+
MATCH_LEN_MIN = 2
|
|
17
|
+
MATCH_LEN_MAX = 273
|
|
18
|
+
DIST_STATES = 4
|
|
19
|
+
DIST_SLOTS = 64
|
|
20
|
+
DIST_MODEL_START = 4
|
|
21
|
+
DIST_MODEL_END = 14
|
|
22
|
+
FULL_DISTANCES = 128
|
|
23
|
+
ALIGN_SIZE = 16
|
|
24
|
+
|
|
25
|
+
attr_accessor :literal, :is_match, :is_rep,
|
|
26
|
+
:is_rep0, :is_rep1, :is_rep2, :is_rep0_long,
|
|
27
|
+
:dist_slot, :dist_special, :dist_align,
|
|
28
|
+
:match_len_encoder, :rep_len_encoder
|
|
29
|
+
|
|
30
|
+
def initialize(lc: 3, lp: 0, pb: 2)
|
|
31
|
+
@lc = lc
|
|
32
|
+
@lp = lp
|
|
33
|
+
@pb = pb
|
|
34
|
+
|
|
35
|
+
@literal = init_literal_models
|
|
36
|
+
@is_match = init_is_match_models
|
|
37
|
+
@is_rep = init_array(STATES, BitModel)
|
|
38
|
+
@is_rep0 = init_array(STATES, BitModel)
|
|
39
|
+
@is_rep1 = init_array(STATES, BitModel)
|
|
40
|
+
@is_rep2 = init_array(STATES, BitModel)
|
|
41
|
+
@is_rep0_long = init_is_rep0_long_models
|
|
42
|
+
@dist_slot = init_dist_slot_models
|
|
43
|
+
@dist_special = init_array(FULL_DISTANCES - DIST_MODEL_END, BitModel)
|
|
44
|
+
@dist_align = init_array(ALIGN_SIZE, BitModel)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def init_literal_models
|
|
50
|
+
num_contexts = 1 << (@lc + @lp)
|
|
51
|
+
Array.new(num_contexts * 0x300) { BitModel.new }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def init_is_match_models
|
|
55
|
+
Array.new(STATES * (1 << @pb)) { BitModel.new }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def init_is_rep0_long_models
|
|
59
|
+
Array.new(STATES * (1 << @pb)) { BitModel.new }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def init_dist_slot_models
|
|
63
|
+
Array.new(DIST_STATES * DIST_SLOTS) { BitModel.new }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def init_array(size, _model_class)
|
|
67
|
+
Array.new(size) { BitModel.new }
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
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 Algorithms
|
|
25
|
+
class LZMA < Algorithm
|
|
26
|
+
# Base class for range encoding and decoding
|
|
27
|
+
#
|
|
28
|
+
# This class provides the core arithmetic coding functionality
|
|
29
|
+
# used by both the encoder and decoder. Range coding is a form
|
|
30
|
+
# of arithmetic coding that uses integer arithmetic to represent
|
|
31
|
+
# probability ranges.
|
|
32
|
+
#
|
|
33
|
+
# The algorithm maintains a range [low, high) and subdivides it
|
|
34
|
+
# based on symbol probabilities. The range is periodically
|
|
35
|
+
# normalized to prevent arithmetic overflow/underflow.
|
|
36
|
+
class RangeCoder
|
|
37
|
+
include Constants
|
|
38
|
+
|
|
39
|
+
attr_reader :range, :low
|
|
40
|
+
|
|
41
|
+
# Initialize the range coder
|
|
42
|
+
#
|
|
43
|
+
# @param stream [IO] The input or output stream
|
|
44
|
+
def initialize(stream)
|
|
45
|
+
@stream = stream
|
|
46
|
+
@range = 0xFFFFFFFF
|
|
47
|
+
@low = 0
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
protected
|
|
51
|
+
|
|
52
|
+
# Normalize the range when it becomes too small
|
|
53
|
+
#
|
|
54
|
+
# This is an abstract method to be implemented by subclasses.
|
|
55
|
+
# The encoder and decoder have different normalization logic.
|
|
56
|
+
#
|
|
57
|
+
# @return [void]
|
|
58
|
+
def normalize
|
|
59
|
+
raise NotImplementedError,
|
|
60
|
+
"#{self.class} must implement #normalize"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Create an array of bit models for probability management
|
|
64
|
+
#
|
|
65
|
+
# @param size [Integer] Number of bit models to create
|
|
66
|
+
# @return [Array<BitModel>] Array of initialized bit models
|
|
67
|
+
def create_bit_models(size)
|
|
68
|
+
Array.new(size) { BitModel.new }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Get a bit model from an array based on index
|
|
72
|
+
#
|
|
73
|
+
# @param models [Array<BitModel>] Array of bit models
|
|
74
|
+
# @param index [Integer] Index to retrieve
|
|
75
|
+
# @return [BitModel] The bit model at the specified index
|
|
76
|
+
def get_bit_model(models, index)
|
|
77
|
+
models[index] ||= BitModel.new
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,274 @@
|
|
|
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 Algorithms
|
|
25
|
+
class LZMA < Algorithm
|
|
26
|
+
# Range decoder for LZMA decompression
|
|
27
|
+
#
|
|
28
|
+
# This class implements the decoding side of arithmetic coding
|
|
29
|
+
# using integer range arithmetic. It decodes bits from the
|
|
30
|
+
# compressed byte stream based on their probability models.
|
|
31
|
+
#
|
|
32
|
+
# The decoder mirrors the encoder's range subdivisions to
|
|
33
|
+
# extract the original bit values. It maintains a code value
|
|
34
|
+
# that represents the current position within the range.
|
|
35
|
+
class RangeDecoder < RangeCoder
|
|
36
|
+
attr_reader :code, :init_bytes_remaining, :range, :stream
|
|
37
|
+
|
|
38
|
+
# Initialize the range decoder
|
|
39
|
+
#
|
|
40
|
+
# @param input_stream [IO] The input stream of encoded bytes
|
|
41
|
+
def initialize(input_stream)
|
|
42
|
+
super
|
|
43
|
+
@code = 0
|
|
44
|
+
@initialization_complete = false
|
|
45
|
+
@init_bytes_remaining = 5
|
|
46
|
+
init_decoder
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Update the input stream (for LZMA2 multi-chunk streams)
|
|
50
|
+
#
|
|
51
|
+
# @param new_stream [IO] New input stream
|
|
52
|
+
# @return [void]
|
|
53
|
+
def update_stream(new_stream)
|
|
54
|
+
@stream = new_stream
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Decode a single bit using a probability model
|
|
58
|
+
#
|
|
59
|
+
# This is the hottest method (~5 billion calls for a 600MB file).
|
|
60
|
+
# normalize() and model.update() are inlined to eliminate method dispatch.
|
|
61
|
+
#
|
|
62
|
+
# @param model [BitModel] The probability model for this bit
|
|
63
|
+
# @return [Integer] The decoded bit value (0 or 1)
|
|
64
|
+
def decode_bit(model)
|
|
65
|
+
# Inline normalize: only the hot path (range < TOP check)
|
|
66
|
+
# Init bytes are handled eagerly in reset(), not here
|
|
67
|
+
if @range < 0x01000000
|
|
68
|
+
@range <<= 8
|
|
69
|
+
byte = @stream.getbyte
|
|
70
|
+
if byte.nil?
|
|
71
|
+
raise Omnizip::DecompressionError,
|
|
72
|
+
"Truncated LZMA stream during range decoder normalization"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
@code = ((@code << 8) | byte) & 0xFFFFFFFF
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
prob = model.probability
|
|
79
|
+
bound = (@range >> 11) * prob
|
|
80
|
+
|
|
81
|
+
if @code < bound
|
|
82
|
+
@range = bound
|
|
83
|
+
# Inline model.update(0): prob += (2048 - prob) >> 5
|
|
84
|
+
model.probability = prob + ((2048 - prob) >> 5)
|
|
85
|
+
0
|
|
86
|
+
else
|
|
87
|
+
@code -= bound
|
|
88
|
+
@range -= bound
|
|
89
|
+
# Inline model.update(1): prob -= prob >> 5
|
|
90
|
+
model.probability = prob - (prob >> 5)
|
|
91
|
+
1
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Decode bits directly without using probability model
|
|
96
|
+
#
|
|
97
|
+
# @param num_bits [Integer] Number of bits to decode
|
|
98
|
+
# @return [Integer] The decoded value
|
|
99
|
+
def decode_direct_bits(num_bits)
|
|
100
|
+
result = 0
|
|
101
|
+
|
|
102
|
+
num_bits.downto(1) do |_i|
|
|
103
|
+
# Inline normalize
|
|
104
|
+
if @range < 0x01000000
|
|
105
|
+
@range <<= 8
|
|
106
|
+
byte = @stream.getbyte
|
|
107
|
+
if byte.nil?
|
|
108
|
+
raise Omnizip::DecompressionError,
|
|
109
|
+
"Truncated LZMA stream during range decoder normalization"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
@code = ((@code << 8) | byte) & 0xFFFFFFFF
|
|
113
|
+
end
|
|
114
|
+
@range >>= 1
|
|
115
|
+
|
|
116
|
+
bit = @code >= @range ? 1 : 0
|
|
117
|
+
|
|
118
|
+
if bit == 1
|
|
119
|
+
@code -= @range
|
|
120
|
+
result = (result << 1) | 1
|
|
121
|
+
else
|
|
122
|
+
result = (result << 1) | 0
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
result
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Decode a cumulative frequency value (PPMd)
|
|
130
|
+
#
|
|
131
|
+
# @param total_freq [Integer] Total frequency of all symbols in context
|
|
132
|
+
# @return [Integer] The cumulative frequency value
|
|
133
|
+
def decode_freq(total_freq)
|
|
134
|
+
normalize
|
|
135
|
+
range_freq = @range / total_freq
|
|
136
|
+
@code / range_freq
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Normalize after decoding a symbol with frequency
|
|
140
|
+
#
|
|
141
|
+
# @param cum_freq [Integer] Cumulative frequency of decoded symbol
|
|
142
|
+
# @param freq [Integer] Frequency of decoded symbol
|
|
143
|
+
# @param total_freq [Integer] Total frequency of all symbols
|
|
144
|
+
# @return [void]
|
|
145
|
+
def normalize_freq(cum_freq, freq, total_freq)
|
|
146
|
+
range_freq = @range / total_freq
|
|
147
|
+
low_bound = range_freq * cum_freq
|
|
148
|
+
high_bound = range_freq * (cum_freq + freq)
|
|
149
|
+
|
|
150
|
+
@code -= low_bound
|
|
151
|
+
@range = (high_bound - low_bound) & 0xFFFFFFFF
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Decode bits directly using a base value (XZ Utils rc_direct pattern)
|
|
155
|
+
#
|
|
156
|
+
# @param num_bits [Integer] Number of bits to decode
|
|
157
|
+
# @param base [Integer] Base value to start from (2 or 3 for distances)
|
|
158
|
+
# @return [Integer] The decoded value
|
|
159
|
+
def decode_direct_bits_with_base(num_bits, base)
|
|
160
|
+
result = base
|
|
161
|
+
num_bits.times do |_i|
|
|
162
|
+
result = (result << 1) + 1
|
|
163
|
+
# Inline normalize
|
|
164
|
+
if @range < 0x01000000
|
|
165
|
+
@range <<= 8
|
|
166
|
+
byte = @stream.getbyte
|
|
167
|
+
if byte.nil?
|
|
168
|
+
raise Omnizip::DecompressionError,
|
|
169
|
+
"Truncated LZMA stream during range decoder normalization"
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
@code = ((@code << 8) | byte) & 0xFFFFFFFF
|
|
173
|
+
end
|
|
174
|
+
@range >>= 1
|
|
175
|
+
|
|
176
|
+
bit = @code >= @range ? 1 : 0
|
|
177
|
+
|
|
178
|
+
if bit == 1
|
|
179
|
+
@code -= @range
|
|
180
|
+
else
|
|
181
|
+
result -= 1
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
result
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Reset the range decoder for a new chunk
|
|
188
|
+
#
|
|
189
|
+
# Resets state only. Call read_init_bytes after the stream is set
|
|
190
|
+
# to the correct input.
|
|
191
|
+
#
|
|
192
|
+
# @return [void]
|
|
193
|
+
def reset
|
|
194
|
+
@range = 0xFFFFFFFF
|
|
195
|
+
@code = 0
|
|
196
|
+
@init_bytes_remaining = 5
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Eagerly read the 5 initialization bytes from the current stream.
|
|
200
|
+
# Must be called after the stream is set to the correct input.
|
|
201
|
+
#
|
|
202
|
+
# @return [void]
|
|
203
|
+
def read_init_bytes
|
|
204
|
+
while @init_bytes_remaining.positive?
|
|
205
|
+
byte = @stream.getbyte
|
|
206
|
+
if byte.nil?
|
|
207
|
+
raise Omnizip::DecompressionError,
|
|
208
|
+
"Truncated LZMA stream during range decoder initialization"
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
@code = ((@code << 8) | byte) & 0xFFFFFFFF
|
|
212
|
+
@init_bytes_remaining -= 1
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Normalize the range when it becomes too small
|
|
217
|
+
#
|
|
218
|
+
# Still needed for decode_freq() and other non-hot paths.
|
|
219
|
+
# The hot-path methods inline normalize directly.
|
|
220
|
+
#
|
|
221
|
+
# @return [void]
|
|
222
|
+
def normalize
|
|
223
|
+
# Handle lazy initialization if needed (for non-hot paths)
|
|
224
|
+
if @init_bytes_remaining.positive?
|
|
225
|
+
while @init_bytes_remaining.positive?
|
|
226
|
+
byte = @stream.getbyte
|
|
227
|
+
if byte.nil?
|
|
228
|
+
raise Omnizip::DecompressionError,
|
|
229
|
+
"Truncated LZMA stream during range decoder initialization"
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
@code = ((@code << 8) | byte) & 0xFFFFFFFF
|
|
233
|
+
@init_bytes_remaining -= 1
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
if @range < TOP
|
|
238
|
+
byte = read_byte
|
|
239
|
+
@range <<= 8
|
|
240
|
+
@code = ((@code << 8) | byte) & 0xFFFFFFFF
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
private
|
|
245
|
+
|
|
246
|
+
# Initialize the decoder by reading the first bytes
|
|
247
|
+
#
|
|
248
|
+
# @return [void]
|
|
249
|
+
def init_decoder
|
|
250
|
+
5.times do
|
|
251
|
+
@code = ((@code << 8) | read_byte) & 0xFFFFFFFF
|
|
252
|
+
@init_bytes_remaining -= 1 if @init_bytes_remaining.positive?
|
|
253
|
+
end
|
|
254
|
+
@initialization_complete = true
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Read a single byte from the input stream
|
|
258
|
+
#
|
|
259
|
+
# @return [Integer] The byte value (0-255)
|
|
260
|
+
# @raise [Omnizip::DecompressionError] If stream is exhausted during normal decoding
|
|
261
|
+
def read_byte
|
|
262
|
+
byte = @stream.getbyte
|
|
263
|
+
|
|
264
|
+
if byte.nil? && @initialization_complete && @init_bytes_remaining.zero?
|
|
265
|
+
raise Omnizip::DecompressionError,
|
|
266
|
+
"LZMA compressed data exhausted prematurely. The file may be corrupted or the uncompressed size field may be incorrect."
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
byte || 0
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|