omnizip 0.4.7-aarch64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +32 -0
- data/.rubocop_todo.yml +293 -0
- data/CHANGELOG.md +1647 -0
- data/CONTEXT.md +68 -0
- data/COPYING +502 -0
- data/Gemfile +19 -0
- data/LICENSE +12 -0
- data/README.adoc +1327 -0
- data/Rakefile +15 -0
- data/TODO.refactor/00-overview.md +67 -0
- data/TODO.refactor/01-registry-base-class.md +81 -0
- data/TODO.refactor/02-error-hierarchy.md +57 -0
- data/TODO.refactor/03-autoload-entry-point.md +69 -0
- data/TODO.refactor/04-filter-base-consolidation.md +49 -0
- data/TODO.refactor/05-send-private-methods.md +64 -0
- data/TODO.refactor/06-instance-variable-access.md +69 -0
- data/TODO.refactor/07-respond-to-replacement.md +237 -0
- data/TODO.refactor/08-spec-doubles.md +27 -0
- data/TODO.refactor/09-cli-shared-module.md +35 -0
- data/TODO.refactor/10-format-detector-ocp.md +34 -0
- data/TODO.refactor/11-convenience-decoupling.md +38 -0
- data/TODO.refactor/12-thread-safety.md +8 -0
- data/TODO.refactor/13-lutaml-model-migration.md +158 -0
- data/TODO.refactor/14-add-missing-specs.md +25 -0
- data/benchmark/README.md +260 -0
- data/benchmark/benchmark_suite.rb +125 -0
- data/benchmark/compression_bench.rb +181 -0
- data/benchmark/filter_bench.rb +180 -0
- data/benchmark/models/benchmark_result.rb +59 -0
- data/benchmark/models/comparison_result.rb +69 -0
- data/benchmark/profile_suite.rb +167 -0
- data/benchmark/reporter.rb +150 -0
- data/benchmark/run_benchmarks.rb +66 -0
- data/benchmark/test_data.rb +137 -0
- data/config/formats/rar3_spec.yml +92 -0
- data/config/formats/rar5_spec.yml +102 -0
- data/docs/.github/workflows/docs.yml +142 -0
- data/docs/.gitignore +21 -0
- data/docs/.lychee.toml +67 -0
- data/docs/Gemfile +13 -0
- data/docs/RAR_WRITE_SUPPORT.md +26 -0
- data/docs/README.md +101 -0
- data/docs/_config.yml +112 -0
- data/docs/assets/logo.svg +1 -0
- data/docs/assets/omnizip-logo.pdf +1540 -11
- data/docs/comparison/feature-matrix.adoc +694 -0
- data/docs/comparison/index.adoc +113 -0
- data/docs/comparison/vs-7zip.adoc +309 -0
- data/docs/comparison/vs-peazip.adoc +77 -0
- data/docs/comparison/vs-rubyzip.adoc +342 -0
- data/docs/comparison/vs-winrar.adoc +100 -0
- data/docs/compatibility.adoc +579 -0
- data/docs/concepts/index.adoc +129 -0
- data/docs/developer/architecture.adoc +256 -0
- data/docs/developer/contributing.adoc +158 -0
- data/docs/developer/index.adoc +25 -0
- data/docs/developer/testing.adoc +212 -0
- data/docs/getting-started/basic-usage.adoc +263 -0
- data/docs/getting-started/index.adoc +42 -0
- data/docs/getting-started/installation.adoc +138 -0
- data/docs/getting-started/quick-start.adoc +183 -0
- data/docs/getting-started/your-first-archive.adoc +219 -0
- data/docs/guides/advanced-features/encryption.adoc +277 -0
- data/docs/guides/advanced-features/index.adoc +59 -0
- data/docs/guides/advanced-features/parallel-processing.adoc +144 -0
- data/docs/guides/advanced-features/progress-tracking.adoc +124 -0
- data/docs/guides/advanced-features/streaming.adoc +142 -0
- data/docs/guides/archive-formats/gzip-format.adoc +105 -0
- data/docs/guides/archive-formats/index.adoc +160 -0
- data/docs/guides/archive-formats/ole-format.adoc +151 -0
- data/docs/guides/archive-formats/rar-format.adoc +104 -0
- data/docs/guides/archive-formats/rar5.adoc +521 -0
- data/docs/guides/archive-formats/rpm-format.adoc +108 -0
- data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
- data/docs/guides/archive-formats/tar-format.adoc +106 -0
- data/docs/guides/archive-formats/xz-format.adoc +118 -0
- data/docs/guides/archive-formats/zip-format.adoc +35 -0
- data/docs/guides/compression-algorithms/bzip2.adoc +114 -0
- data/docs/guides/compression-algorithms/deflate.adoc +313 -0
- data/docs/guides/compression-algorithms/index.adoc +190 -0
- data/docs/guides/compression-algorithms/lzma.adoc +394 -0
- data/docs/guides/compression-algorithms/lzma2.adoc +244 -0
- data/docs/guides/compression-algorithms/ppmd.adoc +313 -0
- data/docs/guides/compression-algorithms/zstandard.adoc +296 -0
- data/docs/guides/creating-archives.adoc +348 -0
- data/docs/guides/extracting-archives.adoc +53 -0
- data/docs/guides/format-conversion.adoc +64 -0
- data/docs/guides/index.adoc +49 -0
- data/docs/guides/migration-rubyzip.adoc +217 -0
- data/docs/guides/parity-archives.adoc +605 -0
- data/docs/guides/performance-tuning.adoc +88 -0
- data/docs/index.adoc +228 -0
- data/docs/lychee.toml +67 -0
- data/docs/reference/api/overview.adoc +187 -0
- data/docs/reference/cli/compress-command.adoc +114 -0
- data/docs/reference/cli/overview.adoc +140 -0
- data/docs/reference/index.adoc +26 -0
- data/docs/resources/faq.adoc +185 -0
- data/docs/resources/quick-reference.adoc +222 -0
- data/docs/rust-backend.md +0 -0
- data/docs/troubleshooting/index.adoc +207 -0
- data/docs/xar_format.md +216 -0
- data/examples/api_comparison.rb +205 -0
- data/examples/deflate64_example.rb +96 -0
- data/examples/par2_demo.rb +121 -0
- data/examples/quick_start_native.rb +150 -0
- data/examples/quick_start_rubyzip.rb +115 -0
- data/examples/rubyzip_compatibility_demo.rb +194 -0
- data/exe/omnizip +27 -0
- data/lib/omnizip/algorithm.rb +176 -0
- data/lib/omnizip/algorithm_registry.rb +65 -0
- data/lib/omnizip/algorithms/.keep +0 -0
- data/lib/omnizip/algorithms/bzip2/bwt.rb +236 -0
- data/lib/omnizip/algorithms/bzip2/bz2.rb +687 -0
- data/lib/omnizip/algorithms/bzip2/rle.rb +146 -0
- data/lib/omnizip/algorithms/bzip2.rb +108 -0
- data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
- data/lib/omnizip/algorithms/deflate/decoder.rb +37 -0
- data/lib/omnizip/algorithms/deflate/encoder.rb +45 -0
- data/lib/omnizip/algorithms/deflate.rb +135 -0
- data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
- data/lib/omnizip/algorithms/deflate64/decoder.rb +151 -0
- data/lib/omnizip/algorithms/deflate64/encoder.rb +95 -0
- data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +352 -0
- data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +140 -0
- data/lib/omnizip/algorithms/deflate64.rb +118 -0
- data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
- data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
- data/lib/omnizip/algorithms/lzma/decoder.rb +146 -0
- data/lib/omnizip/algorithms/lzma/dictionary.rb +70 -0
- data/lib/omnizip/algorithms/lzma/distance_coder.rb +326 -0
- data/lib/omnizip/algorithms/lzma/encoder.rb +139 -0
- data/lib/omnizip/algorithms/lzma/length_coder.rb +172 -0
- data/lib/omnizip/algorithms/lzma/literal_decoder.rb +204 -0
- data/lib/omnizip/algorithms/lzma/literal_encoder.rb +208 -0
- data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +368 -0
- data/lib/omnizip/algorithms/lzma/lzma1_encoder.rb +105 -0
- data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +194 -0
- data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
- data/lib/omnizip/algorithms/lzma/match.rb +32 -0
- data/lib/omnizip/algorithms/lzma/match_finder.rb +233 -0
- data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
- data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +84 -0
- data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +159 -0
- data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
- data/lib/omnizip/algorithms/lzma/range_coder.rb +82 -0
- data/lib/omnizip/algorithms/lzma/range_decoder.rb +274 -0
- data/lib/omnizip/algorithms/lzma/range_encoder.rb +202 -0
- data/lib/omnizip/algorithms/lzma/state.rb +127 -0
- data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +323 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder.rb +420 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +640 -0
- data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +224 -0
- data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +167 -0
- data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +258 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +314 -0
- data/lib/omnizip/algorithms/lzma/xz_state.rb +108 -0
- data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +1311 -0
- data/lib/omnizip/algorithms/lzma.rb +266 -0
- data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +180 -0
- data/lib/omnizip/algorithms/lzma2/constants.rb +38 -0
- data/lib/omnizip/algorithms/lzma2/encoder.rb +145 -0
- data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +165 -0
- data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
- data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +122 -0
- data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
- data/lib/omnizip/algorithms/lzma2.rb +133 -0
- data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
- data/lib/omnizip/algorithms/ppmd7/context.rb +151 -0
- data/lib/omnizip/algorithms/ppmd7/decoder.rb +127 -0
- data/lib/omnizip/algorithms/ppmd7/encoder.rb +153 -0
- data/lib/omnizip/algorithms/ppmd7/model.rb +245 -0
- data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
- data/lib/omnizip/algorithms/ppmd7.rb +146 -0
- data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
- data/lib/omnizip/algorithms/ppmd8/context.rb +32 -0
- data/lib/omnizip/algorithms/ppmd8/decoder.rb +104 -0
- data/lib/omnizip/algorithms/ppmd8/encoder.rb +135 -0
- data/lib/omnizip/algorithms/ppmd8/model.rb +246 -0
- data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
- data/lib/omnizip/algorithms/ppmd8.rb +122 -0
- data/lib/omnizip/algorithms/ppmd_base.rb +142 -0
- data/lib/omnizip/algorithms/registration.rb +28 -0
- data/lib/omnizip/algorithms/zstandard/constants.rb +158 -0
- data/lib/omnizip/algorithms/zstandard/decoder.rb +249 -0
- data/lib/omnizip/algorithms/zstandard/dictionary.rb +73 -0
- data/lib/omnizip/algorithms/zstandard/encoder.rb +294 -0
- data/lib/omnizip/algorithms/zstandard/frame/block.rb +143 -0
- data/lib/omnizip/algorithms/zstandard/frame/header.rb +233 -0
- data/lib/omnizip/algorithms/zstandard/frame.rb +33 -0
- data/lib/omnizip/algorithms/zstandard/fse/bitstream.rb +183 -0
- data/lib/omnizip/algorithms/zstandard/fse/encoder.rb +534 -0
- data/lib/omnizip/algorithms/zstandard/fse/interleaved.rb +92 -0
- data/lib/omnizip/algorithms/zstandard/fse/table.rb +188 -0
- data/lib/omnizip/algorithms/zstandard/fse/table_description.rb +203 -0
- data/lib/omnizip/algorithms/zstandard/fse.rb +53 -0
- data/lib/omnizip/algorithms/zstandard/huffman.rb +276 -0
- data/lib/omnizip/algorithms/zstandard/huffman_encoder.rb +327 -0
- data/lib/omnizip/algorithms/zstandard/ldm.rb +121 -0
- data/lib/omnizip/algorithms/zstandard/literals.rb +241 -0
- data/lib/omnizip/algorithms/zstandard/literals_encoder.rb +96 -0
- data/lib/omnizip/algorithms/zstandard/match_finder.rb +483 -0
- data/lib/omnizip/algorithms/zstandard/sequences.rb +350 -0
- data/lib/omnizip/algorithms/zstandard/sequences_encoder.rb +333 -0
- data/lib/omnizip/algorithms/zstandard/xxhash.rb +159 -0
- data/lib/omnizip/algorithms/zstandard.rb +210 -0
- data/lib/omnizip/algorithms.rb +35 -0
- data/lib/omnizip/archive/builder.rb +48 -0
- data/lib/omnizip/archive/reader_session.rb +67 -0
- data/lib/omnizip/archive.rb +86 -0
- data/lib/omnizip/archive_handler.rb +82 -0
- data/lib/omnizip/archive_handlers/cpio_handler.rb +47 -0
- data/lib/omnizip/archive_handlers/iso_handler.rb +54 -0
- data/lib/omnizip/archive_handlers/ole_handler.rb +37 -0
- data/lib/omnizip/archive_handlers/rar_handler.rb +96 -0
- data/lib/omnizip/archive_handlers/rpm_handler.rb +45 -0
- data/lib/omnizip/archive_handlers/seven_zip_handler.rb +89 -0
- data/lib/omnizip/archive_handlers/tar_handler.rb +75 -0
- data/lib/omnizip/archive_handlers/xar_handler.rb +49 -0
- data/lib/omnizip/archive_handlers/zip_handler.rb +115 -0
- data/lib/omnizip/archive_handlers.rb +18 -0
- data/lib/omnizip/backends.rb +160 -0
- data/lib/omnizip/buffer/memory_archive.rb +246 -0
- data/lib/omnizip/buffer/memory_extractor.rb +234 -0
- data/lib/omnizip/buffer/seven_zip_bridge.rb +171 -0
- data/lib/omnizip/buffer.rb +187 -0
- data/lib/omnizip/checksum_registry.rb +41 -0
- data/lib/omnizip/checksums/crc32.rb +101 -0
- data/lib/omnizip/checksums/crc64.rb +102 -0
- data/lib/omnizip/checksums/crc_base.rb +158 -0
- data/lib/omnizip/checksums/registration.rb +16 -0
- data/lib/omnizip/checksums/verifier.rb +130 -0
- data/lib/omnizip/checksums.rb +11 -0
- data/lib/omnizip/chunked/memory_manager.rb +194 -0
- data/lib/omnizip/chunked/reader.rb +78 -0
- data/lib/omnizip/chunked/writer.rb +123 -0
- data/lib/omnizip/chunked.rb +123 -0
- data/lib/omnizip/cli/output_formatter.rb +112 -0
- data/lib/omnizip/cli.rb +604 -0
- data/lib/omnizip/commands/.keep +0 -0
- data/lib/omnizip/commands/archive_create_command.rb +245 -0
- data/lib/omnizip/commands/archive_extract_command.rb +231 -0
- data/lib/omnizip/commands/archive_list_command.rb +204 -0
- data/lib/omnizip/commands/archive_repair_command.rb +129 -0
- data/lib/omnizip/commands/archive_verify_command.rb +115 -0
- data/lib/omnizip/commands/compress_command.rb +115 -0
- data/lib/omnizip/commands/decompress_command.rb +149 -0
- data/lib/omnizip/commands/list_command.rb +51 -0
- data/lib/omnizip/commands/metadata_command.rb +215 -0
- data/lib/omnizip/commands/parity_create_command.rb +114 -0
- data/lib/omnizip/commands/parity_repair_command.rb +120 -0
- data/lib/omnizip/commands/parity_verify_command.rb +122 -0
- data/lib/omnizip/commands/profile_list_command.rb +54 -0
- data/lib/omnizip/commands/profile_show_command.rb +44 -0
- data/lib/omnizip/commands.rb +21 -0
- data/lib/omnizip/convenience.rb +389 -0
- data/lib/omnizip/converter/conversion_registry.rb +50 -0
- data/lib/omnizip/converter/conversion_strategy.rb +108 -0
- data/lib/omnizip/converter/extract_repack_strategy.rb +51 -0
- data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +43 -0
- data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +54 -0
- data/lib/omnizip/converter.rb +124 -0
- data/lib/omnizip/crypto/aes256/cipher.rb +104 -0
- data/lib/omnizip/crypto/aes256/constants.rb +28 -0
- data/lib/omnizip/crypto/aes256/key_derivation.rb +100 -0
- data/lib/omnizip/crypto/aes256.rb +102 -0
- data/lib/omnizip/crypto.rb +11 -0
- data/lib/omnizip/entry.rb +44 -0
- data/lib/omnizip/error.rb +110 -0
- data/lib/omnizip/eta/exponential_smoothing_estimator.rb +95 -0
- data/lib/omnizip/eta/moving_average_estimator.rb +96 -0
- data/lib/omnizip/eta/rate_calculator.rb +104 -0
- data/lib/omnizip/eta/sample_history.rb +143 -0
- data/lib/omnizip/eta/time_estimator.rb +106 -0
- data/lib/omnizip/eta.rb +68 -0
- data/lib/omnizip/extraction/filter_chain.rb +179 -0
- data/lib/omnizip/extraction/glob_pattern.rb +140 -0
- data/lib/omnizip/extraction/pattern_matcher.rb +66 -0
- data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
- data/lib/omnizip/extraction/regex_pattern.rb +50 -0
- data/lib/omnizip/extraction/selective_extractor.rb +247 -0
- data/lib/omnizip/extraction.rb +115 -0
- data/lib/omnizip/file_type/mime_classifier.rb +144 -0
- data/lib/omnizip/file_type.rb +117 -0
- data/lib/omnizip/filter.rb +141 -0
- data/lib/omnizip/filter_pipeline.rb +108 -0
- data/lib/omnizip/filter_registry.rb +113 -0
- data/lib/omnizip/filters/bcj.rb +277 -0
- data/lib/omnizip/filters/bcj2/constants.rb +53 -0
- data/lib/omnizip/filters/bcj2/decoder.rb +263 -0
- data/lib/omnizip/filters/bcj2/encoder.rb +58 -0
- data/lib/omnizip/filters/bcj2/stream_data.rb +91 -0
- data/lib/omnizip/filters/bcj2.rb +93 -0
- data/lib/omnizip/filters/bcj_arm.rb +174 -0
- data/lib/omnizip/filters/bcj_arm64.rb +242 -0
- data/lib/omnizip/filters/bcj_ia64.rb +194 -0
- data/lib/omnizip/filters/bcj_ppc.rb +188 -0
- data/lib/omnizip/filters/bcj_sparc.rb +174 -0
- data/lib/omnizip/filters/bcj_x86.rb +191 -0
- data/lib/omnizip/filters/delta.rb +195 -0
- data/lib/omnizip/filters/xz_delta.rb +258 -0
- data/lib/omnizip/filters.rb +20 -0
- data/lib/omnizip/format_detector.rb +166 -0
- data/lib/omnizip/formats/.keep +0 -0
- data/lib/omnizip/formats/bzip2_file.rb +159 -0
- data/lib/omnizip/formats/cpio/bounded_io.rb +66 -0
- data/lib/omnizip/formats/cpio/constants.rb +55 -0
- data/lib/omnizip/formats/cpio/entry.rb +389 -0
- data/lib/omnizip/formats/cpio/reader.rb +194 -0
- data/lib/omnizip/formats/cpio/writer.rb +232 -0
- data/lib/omnizip/formats/cpio.rb +132 -0
- data/lib/omnizip/formats/format_spec_loader.rb +228 -0
- data/lib/omnizip/formats/gzip.rb +236 -0
- data/lib/omnizip/formats/iso/directory_builder.rb +321 -0
- data/lib/omnizip/formats/iso/directory_record.rb +162 -0
- data/lib/omnizip/formats/iso/joliet.rb +204 -0
- data/lib/omnizip/formats/iso/path_table.rb +125 -0
- data/lib/omnizip/formats/iso/reader.rb +194 -0
- data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
- data/lib/omnizip/formats/iso/volume_builder.rb +319 -0
- data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
- data/lib/omnizip/formats/iso/writer.rb +543 -0
- data/lib/omnizip/formats/iso.rb +133 -0
- data/lib/omnizip/formats/lzip.rb +161 -0
- data/lib/omnizip/formats/lzma_alone.rb +149 -0
- data/lib/omnizip/formats/msi/cab_extractor.rb +181 -0
- data/lib/omnizip/formats/msi/constants.rb +157 -0
- data/lib/omnizip/formats/msi/directory_resolver.rb +188 -0
- data/lib/omnizip/formats/msi/entry.rb +134 -0
- data/lib/omnizip/formats/msi/reader.rb +301 -0
- data/lib/omnizip/formats/msi/string_pool.rb +246 -0
- data/lib/omnizip/formats/msi/table_parser.rb +244 -0
- data/lib/omnizip/formats/msi.rb +73 -0
- data/lib/omnizip/formats/ole/allocation_table.rb +263 -0
- data/lib/omnizip/formats/ole/constants.rb +61 -0
- data/lib/omnizip/formats/ole/dirent.rb +439 -0
- data/lib/omnizip/formats/ole/header.rb +199 -0
- data/lib/omnizip/formats/ole/ranges_io.rb +347 -0
- data/lib/omnizip/formats/ole/storage.rb +482 -0
- data/lib/omnizip/formats/ole/types/variant.rb +338 -0
- data/lib/omnizip/formats/ole.rb +143 -0
- data/lib/omnizip/formats/rar/archive_repairer.rb +240 -0
- data/lib/omnizip/formats/rar/archive_verifier.rb +192 -0
- data/lib/omnizip/formats/rar/block_parser.rb +282 -0
- data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
- data/lib/omnizip/formats/rar/compression/dispatcher.rb +210 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +212 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +154 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman.rb +25 -0
- data/lib/omnizip/formats/rar/compression/ppmd/context.rb +103 -0
- data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +238 -0
- data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +250 -0
- data/lib/omnizip/formats/rar/compression/ppmd.rb +16 -0
- data/lib/omnizip/formats/rar/compression.rb +17 -0
- data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
- data/lib/omnizip/formats/rar/constants.rb +88 -0
- data/lib/omnizip/formats/rar/decompressor.rb +316 -0
- data/lib/omnizip/formats/rar/external_writer.rb +311 -0
- data/lib/omnizip/formats/rar/header.rb +209 -0
- data/lib/omnizip/formats/rar/license_validator.rb +111 -0
- data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
- data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
- data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
- data/lib/omnizip/formats/rar/models.rb +14 -0
- data/lib/omnizip/formats/rar/parity_handler.rb +299 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +200 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +584 -0
- data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
- data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
- data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +96 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +162 -0
- data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
- data/lib/omnizip/formats/rar/rar5/header.rb +208 -0
- data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +260 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +176 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +108 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +139 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
- data/lib/omnizip/formats/rar/rar5/vint.rb +53 -0
- data/lib/omnizip/formats/rar/rar5/writer.rb +540 -0
- data/lib/omnizip/formats/rar/rar_format_base.rb +239 -0
- data/lib/omnizip/formats/rar/reader.rb +377 -0
- data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
- data/lib/omnizip/formats/rar/volume_manager.rb +166 -0
- data/lib/omnizip/formats/rar/writer.rb +437 -0
- data/lib/omnizip/formats/rar.rb +193 -0
- data/lib/omnizip/formats/rar3/compressor.rb +71 -0
- data/lib/omnizip/formats/rar3/decompressor.rb +64 -0
- data/lib/omnizip/formats/rar3/reader.rb +107 -0
- data/lib/omnizip/formats/rar3/writer.rb +220 -0
- data/lib/omnizip/formats/rar3.rb +15 -0
- data/lib/omnizip/formats/rar5/compressor.rb +71 -0
- data/lib/omnizip/formats/rar5/decompressor.rb +64 -0
- data/lib/omnizip/formats/rar5/reader.rb +130 -0
- data/lib/omnizip/formats/rar5/writer.rb +65 -0
- data/lib/omnizip/formats/rar5.rb +15 -0
- data/lib/omnizip/formats/rpm/constants.rb +58 -0
- data/lib/omnizip/formats/rpm/entry.rb +106 -0
- data/lib/omnizip/formats/rpm/header.rb +106 -0
- data/lib/omnizip/formats/rpm/lead.rb +132 -0
- data/lib/omnizip/formats/rpm/tag.rb +228 -0
- data/lib/omnizip/formats/rpm/writer.rb +652 -0
- data/lib/omnizip/formats/rpm.rb +458 -0
- data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +274 -0
- data/lib/omnizip/formats/seven_zip/coder_chain.rb +169 -0
- data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
- data/lib/omnizip/formats/seven_zip/encoded_header.rb +110 -0
- data/lib/omnizip/formats/seven_zip/encrypted_header.rb +139 -0
- data/lib/omnizip/formats/seven_zip/file_collector.rb +143 -0
- data/lib/omnizip/formats/seven_zip/header.rb +102 -0
- data/lib/omnizip/formats/seven_zip/header_encryptor.rb +132 -0
- data/lib/omnizip/formats/seven_zip/header_writer.rb +425 -0
- data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
- data/lib/omnizip/formats/seven_zip/models/file_entry.rb +65 -0
- data/lib/omnizip/formats/seven_zip/models/folder.rb +67 -0
- data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
- data/lib/omnizip/formats/seven_zip/models.rb +20 -0
- data/lib/omnizip/formats/seven_zip/parser.rb +671 -0
- data/lib/omnizip/formats/seven_zip/reader.rb +626 -0
- data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +611 -0
- data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +308 -0
- data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
- data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +166 -0
- data/lib/omnizip/formats/seven_zip/writer.rb +801 -0
- data/lib/omnizip/formats/seven_zip.rb +179 -0
- data/lib/omnizip/formats/tar/constants.rb +73 -0
- data/lib/omnizip/formats/tar/entry.rb +98 -0
- data/lib/omnizip/formats/tar/header.rb +206 -0
- data/lib/omnizip/formats/tar/reader.rb +119 -0
- data/lib/omnizip/formats/tar/writer.rb +212 -0
- data/lib/omnizip/formats/tar.rb +74 -0
- data/lib/omnizip/formats/xar/constants.rb +119 -0
- data/lib/omnizip/formats/xar/entry.rb +268 -0
- data/lib/omnizip/formats/xar/header.rb +223 -0
- data/lib/omnizip/formats/xar/reader.rb +400 -0
- data/lib/omnizip/formats/xar/toc.rb +570 -0
- data/lib/omnizip/formats/xar/writer.rb +461 -0
- data/lib/omnizip/formats/xar.rb +145 -0
- data/lib/omnizip/formats/xz/reader.rb +121 -0
- data/lib/omnizip/formats/xz/writer.rb +416 -0
- data/lib/omnizip/formats/xz.rb +210 -0
- data/lib/omnizip/formats/xz_const.rb +49 -0
- data/lib/omnizip/formats/xz_impl/block_decoder.rb +761 -0
- data/lib/omnizip/formats/xz_impl/block_encoder.rb +304 -0
- data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
- data/lib/omnizip/formats/xz_impl/block_header_parser.rb +182 -0
- data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
- data/lib/omnizip/formats/xz_impl/index_encoder.rb +120 -0
- data/lib/omnizip/formats/xz_impl/stream_decoder.rb +470 -0
- data/lib/omnizip/formats/xz_impl/stream_encoder.rb +95 -0
- data/lib/omnizip/formats/xz_impl/stream_footer.rb +79 -0
- data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +115 -0
- data/lib/omnizip/formats/xz_impl/stream_header.rb +53 -0
- data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +106 -0
- data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
- data/lib/omnizip/formats/xz_impl.rb +52 -0
- data/lib/omnizip/formats/zip/central_directory_header.rb +223 -0
- data/lib/omnizip/formats/zip/constants.rb +69 -0
- data/lib/omnizip/formats/zip/end_of_central_directory.rb +132 -0
- data/lib/omnizip/formats/zip/local_file_header.rb +136 -0
- data/lib/omnizip/formats/zip/reader.rb +376 -0
- data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
- data/lib/omnizip/formats/zip/writer.rb +489 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +102 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +64 -0
- data/lib/omnizip/formats/zip/zip64_extra_field.rb +112 -0
- data/lib/omnizip/formats/zip.rb +50 -0
- data/lib/omnizip/formats.rb +29 -0
- data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
- data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
- data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
- data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
- data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
- data/lib/omnizip/implementations/base.rb +19 -0
- data/lib/omnizip/implementations/rust/archive.rb +93 -0
- data/lib/omnizip/implementations/rust/library.rb +221 -0
- data/lib/omnizip/implementations/rust.rb +26 -0
- data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +428 -0
- data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +456 -0
- data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +285 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +197 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +194 -0
- data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +139 -0
- data/lib/omnizip/implementations/seven_zip/lzma.rb +21 -0
- data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +56 -0
- data/lib/omnizip/implementations/seven_zip/lzma2.rb +12 -0
- data/lib/omnizip/implementations/seven_zip.rb +11 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +547 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +748 -0
- data/lib/omnizip/implementations/xz_utils/lzma2.rb +13 -0
- data/lib/omnizip/implementations/xz_utils.rb +10 -0
- data/lib/omnizip/implementations.rb +25 -0
- data/lib/omnizip/io/buffered_input.rb +147 -0
- data/lib/omnizip/io/buffered_output.rb +106 -0
- data/lib/omnizip/io/source.rb +143 -0
- data/lib/omnizip/io/stream_manager.rb +117 -0
- data/lib/omnizip/io.rb +15 -0
- data/lib/omnizip/link_handler/hard_link.rb +79 -0
- data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
- data/lib/omnizip/link_handler.rb +129 -0
- data/lib/omnizip/metadata/archive_metadata.rb +114 -0
- data/lib/omnizip/metadata/entry_metadata.rb +153 -0
- data/lib/omnizip/metadata/metadata_editor.rb +169 -0
- data/lib/omnizip/metadata/metadata_registry.rb +71 -0
- data/lib/omnizip/metadata/metadata_validator.rb +101 -0
- data/lib/omnizip/metadata.rb +58 -0
- data/lib/omnizip/models/.keep +0 -0
- data/lib/omnizip/models/algorithm_metadata.rb +41 -0
- data/lib/omnizip/models/attribute_apply.rb +40 -0
- data/lib/omnizip/models/compression_options.rb +53 -0
- data/lib/omnizip/models/conversion_options.rb +79 -0
- data/lib/omnizip/models/conversion_result.rb +141 -0
- data/lib/omnizip/models/eta_result.rb +45 -0
- data/lib/omnizip/models/extraction_rule.rb +115 -0
- data/lib/omnizip/models/filter_chain.rb +142 -0
- data/lib/omnizip/models/filter_config.rb +148 -0
- data/lib/omnizip/models/match_result.rb +141 -0
- data/lib/omnizip/models/optimization_suggestion.rb +95 -0
- data/lib/omnizip/models/parallel_options.rb +116 -0
- data/lib/omnizip/models/performance_result.rb +85 -0
- data/lib/omnizip/models/profile_report.rb +116 -0
- data/lib/omnizip/models/progress_options.rb +39 -0
- data/lib/omnizip/models/split_options.rb +116 -0
- data/lib/omnizip/optimization_registry.rb +45 -0
- data/lib/omnizip/parallel/engine.rb +52 -0
- data/lib/omnizip/parallel/job_queue.rb +209 -0
- data/lib/omnizip/parallel/job_scheduler.rb +225 -0
- data/lib/omnizip/parallel/parallel_compressor.rb +326 -0
- data/lib/omnizip/parallel/parallel_extractor.rb +238 -0
- data/lib/omnizip/parallel/thread_pool.rb +60 -0
- data/lib/omnizip/parallel/worker_pool.rb +227 -0
- data/lib/omnizip/parallel.rb +156 -0
- data/lib/omnizip/parity/chunked_block_processor.rb +194 -0
- data/lib/omnizip/parity/galois16.rb +145 -0
- data/lib/omnizip/parity/models/creator_packet.rb +71 -0
- data/lib/omnizip/parity/models/file_description_packet.rb +131 -0
- data/lib/omnizip/parity/models/ifsc_packet.rb +111 -0
- data/lib/omnizip/parity/models/main_packet.rb +126 -0
- data/lib/omnizip/parity/models/packet.rb +156 -0
- data/lib/omnizip/parity/models/packet_registry.rb +102 -0
- data/lib/omnizip/parity/models/recovery_slice_packet.rb +76 -0
- data/lib/omnizip/parity/models.rb +27 -0
- data/lib/omnizip/parity/par2_creator.rb +496 -0
- data/lib/omnizip/parity/par2_repairer.rb +409 -0
- data/lib/omnizip/parity/par2_verifier.rb +373 -0
- data/lib/omnizip/parity/par2cmdline_algorithm.rb +108 -0
- data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
- data/lib/omnizip/parity/reed_solomon_decoder.rb +263 -0
- data/lib/omnizip/parity/reed_solomon_encoder.rb +108 -0
- data/lib/omnizip/parity/reed_solomon_matrix.rb +339 -0
- data/lib/omnizip/parity.rb +207 -0
- data/lib/omnizip/password/encryption_registry.rb +26 -0
- data/lib/omnizip/password/encryption_strategy.rb +96 -0
- data/lib/omnizip/password/password_validator.rb +129 -0
- data/lib/omnizip/password/winzip_aes_strategy.rb +190 -0
- data/lib/omnizip/password/zip_crypto_strategy.rb +135 -0
- data/lib/omnizip/password.rb +88 -0
- data/lib/omnizip/pipe/stream_compressor.rb +124 -0
- data/lib/omnizip/pipe/stream_decompressor.rb +173 -0
- data/lib/omnizip/pipe.rb +120 -0
- data/lib/omnizip/platform/ntfs_streams.rb +200 -0
- data/lib/omnizip/platform.rb +189 -0
- data/lib/omnizip/profile/archive_profile.rb +36 -0
- data/lib/omnizip/profile/balanced_profile.rb +31 -0
- data/lib/omnizip/profile/binary_profile.rb +33 -0
- data/lib/omnizip/profile/compression_profile.rb +157 -0
- data/lib/omnizip/profile/custom_profile.rb +155 -0
- data/lib/omnizip/profile/fast_profile.rb +31 -0
- data/lib/omnizip/profile/maximum_profile.rb +31 -0
- data/lib/omnizip/profile/profile_detector.rb +108 -0
- data/lib/omnizip/profile/profile_registry.rb +160 -0
- data/lib/omnizip/profile/text_profile.rb +33 -0
- data/lib/omnizip/profile.rb +261 -0
- data/lib/omnizip/profiler/memory_profiler.rb +66 -0
- data/lib/omnizip/profiler/method_profiler.rb +49 -0
- data/lib/omnizip/profiler/report_generator.rb +158 -0
- data/lib/omnizip/profiler.rb +192 -0
- data/lib/omnizip/progress/callback_reporter.rb +34 -0
- data/lib/omnizip/progress/console_reporter.rb +59 -0
- data/lib/omnizip/progress/log_reporter.rb +89 -0
- data/lib/omnizip/progress/operation_progress.rb +118 -0
- data/lib/omnizip/progress/progress_bar.rb +156 -0
- data/lib/omnizip/progress/progress_reporter.rb +40 -0
- data/lib/omnizip/progress/progress_tracker.rb +215 -0
- data/lib/omnizip/progress/silent_reporter.rb +22 -0
- data/lib/omnizip/progress.rb +131 -0
- data/lib/omnizip/registry.rb +111 -0
- data/lib/omnizip/rubyzip_compat.rb +61 -0
- data/lib/omnizip/temp/safe_extract.rb +124 -0
- data/lib/omnizip/temp/temp_file.rb +123 -0
- data/lib/omnizip/temp/temp_file_pool.rb +109 -0
- data/lib/omnizip/temp.rb +184 -0
- data/lib/omnizip/version.rb +5 -0
- data/lib/omnizip/zip/entry.rb +160 -0
- data/lib/omnizip/zip/file.rb +485 -0
- data/lib/omnizip/zip/input_stream.rb +270 -0
- data/lib/omnizip/zip/output_stream.rb +320 -0
- data/lib/omnizip/zip.rb +23 -0
- data/lib/omnizip.rb +157 -0
- data/lib/tasks/msi_test_files.rake +66 -0
- data/lib/tasks/platform_gems.rake +147 -0
- data/lib/tasks/rust_backend.rake +48 -0
- data/readme-docs/advanced-features.adoc +514 -0
- data/readme-docs/api-usage.adoc +445 -0
- data/readme-docs/architecture.adoc +450 -0
- data/readme-docs/archive-formats.adoc +479 -0
- data/readme-docs/cli-usage.adoc +222 -0
- data/readme-docs/compression-algorithms.adoc +446 -0
- data/readme-docs/compression-profiles.adoc +247 -0
- data/readme-docs/encryption-checksums.adoc +328 -0
- data/readme-docs/format-converter.adoc +316 -0
- data/readme-docs/installation.adoc +228 -0
- data/readme-docs/par2-archives.adoc +608 -0
- data/readme-docs/performance-profiler.adoc +389 -0
- data/readme-docs/preprocessing-filters.adoc +280 -0
- data/vendor/libomnizip_ffi.so +0 -0
- data/xz-file-format-1.2.1.txt +1174 -0
- metadata +768 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Algorithms
|
|
5
|
+
class LZMA < Algorithm
|
|
6
|
+
# LZMA State Machine
|
|
7
|
+
# Ported from XZ Utils lzma_common.h and lzma_decoder.c
|
|
8
|
+
class LZMAState
|
|
9
|
+
# State transition table (from lzma_decoder.c)
|
|
10
|
+
TRANSITIONS = {
|
|
11
|
+
# Literal after literal (matches XZ Utils update_literal macro)
|
|
12
|
+
update_literal: {
|
|
13
|
+
0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 1, 5 => 2,
|
|
14
|
+
6 => 3, 7 => 4, 8 => 5, 9 => 6, 10 => 4, 11 => 5
|
|
15
|
+
}.freeze,
|
|
16
|
+
|
|
17
|
+
# Matched literal (literal after match, matches XZ Utils update_literal_matched macro)
|
|
18
|
+
# Only called when previous state was NOT a literal (states 7-11)
|
|
19
|
+
update_literal_matched: {
|
|
20
|
+
0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 1, 5 => 2,
|
|
21
|
+
6 => 3, 7 => 4, 8 => 5, 9 => 6, 10 => 4, 11 => 5
|
|
22
|
+
}.freeze,
|
|
23
|
+
|
|
24
|
+
# Regular match
|
|
25
|
+
update_match: {
|
|
26
|
+
0 => 7, 1 => 7, 2 => 7, 3 => 7, 4 => 7, 5 => 7,
|
|
27
|
+
6 => 7, 7 => 10, 8 => 10, 9 => 10, 10 => 10, 11 => 10
|
|
28
|
+
}.freeze,
|
|
29
|
+
|
|
30
|
+
# Repeat match
|
|
31
|
+
update_rep: {
|
|
32
|
+
0 => 8, 1 => 8, 2 => 8, 3 => 8, 4 => 8, 5 => 8,
|
|
33
|
+
6 => 8, 7 => 11, 8 => 11, 9 => 11, 10 => 11, 11 => 11
|
|
34
|
+
}.freeze,
|
|
35
|
+
|
|
36
|
+
# Short repeat (length=1)
|
|
37
|
+
update_short_rep: {
|
|
38
|
+
0 => 9, 1 => 9, 2 => 9, 3 => 9, 4 => 9, 5 => 9,
|
|
39
|
+
6 => 9, 7 => 11, 8 => 11, 9 => 11, 10 => 11, 11 => 11
|
|
40
|
+
}.freeze,
|
|
41
|
+
|
|
42
|
+
# Long repeat (length>1)
|
|
43
|
+
# Ported from XZ Utils: state < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP
|
|
44
|
+
# where LIT_STATES=7, STATE_LIT_LONGREP=8, STATE_NONLIT_REP=11
|
|
45
|
+
update_long_rep: {
|
|
46
|
+
0 => 8, 1 => 8, 2 => 8, 3 => 8, 4 => 8, 5 => 8,
|
|
47
|
+
6 => 8, 7 => 11, 8 => 11, 9 => 11, 10 => 11, 11 => 11
|
|
48
|
+
}.freeze,
|
|
49
|
+
}.freeze
|
|
50
|
+
|
|
51
|
+
attr_reader :value, :reps
|
|
52
|
+
|
|
53
|
+
def initialize(value = 0)
|
|
54
|
+
@value = value
|
|
55
|
+
@reps = [0, 0, 0, 0] # Initial repeat distances (matches XZ Utils)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# After encoding a literal
|
|
59
|
+
def update_literal!
|
|
60
|
+
@value = if use_matched_literal?
|
|
61
|
+
TRANSITIONS[:update_literal_matched][@value]
|
|
62
|
+
else
|
|
63
|
+
TRANSITIONS[:update_literal][@value]
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# After encoding a regular match
|
|
68
|
+
def update_match!(distance)
|
|
69
|
+
@value = TRANSITIONS[:update_match][@value]
|
|
70
|
+
rotate_reps!(distance)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# After encoding a repeat match
|
|
74
|
+
def update_rep!(rep_index)
|
|
75
|
+
@value = TRANSITIONS[:update_rep][@value]
|
|
76
|
+
rotate_reps_for_rep!(rep_index)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# After encoding a short rep (length=1)
|
|
80
|
+
def update_short_rep!
|
|
81
|
+
@value = TRANSITIONS[:update_short_rep][@value]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# After encoding a long rep (length>1)
|
|
85
|
+
# Ported from XZ Utils update_long_rep macro
|
|
86
|
+
def update_long_rep!
|
|
87
|
+
@value = TRANSITIONS[:update_long_rep][@value]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Check if we should use matched literal encoding
|
|
91
|
+
# XZ Utils logic: is_literal_state(state) = (state < LIT_STATES)
|
|
92
|
+
# where LIT_STATES = 7
|
|
93
|
+
# States 0-6: literal states (use unmatched literal)
|
|
94
|
+
# States 7-11: non-literal states (use matched literal)
|
|
95
|
+
def use_matched_literal?
|
|
96
|
+
@value >= 7
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Repeat distance rotation
|
|
100
|
+
def rotate_reps!(distance)
|
|
101
|
+
@reps[3] = @reps[2]
|
|
102
|
+
@reps[2] = @reps[1]
|
|
103
|
+
@reps[1] = @reps[0]
|
|
104
|
+
@reps[0] = distance
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
def rotate_reps_for_rep!(rep_index)
|
|
110
|
+
case rep_index
|
|
111
|
+
when 0
|
|
112
|
+
# Keep rep0, no rotation
|
|
113
|
+
when 1
|
|
114
|
+
# rep1 -> rep0
|
|
115
|
+
@reps[0], @reps[1] = @reps[1], @reps[0]
|
|
116
|
+
when 2
|
|
117
|
+
# rep2 -> rep0, rep0 -> rep1, rep1 -> rep2
|
|
118
|
+
@reps[0], @reps[1], @reps[2] = @reps[2], @reps[0], @reps[1]
|
|
119
|
+
when 3
|
|
120
|
+
# rep3 -> rep0, rotate others
|
|
121
|
+
@reps[0], @reps[1], @reps[2], @reps[3] =
|
|
122
|
+
@reps[3], @reps[0], @reps[1], @reps[2]
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Algorithms
|
|
5
|
+
class LZMA < Algorithm
|
|
6
|
+
# Match candidate result from LZ77 match finding
|
|
7
|
+
class Match
|
|
8
|
+
attr_reader :distance, :length
|
|
9
|
+
|
|
10
|
+
def initialize(distance, length)
|
|
11
|
+
@distance = distance
|
|
12
|
+
@length = length
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Check if match is valid for given dictionary size
|
|
16
|
+
#
|
|
17
|
+
# @param dict_size [Integer] Dictionary size in bytes
|
|
18
|
+
# @return [Boolean] true if match is valid
|
|
19
|
+
def valid?(dict_size)
|
|
20
|
+
@distance <= dict_size && @length >= 2
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# String representation for debugging
|
|
24
|
+
#
|
|
25
|
+
# @return [String] Match description
|
|
26
|
+
def to_s
|
|
27
|
+
"Match(dist=#{@distance}, len=#{@length})"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,233 @@
|
|
|
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
|
+
# Match Finder using hash chain algorithm for LZ77 compression
|
|
27
|
+
# Ported from XZ Utils lz_encoder.c
|
|
28
|
+
class MatchFinder
|
|
29
|
+
# Larger hash table for better distribution
|
|
30
|
+
# 16384 slots with 4-byte keys gives better collision resistance
|
|
31
|
+
HASH_SIZE = 16384
|
|
32
|
+
HASH_MASK = HASH_SIZE - 1
|
|
33
|
+
MAX_MATCHES = 274
|
|
34
|
+
# Maximum hash chain depth to prevent O(n) lookups
|
|
35
|
+
# XZ Utils uses different values based on compression level (4-256)
|
|
36
|
+
# Ruby needs much lower values due to slower string operations
|
|
37
|
+
# Testing shows depth 16 gives same compression ratio as 32-64 but 2-3x faster
|
|
38
|
+
DEFAULT_CHAIN_DEPTH = 16
|
|
39
|
+
|
|
40
|
+
attr_reader :dictionary, :buffer, :position
|
|
41
|
+
|
|
42
|
+
def initialize(dictionary, chain_depth: DEFAULT_CHAIN_DEPTH)
|
|
43
|
+
@dictionary = dictionary
|
|
44
|
+
@buffer = String.new(encoding: Encoding::BINARY)
|
|
45
|
+
@position = 0
|
|
46
|
+
@chain_depth = chain_depth
|
|
47
|
+
# Use nil as empty marker (not 0) to distinguish from position 0
|
|
48
|
+
@hash_table = Array.new(HASH_SIZE, nil)
|
|
49
|
+
@hash_chain = Array.new(0)
|
|
50
|
+
@matches = Array.new(MAX_MATCHES)
|
|
51
|
+
@matches_count = 0
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Add input data for processing
|
|
55
|
+
#
|
|
56
|
+
# @param data [String] Binary data to add
|
|
57
|
+
# @return [void]
|
|
58
|
+
def feed(data)
|
|
59
|
+
@buffer << data
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Reset the match finder state for a new encoding session
|
|
63
|
+
# Clears the buffer, hash table, and hash chain
|
|
64
|
+
def reset
|
|
65
|
+
@buffer.clear
|
|
66
|
+
@position = 0
|
|
67
|
+
@hash_table = Array.new(HASH_SIZE, nil)
|
|
68
|
+
@hash_chain.clear
|
|
69
|
+
@matches_count = 0
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Initialize hash table for all positions up to end_pos
|
|
73
|
+
# This is called before encoding starts to ensure the hash table
|
|
74
|
+
# is populated for all positions. Matches XZ Utils "skip" behavior.
|
|
75
|
+
#
|
|
76
|
+
# @param end_pos [Integer] Last position to initialize (inclusive)
|
|
77
|
+
# @return [void]
|
|
78
|
+
def skip(end_pos)
|
|
79
|
+
pos = 0
|
|
80
|
+
while pos + 3 <= @buffer.bytesize && pos <= end_pos
|
|
81
|
+
hash = calc_hash(@buffer, pos)
|
|
82
|
+
if hash
|
|
83
|
+
@hash_chain[pos] = @hash_table[hash]
|
|
84
|
+
@hash_table[hash] = pos
|
|
85
|
+
end
|
|
86
|
+
pos += 1
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Find matches for current position
|
|
91
|
+
#
|
|
92
|
+
# @param current_pos [Integer] Position to find matches at (defaults to end)
|
|
93
|
+
# @return [Array<Match>] Array of matches sorted by length (descending)
|
|
94
|
+
def find_matches(current_pos = @buffer.bytesize - 273)
|
|
95
|
+
# Calculate hash for current position
|
|
96
|
+
# Note: Using 4-byte hash now (calc_hash checks pos + 4)
|
|
97
|
+
hash = nil
|
|
98
|
+
if current_pos >= 0 && current_pos + 4 <= @buffer.bytesize
|
|
99
|
+
hash = calc_hash(@buffer, current_pos)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Skip hash table update here - skip() already built the table for all positions
|
|
103
|
+
# Adding current_pos to the chain is redundant since skip processed all positions
|
|
104
|
+
|
|
105
|
+
# Can't find matches if no hash or insufficient data
|
|
106
|
+
# Note: We CAN find matches at early positions (e.g., position 2 can match position 0)
|
|
107
|
+
# The only requirement is that there's enough data for hash calculation (current_pos + 4 <= buffer size)
|
|
108
|
+
# and that there's at least 2 bytes of history (for MIN_MATCH_LENGTH=2)
|
|
109
|
+
# CRITICAL: Don't produce matches until position >= 2 to ensure decoder has enough dict_full
|
|
110
|
+
# The decoder validates: dict_full > distance, where dict_full starts at 0 after 1st byte
|
|
111
|
+
# For distance=1 match to be valid, decoder needs dict_full >= 2 (at least 2 bytes decoded)
|
|
112
|
+
# This happens after processing position 1 (first byte was literal at position 0)
|
|
113
|
+
# So we can only produce matches starting at position 2
|
|
114
|
+
return [] if hash.nil? || @buffer.bytesize < 4 || current_pos + 4 > @buffer.bytesize || current_pos < 2
|
|
115
|
+
|
|
116
|
+
@matches_count = 0
|
|
117
|
+
chain_pos = @hash_chain[current_pos]
|
|
118
|
+
chain_depth = 0
|
|
119
|
+
|
|
120
|
+
while chain_pos && @matches_count < MAX_MATCHES && chain_depth < @chain_depth
|
|
121
|
+
chain_depth += 1
|
|
122
|
+
# CRITICAL: Skip invalid chain_pos values (beyond buffer or negative)
|
|
123
|
+
next if chain_pos >= @buffer.bytesize || chain_pos.negative?
|
|
124
|
+
|
|
125
|
+
distance = current_pos - chain_pos
|
|
126
|
+
# CRITICAL: Break if distance is negative (chain_pos > current_pos)
|
|
127
|
+
# This can happen when skip() links positions within the same chunk
|
|
128
|
+
# where a later position has the same hash as an earlier position
|
|
129
|
+
break if distance.negative? || distance > @dictionary.size || distance.zero?
|
|
130
|
+
|
|
131
|
+
length = verify_match(current_pos, chain_pos)
|
|
132
|
+
|
|
133
|
+
if length >= 2
|
|
134
|
+
@matches[@matches_count] = Match.new(distance, length)
|
|
135
|
+
@matches_count += 1
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Safely get next chain position
|
|
139
|
+
chain_pos = if chain_pos < @hash_chain.size
|
|
140
|
+
@hash_chain[chain_pos]
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
@matches.first(@matches_count).sort_by { |m| -m.length }
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Get the longest match at current position
|
|
148
|
+
#
|
|
149
|
+
# @return [Match, nil] Longest match found or nil
|
|
150
|
+
def longest_match
|
|
151
|
+
find_matches.first
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Legacy API: Find longest match at given position in external byte array
|
|
155
|
+
# This is a compatibility method for older code that passes bytes and position
|
|
156
|
+
#
|
|
157
|
+
# @param bytes [Array<Integer>] Byte array
|
|
158
|
+
# @param pos [Integer] Position to find match at
|
|
159
|
+
# @return [Match, nil] Longest match found or nil
|
|
160
|
+
def find_longest_match(bytes, pos)
|
|
161
|
+
# If position is beyond current buffer, feed more data
|
|
162
|
+
if pos >= @buffer.bytesize
|
|
163
|
+
bytes_to_feed = bytes[pos..]
|
|
164
|
+
@buffer << bytes_to_feed.pack("C*")
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Find matches at the given position
|
|
168
|
+
matches = find_matches(pos)
|
|
169
|
+
matches.first
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
private
|
|
173
|
+
|
|
174
|
+
# Calculate hash for position using 4-byte key with mixing
|
|
175
|
+
# Uses FNV-1a inspired mixing for better distribution
|
|
176
|
+
#
|
|
177
|
+
# @param data [String] Buffer data
|
|
178
|
+
# @param pos [Integer] Position to hash
|
|
179
|
+
# @return [Integer] Hash value
|
|
180
|
+
def calc_hash(data, pos)
|
|
181
|
+
return 0 if pos + 4 > data.bytesize
|
|
182
|
+
|
|
183
|
+
# Read 4 bytes as 32-bit integer (little-endian)
|
|
184
|
+
v = data.getbyte(pos) |
|
|
185
|
+
(data.getbyte(pos + 1) << 8) |
|
|
186
|
+
(data.getbyte(pos + 2) << 16) |
|
|
187
|
+
(data.getbyte(pos + 3) << 24)
|
|
188
|
+
|
|
189
|
+
# FNV-1a style mixing for better distribution
|
|
190
|
+
# Hash avalanche: each input bit affects all output bits
|
|
191
|
+
v = (v ^ (v >> 16)) * 0x45D9F3B
|
|
192
|
+
v = (v ^ (v >> 16)) * 0x45D9F3B
|
|
193
|
+
(v ^ (v >> 16)) & HASH_MASK
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Verify match length between two positions
|
|
197
|
+
# Uses 4-byte quick check then binary search with integer comparison
|
|
198
|
+
#
|
|
199
|
+
# @param pos1 [Integer] First position
|
|
200
|
+
# @param pos2 [Integer] Second position
|
|
201
|
+
# @return [Integer] Match length
|
|
202
|
+
def verify_match(pos1, pos2)
|
|
203
|
+
buf = @buffer
|
|
204
|
+
max_len = [273, buf.bytesize - pos1, buf.bytesize - pos2].min
|
|
205
|
+
return 0 if max_len <= 0
|
|
206
|
+
|
|
207
|
+
# Quick rejection: check first 4 bytes as integer
|
|
208
|
+
if max_len >= 4
|
|
209
|
+
v1 = buf.byteslice(pos1, 4).unpack1("L<")
|
|
210
|
+
v2 = buf.byteslice(pos2, 4).unpack1("L<")
|
|
211
|
+
return 0 if v1 != v2
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Binary search for exact match length
|
|
215
|
+
# Creates O(log n) strings but does efficient integer comparison
|
|
216
|
+
low = 0
|
|
217
|
+
high = max_len
|
|
218
|
+
|
|
219
|
+
while low < high
|
|
220
|
+
mid = (low + high + 1) / 2
|
|
221
|
+
if buf.byteslice(pos1, mid) == buf.byteslice(pos2, mid)
|
|
222
|
+
low = mid
|
|
223
|
+
else
|
|
224
|
+
high = mid - 1
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
low
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
@@ -0,0 +1,142 @@
|
|
|
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
|
+
# Configuration model for Match Finder behavior
|
|
27
|
+
#
|
|
28
|
+
# This model separates configuration from implementation, allowing
|
|
29
|
+
# different match finding strategies (SDK-compatible vs simplified)
|
|
30
|
+
# to be configured declaratively.
|
|
31
|
+
#
|
|
32
|
+
# @example SDK-compatible configuration
|
|
33
|
+
# config = MatchFinderConfig.new(
|
|
34
|
+
# mode: :sdk,
|
|
35
|
+
# hash_size: 65536,
|
|
36
|
+
# chain_length: 32,
|
|
37
|
+
# lazy_matching: false
|
|
38
|
+
# )
|
|
39
|
+
#
|
|
40
|
+
# @example Simplified configuration
|
|
41
|
+
# config = MatchFinderConfig.new(
|
|
42
|
+
# mode: :simplified,
|
|
43
|
+
# hash_size: 65536,
|
|
44
|
+
# chain_length: 1024
|
|
45
|
+
# )
|
|
46
|
+
class MatchFinderConfig
|
|
47
|
+
attr_accessor :mode, :hash_size, :chain_length, :search_mode,
|
|
48
|
+
:lazy_matching, :max_match_length, :window_size
|
|
49
|
+
|
|
50
|
+
def initialize(mode: "simplified", hash_size: 65_536,
|
|
51
|
+
chain_length: 1024, search_mode: "hash_chain",
|
|
52
|
+
lazy_matching: false, max_match_length: 273,
|
|
53
|
+
window_size: 65_536)
|
|
54
|
+
@mode = mode
|
|
55
|
+
@hash_size = hash_size
|
|
56
|
+
@chain_length = chain_length
|
|
57
|
+
@search_mode = search_mode
|
|
58
|
+
@lazy_matching = lazy_matching
|
|
59
|
+
@max_match_length = max_match_length
|
|
60
|
+
@window_size = window_size
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Validate configuration
|
|
64
|
+
#
|
|
65
|
+
# @return [Boolean] true if valid
|
|
66
|
+
# @raise [ArgumentError] if configuration is invalid
|
|
67
|
+
def validate!
|
|
68
|
+
unless %w[sdk simplified].include?(mode)
|
|
69
|
+
raise ArgumentError, "mode must be :sdk or :simplified"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
unless %w[hash_chain binary_tree].include?(search_mode)
|
|
73
|
+
raise ArgumentError,
|
|
74
|
+
"search_mode must be :hash_chain or :binary_tree"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
raise ArgumentError, "hash_size must be positive" if hash_size <= 0
|
|
78
|
+
|
|
79
|
+
if chain_length <= 0
|
|
80
|
+
raise ArgumentError,
|
|
81
|
+
"chain_length must be positive"
|
|
82
|
+
end
|
|
83
|
+
if max_match_length < 2
|
|
84
|
+
raise ArgumentError,
|
|
85
|
+
"max_match_length must be >= 2"
|
|
86
|
+
end
|
|
87
|
+
if window_size <= 0
|
|
88
|
+
raise ArgumentError,
|
|
89
|
+
"window_size must be positive"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
true
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Create SDK-compatible configuration
|
|
96
|
+
#
|
|
97
|
+
# @param dict_size [Integer] Dictionary size
|
|
98
|
+
# @param level [Integer] Compression level (0-9)
|
|
99
|
+
# @return [MatchFinderConfig] SDK-compatible configuration
|
|
100
|
+
def self.sdk_config(dict_size: 65536, level: 5)
|
|
101
|
+
# SDK uses different parameters based on dictionary size and level
|
|
102
|
+
hash_size = dict_size >= (1 << 20) ? (1 << 20) : (1 << 16)
|
|
103
|
+
|
|
104
|
+
# SDK nice_len varies by compression level:
|
|
105
|
+
# Level 0-4: 32, Level 5-6: 64, Level 7-8: 128, Level 9: 273
|
|
106
|
+
chain_length = case level
|
|
107
|
+
when 0..4 then 32
|
|
108
|
+
when 5..6 then 64
|
|
109
|
+
when 7..8 then 128
|
|
110
|
+
else 273
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
new(
|
|
114
|
+
mode: "sdk",
|
|
115
|
+
hash_size: hash_size,
|
|
116
|
+
chain_length: chain_length,
|
|
117
|
+
search_mode: "hash_chain",
|
|
118
|
+
lazy_matching: level >= 7, # Enable lazy matching for high compression
|
|
119
|
+
max_match_length: 273,
|
|
120
|
+
window_size: dict_size,
|
|
121
|
+
)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Create simplified configuration with sensible defaults.
|
|
125
|
+
#
|
|
126
|
+
# @param dict_size [Integer] Dictionary size
|
|
127
|
+
# @return [MatchFinderConfig] Simplified configuration
|
|
128
|
+
def self.simplified_config(dict_size: 65536)
|
|
129
|
+
new(
|
|
130
|
+
mode: "simplified",
|
|
131
|
+
hash_size: 65536,
|
|
132
|
+
chain_length: 1024,
|
|
133
|
+
search_mode: "hash_chain",
|
|
134
|
+
lazy_matching: false,
|
|
135
|
+
max_match_length: 273,
|
|
136
|
+
window_size: dict_size,
|
|
137
|
+
)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
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
|
+
# Factory for creating Match Finder instances
|
|
27
|
+
#
|
|
28
|
+
# This factory implements the Factory pattern to create different
|
|
29
|
+
# match finder implementations based on configuration. It provides
|
|
30
|
+
# a clean separation between the configuration (what) and the
|
|
31
|
+
# implementation (how).
|
|
32
|
+
#
|
|
33
|
+
# @example Creating an SDK-compatible match finder
|
|
34
|
+
# config = MatchFinderConfig.sdk_config(dict_size: 65536, level: 5)
|
|
35
|
+
# finder = MatchFinderFactory.create(config)
|
|
36
|
+
#
|
|
37
|
+
# @example Creating a simplified match finder
|
|
38
|
+
# config = MatchFinderConfig.simplified_config(dict_size: 65536)
|
|
39
|
+
# finder = MatchFinderFactory.create(config)
|
|
40
|
+
class MatchFinderFactory
|
|
41
|
+
# Create a match finder instance based on configuration
|
|
42
|
+
#
|
|
43
|
+
# @param config [MatchFinderConfig] Configuration object
|
|
44
|
+
# @return [MatchFinder, Implementations::SevenZip::LZMA::MatchFinder] Match finder instance
|
|
45
|
+
# @raise [ArgumentError] if configuration is invalid
|
|
46
|
+
def self.create(config)
|
|
47
|
+
config.validate!
|
|
48
|
+
|
|
49
|
+
case config.mode
|
|
50
|
+
when "sdk"
|
|
51
|
+
Implementations::SevenZip::LZMA::MatchFinder.new(config)
|
|
52
|
+
when "simplified"
|
|
53
|
+
# Use simplified MatchFinder implementation
|
|
54
|
+
MatchFinder.new(config.window_size, config.max_match_length)
|
|
55
|
+
else
|
|
56
|
+
raise ArgumentError, "Unknown match finder mode: #{config.mode}"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Create match finder from options hash (convenience method)
|
|
61
|
+
#
|
|
62
|
+
# @param options [Hash] Options hash
|
|
63
|
+
# @option options [Boolean] :sdk_compatible Use SDK mode
|
|
64
|
+
# @option options [Integer] :dict_size Dictionary size
|
|
65
|
+
# @option options [Integer] :level Compression level
|
|
66
|
+
# @return [MatchFinder, Implementations::SevenZip::LZMA::MatchFinder] Match finder instance
|
|
67
|
+
def self.from_options(options = {})
|
|
68
|
+
config = if options[:sdk_compatible]
|
|
69
|
+
MatchFinderConfig.sdk_config(
|
|
70
|
+
dict_size: options[:dict_size] || 65536,
|
|
71
|
+
level: options[:level] || 5,
|
|
72
|
+
)
|
|
73
|
+
else
|
|
74
|
+
MatchFinderConfig.simplified_config(
|
|
75
|
+
dict_size: options[:dict_size] || 65536,
|
|
76
|
+
)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
create(config)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|