omnizip 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +32 -0
- data/.rubocop_todo.yml +754 -0
- data/COPYING +502 -0
- data/Gemfile +17 -0
- data/LICENSE +12 -0
- data/README.adoc +1045 -0
- data/Rakefile +12 -0
- data/benchmark/README.md +260 -0
- data/benchmark/benchmark_suite.rb +125 -0
- data/benchmark/compression_bench.rb +181 -0
- data/benchmark/filter_bench.rb +180 -0
- data/benchmark/models/benchmark_result.rb +59 -0
- data/benchmark/models/comparison_result.rb +69 -0
- data/benchmark/profile_suite.rb +167 -0
- data/benchmark/reporter.rb +150 -0
- data/benchmark/run_benchmarks.rb +66 -0
- data/benchmark/test_data.rb +137 -0
- data/config/formats/rar3_spec.yml +91 -0
- data/config/formats/rar5_spec.yml +102 -0
- data/docs/.github/workflows/docs.yml +142 -0
- data/docs/.gitignore +21 -0
- data/docs/.lychee.toml +67 -0
- data/docs/Gemfile +13 -0
- data/docs/RAR_WRITE_SUPPORT.md +26 -0
- data/docs/README.md +101 -0
- data/docs/_config.yml +112 -0
- data/docs/assets/logo.svg +1 -0
- data/docs/assets/omnizip-logo.pdf +1540 -11
- data/docs/comparison/feature-matrix.adoc +694 -0
- data/docs/comparison/index.adoc +113 -0
- data/docs/comparison/vs-7zip.adoc +309 -0
- data/docs/comparison/vs-peazip.adoc +77 -0
- data/docs/comparison/vs-rubyzip.adoc +342 -0
- data/docs/comparison/vs-winrar.adoc +100 -0
- data/docs/compatibility.adoc +579 -0
- data/docs/concepts/index.adoc +129 -0
- data/docs/developer/architecture.adoc +256 -0
- data/docs/developer/contributing.adoc +158 -0
- data/docs/developer/index.adoc +25 -0
- data/docs/developer/testing.adoc +212 -0
- data/docs/getting-started/basic-usage.adoc +271 -0
- data/docs/getting-started/index.adoc +42 -0
- data/docs/getting-started/installation.adoc +138 -0
- data/docs/getting-started/quick-start.adoc +185 -0
- data/docs/getting-started/your-first-archive.adoc +218 -0
- data/docs/guides/advanced-features/encryption.adoc +300 -0
- data/docs/guides/advanced-features/index.adoc +49 -0
- data/docs/guides/advanced-features/parallel-processing.adoc +246 -0
- data/docs/guides/advanced-features/progress-tracking.adoc +320 -0
- data/docs/guides/advanced-features/streaming.adoc +212 -0
- data/docs/guides/archive-formats/gzip-format.adoc +107 -0
- data/docs/guides/archive-formats/index.adoc +130 -0
- data/docs/guides/archive-formats/rar-format.adoc +104 -0
- data/docs/guides/archive-formats/rar5.adoc +521 -0
- data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
- data/docs/guides/archive-formats/tar-format.adoc +106 -0
- data/docs/guides/archive-formats/xz-format.adoc +118 -0
- data/docs/guides/archive-formats/zip-format.adoc +35 -0
- data/docs/guides/compression-algorithms/bzip2.adoc +113 -0
- data/docs/guides/compression-algorithms/deflate.adoc +319 -0
- data/docs/guides/compression-algorithms/index.adoc +190 -0
- data/docs/guides/compression-algorithms/lzma.adoc +398 -0
- data/docs/guides/compression-algorithms/lzma2.adoc +327 -0
- data/docs/guides/compression-algorithms/ppmd.adoc +316 -0
- data/docs/guides/compression-algorithms/zstandard.adoc +361 -0
- data/docs/guides/creating-archives.adoc +354 -0
- data/docs/guides/extracting-archives.adoc +53 -0
- data/docs/guides/format-conversion.adoc +64 -0
- data/docs/guides/index.adoc +49 -0
- data/docs/guides/migration-rubyzip.adoc +217 -0
- data/docs/guides/parity-archives.adoc +605 -0
- data/docs/guides/performance-tuning.adoc +88 -0
- data/docs/index.adoc +218 -0
- data/docs/lychee.toml +67 -0
- data/docs/reference/api/overview.adoc +188 -0
- data/docs/reference/cli/compress-command.adoc +114 -0
- data/docs/reference/cli/overview.adoc +140 -0
- data/docs/reference/index.adoc +26 -0
- data/docs/resources/faq.adoc +185 -0
- data/docs/resources/quick-reference.adoc +222 -0
- data/docs/troubleshooting/index.adoc +208 -0
- data/examples/api_comparison.rb +205 -0
- data/examples/deflate64_example.rb +96 -0
- data/examples/par2_demo.rb +121 -0
- data/examples/quick_start_native.rb +150 -0
- data/examples/quick_start_rubyzip.rb +115 -0
- data/examples/rubyzip_compatibility_demo.rb +194 -0
- data/exe/omnizip +27 -0
- data/lib/omnizip/algorithm.rb +130 -0
- data/lib/omnizip/algorithm_registry.rb +86 -0
- data/lib/omnizip/algorithms/.keep +0 -0
- data/lib/omnizip/algorithms/bzip2/bwt.rb +225 -0
- data/lib/omnizip/algorithms/bzip2/decoder.rb +193 -0
- data/lib/omnizip/algorithms/bzip2/encoder.rb +237 -0
- data/lib/omnizip/algorithms/bzip2/huffman.rb +206 -0
- data/lib/omnizip/algorithms/bzip2/mtf.rb +101 -0
- data/lib/omnizip/algorithms/bzip2/rle.rb +151 -0
- data/lib/omnizip/algorithms/bzip2.rb +130 -0
- data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
- data/lib/omnizip/algorithms/deflate/decoder.rb +38 -0
- data/lib/omnizip/algorithms/deflate/encoder.rb +46 -0
- data/lib/omnizip/algorithms/deflate.rb +128 -0
- data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
- data/lib/omnizip/algorithms/deflate64/decoder.rb +153 -0
- data/lib/omnizip/algorithms/deflate64/encoder.rb +98 -0
- data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +354 -0
- data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +142 -0
- data/lib/omnizip/algorithms/deflate64.rb +109 -0
- data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
- data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
- data/lib/omnizip/algorithms/lzma/decoder.rb +148 -0
- data/lib/omnizip/algorithms/lzma/dictionary.rb +69 -0
- data/lib/omnizip/algorithms/lzma/distance_coder.rb +415 -0
- data/lib/omnizip/algorithms/lzma/encoder.rb +142 -0
- data/lib/omnizip/algorithms/lzma/length_coder.rb +260 -0
- data/lib/omnizip/algorithms/lzma/literal_decoder.rb +320 -0
- data/lib/omnizip/algorithms/lzma/literal_encoder.rb +210 -0
- data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +341 -0
- data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +192 -0
- data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
- data/lib/omnizip/algorithms/lzma/match.rb +32 -0
- data/lib/omnizip/algorithms/lzma/match_finder.rb +205 -0
- data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
- data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +88 -0
- data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +130 -0
- data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
- data/lib/omnizip/algorithms/lzma/range_coder.rb +85 -0
- data/lib/omnizip/algorithms/lzma/range_decoder.rb +434 -0
- data/lib/omnizip/algorithms/lzma/range_encoder.rb +194 -0
- data/lib/omnizip/algorithms/lzma/state.rb +127 -0
- data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +325 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder.rb +426 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +645 -0
- data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +227 -0
- data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +169 -0
- data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +261 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +331 -0
- data/lib/omnizip/algorithms/lzma/xz_state.rb +116 -0
- data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +2055 -0
- data/lib/omnizip/algorithms/lzma.rb +238 -0
- data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +182 -0
- data/lib/omnizip/algorithms/lzma2/constants.rb +41 -0
- data/lib/omnizip/algorithms/lzma2/encoder.rb +147 -0
- data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +161 -0
- data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
- data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +127 -0
- data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
- data/lib/omnizip/algorithms/lzma2.rb +141 -0
- data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
- data/lib/omnizip/algorithms/ppmd7/context.rb +154 -0
- data/lib/omnizip/algorithms/ppmd7/decoder.rb +126 -0
- data/lib/omnizip/algorithms/ppmd7/encoder.rb +163 -0
- data/lib/omnizip/algorithms/ppmd7/model.rb +248 -0
- data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
- data/lib/omnizip/algorithms/ppmd7.rb +116 -0
- data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
- data/lib/omnizip/algorithms/ppmd8/context.rb +34 -0
- data/lib/omnizip/algorithms/ppmd8/decoder.rb +107 -0
- data/lib/omnizip/algorithms/ppmd8/encoder.rb +138 -0
- data/lib/omnizip/algorithms/ppmd8/model.rb +250 -0
- data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
- data/lib/omnizip/algorithms/ppmd8.rb +82 -0
- data/lib/omnizip/algorithms/ppmd_base.rb +138 -0
- data/lib/omnizip/algorithms/sevenzip_lzma2.rb +123 -0
- data/lib/omnizip/algorithms/xz_lzma2.rb +118 -0
- data/lib/omnizip/algorithms/zstandard/constants.rb +25 -0
- data/lib/omnizip/algorithms/zstandard/decoder.rb +46 -0
- data/lib/omnizip/algorithms/zstandard/encoder.rb +51 -0
- data/lib/omnizip/algorithms/zstandard.rb +138 -0
- data/lib/omnizip/buffer/memory_archive.rb +251 -0
- data/lib/omnizip/buffer/memory_extractor.rb +224 -0
- data/lib/omnizip/buffer.rb +176 -0
- data/lib/omnizip/checksum_registry.rb +114 -0
- data/lib/omnizip/checksums/crc32.rb +100 -0
- data/lib/omnizip/checksums/crc64.rb +101 -0
- data/lib/omnizip/checksums/crc_base.rb +158 -0
- data/lib/omnizip/checksums/verifier.rb +131 -0
- data/lib/omnizip/chunked/memory_manager.rb +194 -0
- data/lib/omnizip/chunked/reader.rb +78 -0
- data/lib/omnizip/chunked/writer.rb +120 -0
- data/lib/omnizip/chunked.rb +129 -0
- data/lib/omnizip/cli/output_formatter.rb +104 -0
- data/lib/omnizip/cli.rb +572 -0
- data/lib/omnizip/commands/.keep +0 -0
- data/lib/omnizip/commands/archive_create_command.rb +427 -0
- data/lib/omnizip/commands/archive_extract_command.rb +272 -0
- data/lib/omnizip/commands/archive_list_command.rb +218 -0
- data/lib/omnizip/commands/archive_repair_command.rb +131 -0
- data/lib/omnizip/commands/archive_verify_command.rb +117 -0
- data/lib/omnizip/commands/compress_command.rb +117 -0
- data/lib/omnizip/commands/decompress_command.rb +120 -0
- data/lib/omnizip/commands/list_command.rb +53 -0
- data/lib/omnizip/commands/metadata_command.rb +153 -0
- data/lib/omnizip/commands/parity_create_command.rb +122 -0
- data/lib/omnizip/commands/parity_repair_command.rb +122 -0
- data/lib/omnizip/commands/parity_verify_command.rb +124 -0
- data/lib/omnizip/commands/profile_list_command.rb +56 -0
- data/lib/omnizip/commands/profile_show_command.rb +44 -0
- data/lib/omnizip/convenience.rb +359 -0
- data/lib/omnizip/converter/conversion_registry.rb +49 -0
- data/lib/omnizip/converter/conversion_strategy.rb +121 -0
- data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +97 -0
- data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +112 -0
- data/lib/omnizip/converter.rb +105 -0
- data/lib/omnizip/crypto/aes256/cipher.rb +100 -0
- data/lib/omnizip/crypto/aes256/constants.rb +28 -0
- data/lib/omnizip/crypto/aes256/key_derivation.rb +101 -0
- data/lib/omnizip/crypto/aes256.rb +102 -0
- data/lib/omnizip/error.rb +106 -0
- data/lib/omnizip/eta/exponential_smoothing_estimator.rb +98 -0
- data/lib/omnizip/eta/moving_average_estimator.rb +99 -0
- data/lib/omnizip/eta/rate_calculator.rb +104 -0
- data/lib/omnizip/eta/sample_history.rb +143 -0
- data/lib/omnizip/eta/time_estimator.rb +106 -0
- data/lib/omnizip/eta.rb +63 -0
- data/lib/omnizip/extraction/filter_chain.rb +177 -0
- data/lib/omnizip/extraction/glob_pattern.rb +140 -0
- data/lib/omnizip/extraction/pattern_matcher.rb +70 -0
- data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
- data/lib/omnizip/extraction/regex_pattern.rb +50 -0
- data/lib/omnizip/extraction/selective_extractor.rb +240 -0
- data/lib/omnizip/extraction.rb +111 -0
- data/lib/omnizip/file_type/mime_classifier.rb +144 -0
- data/lib/omnizip/file_type.rb +113 -0
- data/lib/omnizip/filter.rb +139 -0
- data/lib/omnizip/filter_pipeline.rb +108 -0
- data/lib/omnizip/filter_registry.rb +166 -0
- data/lib/omnizip/filters/bcj.rb +279 -0
- data/lib/omnizip/filters/bcj2/constants.rb +53 -0
- data/lib/omnizip/filters/bcj2/decoder.rb +200 -0
- data/lib/omnizip/filters/bcj2/encoder.rb +61 -0
- data/lib/omnizip/filters/bcj2/stream_data.rb +93 -0
- data/lib/omnizip/filters/bcj2.rb +99 -0
- data/lib/omnizip/filters/bcj_arm.rb +176 -0
- data/lib/omnizip/filters/bcj_arm64.rb +244 -0
- data/lib/omnizip/filters/bcj_ia64.rb +196 -0
- data/lib/omnizip/filters/bcj_ppc.rb +190 -0
- data/lib/omnizip/filters/bcj_sparc.rb +176 -0
- data/lib/omnizip/filters/bcj_x86.rb +193 -0
- data/lib/omnizip/filters/delta.rb +196 -0
- data/lib/omnizip/filters/filter_base.rb +72 -0
- data/lib/omnizip/filters/registry.rb +123 -0
- data/lib/omnizip/filters/xz_delta.rb +258 -0
- data/lib/omnizip/format_detector.rb +162 -0
- data/lib/omnizip/format_registry.rb +59 -0
- data/lib/omnizip/formats/.keep +0 -0
- data/lib/omnizip/formats/bzip2_file.rb +172 -0
- data/lib/omnizip/formats/cpio/constants.rb +55 -0
- data/lib/omnizip/formats/cpio/entry.rb +385 -0
- data/lib/omnizip/formats/cpio/reader.rb +196 -0
- data/lib/omnizip/formats/cpio/writer.rb +234 -0
- data/lib/omnizip/formats/cpio.rb +140 -0
- data/lib/omnizip/formats/format_spec_loader.rb +230 -0
- data/lib/omnizip/formats/gzip.rb +238 -0
- data/lib/omnizip/formats/iso/directory_builder.rb +297 -0
- data/lib/omnizip/formats/iso/directory_record.rb +152 -0
- data/lib/omnizip/formats/iso/joliet.rb +204 -0
- data/lib/omnizip/formats/iso/path_table.rb +125 -0
- data/lib/omnizip/formats/iso/reader.rb +197 -0
- data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
- data/lib/omnizip/formats/iso/volume_builder.rb +320 -0
- data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
- data/lib/omnizip/formats/iso/writer.rb +530 -0
- data/lib/omnizip/formats/iso.rb +140 -0
- data/lib/omnizip/formats/lzip.rb +175 -0
- data/lib/omnizip/formats/lzma_alone.rb +171 -0
- data/lib/omnizip/formats/rar/archive_repairer.rb +243 -0
- data/lib/omnizip/formats/rar/archive_verifier.rb +195 -0
- data/lib/omnizip/formats/rar/block_parser.rb +243 -0
- data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
- data/lib/omnizip/formats/rar/compression/dispatcher.rb +217 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +216 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +158 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
- data/lib/omnizip/formats/rar/compression/ppmd/context.rb +105 -0
- data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +219 -0
- data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +262 -0
- data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
- data/lib/omnizip/formats/rar/constants.rb +82 -0
- data/lib/omnizip/formats/rar/decompressor.rb +238 -0
- data/lib/omnizip/formats/rar/external_writer.rb +312 -0
- data/lib/omnizip/formats/rar/header.rb +192 -0
- data/lib/omnizip/formats/rar/license_validator.rb +109 -0
- data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
- data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
- data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
- data/lib/omnizip/formats/rar/parity_handler.rb +292 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +202 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +578 -0
- data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
- data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
- data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +97 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +166 -0
- data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
- data/lib/omnizip/formats/rar/rar5/header.rb +187 -0
- data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +264 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +194 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +109 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +142 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
- data/lib/omnizip/formats/rar/rar5/vint.rb +65 -0
- data/lib/omnizip/formats/rar/rar5/writer.rb +466 -0
- data/lib/omnizip/formats/rar/rar_format_base.rb +241 -0
- data/lib/omnizip/formats/rar/reader.rb +366 -0
- data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
- data/lib/omnizip/formats/rar/volume_manager.rb +168 -0
- data/lib/omnizip/formats/rar/writer.rb +431 -0
- data/lib/omnizip/formats/rar.rb +205 -0
- data/lib/omnizip/formats/rar3/compressor.rb +73 -0
- data/lib/omnizip/formats/rar3/decompressor.rb +66 -0
- data/lib/omnizip/formats/rar3/reader.rb +386 -0
- data/lib/omnizip/formats/rar3/writer.rb +219 -0
- data/lib/omnizip/formats/rar5/compressor.rb +73 -0
- data/lib/omnizip/formats/rar5/decompressor.rb +66 -0
- data/lib/omnizip/formats/rar5/reader.rb +342 -0
- data/lib/omnizip/formats/rar5/writer.rb +214 -0
- data/lib/omnizip/formats/seven_zip/coder_chain.rb +150 -0
- data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
- data/lib/omnizip/formats/seven_zip/encoded_header.rb +114 -0
- data/lib/omnizip/formats/seven_zip/encrypted_header.rb +142 -0
- data/lib/omnizip/formats/seven_zip/file_collector.rb +144 -0
- data/lib/omnizip/formats/seven_zip/header.rb +106 -0
- data/lib/omnizip/formats/seven_zip/header_encryptor.rb +134 -0
- data/lib/omnizip/formats/seven_zip/header_writer.rb +466 -0
- data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
- data/lib/omnizip/formats/seven_zip/models/file_entry.rb +58 -0
- data/lib/omnizip/formats/seven_zip/models/folder.rb +69 -0
- data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
- data/lib/omnizip/formats/seven_zip/parser.rb +660 -0
- data/lib/omnizip/formats/seven_zip/reader.rb +458 -0
- data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +632 -0
- data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +315 -0
- data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
- data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +162 -0
- data/lib/omnizip/formats/seven_zip/writer.rb +740 -0
- data/lib/omnizip/formats/seven_zip.rb +93 -0
- data/lib/omnizip/formats/tar/constants.rb +73 -0
- data/lib/omnizip/formats/tar/entry.rb +94 -0
- data/lib/omnizip/formats/tar/header.rb +168 -0
- data/lib/omnizip/formats/tar/reader.rb +121 -0
- data/lib/omnizip/formats/tar/writer.rb +216 -0
- data/lib/omnizip/formats/tar.rb +84 -0
- data/lib/omnizip/formats/xz/reader.rb +116 -0
- data/lib/omnizip/formats/xz.rb +237 -0
- data/lib/omnizip/formats/xz_impl/block_decoder.rb +754 -0
- data/lib/omnizip/formats/xz_impl/block_encoder.rb +306 -0
- data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
- data/lib/omnizip/formats/xz_impl/block_header_parser.rb +186 -0
- data/lib/omnizip/formats/xz_impl/constants.rb +49 -0
- data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
- data/lib/omnizip/formats/xz_impl/index_encoder.rb +122 -0
- data/lib/omnizip/formats/xz_impl/stream_decoder.rb +468 -0
- data/lib/omnizip/formats/xz_impl/stream_encoder.rb +99 -0
- data/lib/omnizip/formats/xz_impl/stream_footer.rb +81 -0
- data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +117 -0
- data/lib/omnizip/formats/xz_impl/stream_header.rb +55 -0
- data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +108 -0
- data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
- data/lib/omnizip/formats/xz_impl/writer.rb +421 -0
- data/lib/omnizip/formats/zip/central_directory_header.rb +195 -0
- data/lib/omnizip/formats/zip/constants.rb +69 -0
- data/lib/omnizip/formats/zip/end_of_central_directory.rb +133 -0
- data/lib/omnizip/formats/zip/local_file_header.rb +138 -0
- data/lib/omnizip/formats/zip/reader.rb +250 -0
- data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
- data/lib/omnizip/formats/zip/writer.rb +375 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +104 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +66 -0
- data/lib/omnizip/formats/zip/zip64_extra_field.rb +114 -0
- data/lib/omnizip/formats/zip.rb +50 -0
- data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
- data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
- data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
- data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
- data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
- data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +421 -0
- data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +465 -0
- data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +288 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +200 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +197 -0
- data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +141 -0
- data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +519 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +723 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +750 -0
- data/lib/omnizip/io/buffered_input.rb +146 -0
- data/lib/omnizip/io/buffered_output.rb +105 -0
- data/lib/omnizip/io/stream_manager.rb +115 -0
- data/lib/omnizip/link_handler/hard_link.rb +79 -0
- data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
- data/lib/omnizip/link_handler.rb +124 -0
- data/lib/omnizip/metadata/archive_metadata.rb +114 -0
- data/lib/omnizip/metadata/entry_metadata.rb +146 -0
- data/lib/omnizip/metadata/metadata_editor.rb +171 -0
- data/lib/omnizip/metadata/metadata_registry.rb +64 -0
- data/lib/omnizip/metadata/metadata_validator.rb +99 -0
- data/lib/omnizip/metadata.rb +57 -0
- data/lib/omnizip/models/.keep +0 -0
- data/lib/omnizip/models/algorithm_metadata.rb +73 -0
- data/lib/omnizip/models/compression_options.rb +71 -0
- data/lib/omnizip/models/conversion_options.rb +87 -0
- data/lib/omnizip/models/conversion_result.rb +135 -0
- data/lib/omnizip/models/eta_result.rb +46 -0
- data/lib/omnizip/models/extraction_rule.rb +115 -0
- data/lib/omnizip/models/filter_chain.rb +144 -0
- data/lib/omnizip/models/filter_config.rb +183 -0
- data/lib/omnizip/models/match_result.rb +124 -0
- data/lib/omnizip/models/optimization_suggestion.rb +91 -0
- data/lib/omnizip/models/parallel_options.rb +104 -0
- data/lib/omnizip/models/performance_result.rb +79 -0
- data/lib/omnizip/models/profile_report.rb +82 -0
- data/lib/omnizip/models/progress_options.rb +38 -0
- data/lib/omnizip/models/split_options.rb +116 -0
- data/lib/omnizip/optimization_registry.rb +81 -0
- data/lib/omnizip/parallel/job_queue.rb +209 -0
- data/lib/omnizip/parallel/job_scheduler.rb +203 -0
- data/lib/omnizip/parallel/parallel_compressor.rb +347 -0
- data/lib/omnizip/parallel/parallel_extractor.rb +329 -0
- data/lib/omnizip/parallel/worker_pool.rb +223 -0
- data/lib/omnizip/parallel.rb +149 -0
- data/lib/omnizip/parity/chunked_block_processor.rb +196 -0
- data/lib/omnizip/parity/galois16.rb +145 -0
- data/lib/omnizip/parity/models/creator_packet.rb +73 -0
- data/lib/omnizip/parity/models/file_description_packet.rb +133 -0
- data/lib/omnizip/parity/models/ifsc_packet.rb +123 -0
- data/lib/omnizip/parity/models/main_packet.rb +128 -0
- data/lib/omnizip/parity/models/packet.rb +156 -0
- data/lib/omnizip/parity/models/packet_registry.rb +109 -0
- data/lib/omnizip/parity/models/recovery_slice_packet.rb +78 -0
- data/lib/omnizip/parity/par2_creator.rb +531 -0
- data/lib/omnizip/parity/par2_repairer.rb +407 -0
- data/lib/omnizip/parity/par2_verifier.rb +364 -0
- data/lib/omnizip/parity/par2cmdline_algorithm.rb +110 -0
- data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
- data/lib/omnizip/parity/reed_solomon_decoder.rb +266 -0
- data/lib/omnizip/parity/reed_solomon_encoder.rb +111 -0
- data/lib/omnizip/parity/reed_solomon_matrix.rb +342 -0
- data/lib/omnizip/parity.rb +186 -0
- data/lib/omnizip/password/encryption_registry.rb +65 -0
- data/lib/omnizip/password/encryption_strategy.rb +96 -0
- data/lib/omnizip/password/password_validator.rb +129 -0
- data/lib/omnizip/password/winzip_aes_strategy.rb +192 -0
- data/lib/omnizip/password/zip_crypto_strategy.rb +141 -0
- data/lib/omnizip/password.rb +87 -0
- data/lib/omnizip/pipe/stream_compressor.rb +124 -0
- data/lib/omnizip/pipe/stream_decompressor.rb +174 -0
- data/lib/omnizip/pipe.rb +121 -0
- data/lib/omnizip/platform/ntfs_streams.rb +201 -0
- data/lib/omnizip/platform.rb +189 -0
- data/lib/omnizip/profile/archive_profile.rb +39 -0
- data/lib/omnizip/profile/balanced_profile.rb +33 -0
- data/lib/omnizip/profile/binary_profile.rb +36 -0
- data/lib/omnizip/profile/compression_profile.rb +158 -0
- data/lib/omnizip/profile/custom_profile.rb +157 -0
- data/lib/omnizip/profile/fast_profile.rb +33 -0
- data/lib/omnizip/profile/maximum_profile.rb +33 -0
- data/lib/omnizip/profile/profile_detector.rb +110 -0
- data/lib/omnizip/profile/profile_registry.rb +161 -0
- data/lib/omnizip/profile/text_profile.rb +36 -0
- data/lib/omnizip/profile.rb +190 -0
- data/lib/omnizip/profiler/memory_profiler.rb +66 -0
- data/lib/omnizip/profiler/method_profiler.rb +49 -0
- data/lib/omnizip/profiler/report_generator.rb +169 -0
- data/lib/omnizip/profiler.rb +204 -0
- data/lib/omnizip/progress/callback_reporter.rb +36 -0
- data/lib/omnizip/progress/console_reporter.rb +62 -0
- data/lib/omnizip/progress/log_reporter.rb +91 -0
- data/lib/omnizip/progress/operation_progress.rb +118 -0
- data/lib/omnizip/progress/progress_bar.rb +156 -0
- data/lib/omnizip/progress/progress_reporter.rb +40 -0
- data/lib/omnizip/progress/progress_tracker.rb +190 -0
- data/lib/omnizip/progress/silent_reporter.rb +24 -0
- data/lib/omnizip/progress.rb +127 -0
- data/lib/omnizip/rubyzip_compat.rb +63 -0
- data/lib/omnizip/temp/safe_extract.rb +168 -0
- data/lib/omnizip/temp/temp_file.rb +124 -0
- data/lib/omnizip/temp/temp_file_pool.rb +109 -0
- data/lib/omnizip/temp.rb +181 -0
- data/lib/omnizip/version.rb +5 -0
- data/lib/omnizip/zip/entry.rb +156 -0
- data/lib/omnizip/zip/file.rb +485 -0
- data/lib/omnizip/zip/input_stream.rb +273 -0
- data/lib/omnizip/zip/output_stream.rb +324 -0
- data/lib/omnizip.rb +156 -0
- data/readme-docs/advanced-features.adoc +515 -0
- data/readme-docs/api-usage.adoc +444 -0
- data/readme-docs/architecture.adoc +449 -0
- data/readme-docs/archive-formats.adoc +479 -0
- data/readme-docs/cli-usage.adoc +222 -0
- data/readme-docs/compression-algorithms.adoc +442 -0
- data/readme-docs/compression-profiles.adoc +247 -0
- data/readme-docs/encryption-checksums.adoc +328 -0
- data/readme-docs/format-converter.adoc +325 -0
- data/readme-docs/installation.adoc +228 -0
- data/readme-docs/par2-archives.adoc +608 -0
- data/readme-docs/performance-profiler.adoc +389 -0
- data/readme-docs/preprocessing-filters.adoc +280 -0
- data/xz-file-format-1.2.1.txt +1174 -0
- metadata +617 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2024 Ribose Inc.
|
|
5
|
+
#
|
|
6
|
+
# This file is part of Omnizip.
|
|
7
|
+
#
|
|
8
|
+
# Omnizip is a pure Ruby port of 7-Zip compression algorithms.
|
|
9
|
+
# Based on the 7-Zip LZMA SDK by Igor Pavlov.
|
|
10
|
+
#
|
|
11
|
+
# This library is free software; you can redistribute it and/or
|
|
12
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
# License as published by the Free Software Foundation; either
|
|
14
|
+
# version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
#
|
|
16
|
+
# See the COPYING file for the complete text of the license.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
require "json"
|
|
20
|
+
|
|
21
|
+
module Omnizip
|
|
22
|
+
module Models
|
|
23
|
+
# Model representing metadata about a compression algorithm.
|
|
24
|
+
#
|
|
25
|
+
# This class encapsulates information about a compression algorithm,
|
|
26
|
+
# including its name, description, version, and capabilities.
|
|
27
|
+
class AlgorithmMetadata
|
|
28
|
+
attr_accessor :name, :description, :version, :author,
|
|
29
|
+
:max_compression_level, :min_compression_level,
|
|
30
|
+
:default_compression_level, :supports_streaming,
|
|
31
|
+
:supports_multithreading
|
|
32
|
+
|
|
33
|
+
def initialize(**kwargs)
|
|
34
|
+
@supports_streaming = false
|
|
35
|
+
@supports_multithreading = false
|
|
36
|
+
|
|
37
|
+
kwargs.each do |key, value|
|
|
38
|
+
instance_variable_set("@#{key}", value)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def to_h
|
|
43
|
+
{
|
|
44
|
+
name: @name,
|
|
45
|
+
description: @description,
|
|
46
|
+
version: @version,
|
|
47
|
+
author: @author,
|
|
48
|
+
max_compression_level: @max_compression_level,
|
|
49
|
+
min_compression_level: @min_compression_level,
|
|
50
|
+
default_compression_level: @default_compression_level,
|
|
51
|
+
supports_streaming: @supports_streaming,
|
|
52
|
+
supports_multithreading: @supports_multithreading,
|
|
53
|
+
}.compact
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Serialize to JSON
|
|
57
|
+
#
|
|
58
|
+
# @return [String] JSON representation
|
|
59
|
+
def to_json(*args)
|
|
60
|
+
to_h.to_json(*args)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Deserialize from JSON
|
|
64
|
+
#
|
|
65
|
+
# @param json [String] JSON string
|
|
66
|
+
# @return [AlgorithmMetadata] Deserialized instance
|
|
67
|
+
def self.from_json(json)
|
|
68
|
+
data = JSON.parse(json)
|
|
69
|
+
new(**data.transform_keys(&:to_sym))
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2024 Ribose Inc.
|
|
5
|
+
#
|
|
6
|
+
# This file is part of Omnizip.
|
|
7
|
+
#
|
|
8
|
+
# Omnizip is a pure Ruby port of 7-Zip compression algorithms.
|
|
9
|
+
# Based on the 7-Zip LZMA SDK by Igor Pavlov.
|
|
10
|
+
#
|
|
11
|
+
# This library is free software; you can redistribute it and/or
|
|
12
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
# License as published by the Free Software Foundation; either
|
|
14
|
+
# version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
#
|
|
16
|
+
# See the COPYING file for the complete text of the license.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
require "json"
|
|
20
|
+
|
|
21
|
+
module Omnizip
|
|
22
|
+
module Models
|
|
23
|
+
# Model representing compression operation options.
|
|
24
|
+
#
|
|
25
|
+
# This class encapsulates configuration options for compression
|
|
26
|
+
# operations, including compression level, threading, and buffer sizes.
|
|
27
|
+
class CompressionOptions
|
|
28
|
+
attr_accessor :level, :dictionary_size, :num_fast_bytes, :match_finder,
|
|
29
|
+
:num_threads, :solid, :buffer_size
|
|
30
|
+
|
|
31
|
+
def initialize(**kwargs)
|
|
32
|
+
@level = 5
|
|
33
|
+
@num_threads = 1
|
|
34
|
+
@solid = false
|
|
35
|
+
@buffer_size = 65_536
|
|
36
|
+
|
|
37
|
+
kwargs.each do |key, value|
|
|
38
|
+
instance_variable_set("@#{key}", value)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def to_h
|
|
43
|
+
{
|
|
44
|
+
level: @level,
|
|
45
|
+
dictionary_size: @dictionary_size,
|
|
46
|
+
num_fast_bytes: @num_fast_bytes,
|
|
47
|
+
match_finder: @match_finder,
|
|
48
|
+
num_threads: @num_threads,
|
|
49
|
+
solid: @solid,
|
|
50
|
+
buffer_size: @buffer_size,
|
|
51
|
+
}.compact
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Serialize to JSON
|
|
55
|
+
#
|
|
56
|
+
# @return [String] JSON representation
|
|
57
|
+
def to_json(*args)
|
|
58
|
+
to_h.to_json(*args)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Deserialize from JSON
|
|
62
|
+
#
|
|
63
|
+
# @param json [String] JSON string
|
|
64
|
+
# @return [CompressionOptions] Deserialized instance
|
|
65
|
+
def self.from_json(json)
|
|
66
|
+
data = JSON.parse(json)
|
|
67
|
+
new(**data.transform_keys(&:to_sym))
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Models
|
|
5
|
+
# Model for format conversion options
|
|
6
|
+
class ConversionOptions
|
|
7
|
+
attr_accessor :source_format, :target_format, :compression,
|
|
8
|
+
:compression_level, :filter, :preserve_metadata,
|
|
9
|
+
:temp_directory, :solid, :delete_source
|
|
10
|
+
|
|
11
|
+
# Initialize conversion options
|
|
12
|
+
# @param source_format [Symbol, nil] Source format (auto-detect if nil)
|
|
13
|
+
# @param target_format [Symbol] Target format
|
|
14
|
+
# @param compression [Symbol, nil] Compression algorithm
|
|
15
|
+
# @param compression_level [Integer] Compression level (1-9)
|
|
16
|
+
# @param filter [Symbol, nil] Filter to apply
|
|
17
|
+
# @param preserve_metadata [Boolean] Preserve metadata
|
|
18
|
+
# @param temp_directory [String, nil] Temporary directory
|
|
19
|
+
# @param solid [Boolean] Use solid compression (7z only)
|
|
20
|
+
# @param delete_source [Boolean] Delete source after conversion
|
|
21
|
+
def initialize(
|
|
22
|
+
source_format: nil,
|
|
23
|
+
target_format: :seven_zip,
|
|
24
|
+
compression: nil,
|
|
25
|
+
compression_level: 5,
|
|
26
|
+
filter: nil,
|
|
27
|
+
preserve_metadata: true,
|
|
28
|
+
temp_directory: nil,
|
|
29
|
+
solid: true,
|
|
30
|
+
delete_source: false
|
|
31
|
+
)
|
|
32
|
+
@source_format = source_format
|
|
33
|
+
@target_format = target_format
|
|
34
|
+
@compression = compression
|
|
35
|
+
@compression_level = compression_level
|
|
36
|
+
@filter = filter
|
|
37
|
+
@preserve_metadata = preserve_metadata
|
|
38
|
+
@temp_directory = temp_directory
|
|
39
|
+
@solid = solid
|
|
40
|
+
@delete_source = delete_source
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Convert to hash
|
|
44
|
+
# @return [Hash] Options as hash
|
|
45
|
+
def to_h
|
|
46
|
+
{
|
|
47
|
+
source_format: source_format,
|
|
48
|
+
target_format: target_format,
|
|
49
|
+
compression: compression,
|
|
50
|
+
compression_level: compression_level,
|
|
51
|
+
filter: filter,
|
|
52
|
+
preserve_metadata: preserve_metadata,
|
|
53
|
+
temp_directory: temp_directory,
|
|
54
|
+
solid: solid,
|
|
55
|
+
delete_source: delete_source,
|
|
56
|
+
}
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Validate options
|
|
60
|
+
# @raise [ArgumentError] If options are invalid
|
|
61
|
+
def validate
|
|
62
|
+
validate_format(target_format, "target")
|
|
63
|
+
validate_format(source_format, "source") if source_format
|
|
64
|
+
validate_compression_level
|
|
65
|
+
|
|
66
|
+
true
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
def validate_format(format, type)
|
|
72
|
+
valid_formats = %i[zip seven_zip 7z]
|
|
73
|
+
return if valid_formats.include?(format)
|
|
74
|
+
|
|
75
|
+
raise ArgumentError, "Invalid #{type} format: #{format}. " \
|
|
76
|
+
"Valid formats: #{valid_formats.join(', ')}"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def validate_compression_level
|
|
80
|
+
return if (1..9).cover?(compression_level)
|
|
81
|
+
|
|
82
|
+
raise ArgumentError,
|
|
83
|
+
"Invalid compression level: #{compression_level}. Must be 1-9"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Models
|
|
5
|
+
# Model for format conversion results
|
|
6
|
+
class ConversionResult
|
|
7
|
+
attr_reader :source_path, :target_path, :source_format, :target_format,
|
|
8
|
+
:source_size, :target_size, :duration, :entry_count,
|
|
9
|
+
:compression_ratio, :warnings
|
|
10
|
+
|
|
11
|
+
# Initialize conversion result
|
|
12
|
+
# @param source_path [String] Source file path
|
|
13
|
+
# @param target_path [String] Target file path
|
|
14
|
+
# @param source_format [Symbol] Source format
|
|
15
|
+
# @param target_format [Symbol] Target format
|
|
16
|
+
# @param source_size [Integer] Source file size in bytes
|
|
17
|
+
# @param target_size [Integer] Target file size in bytes
|
|
18
|
+
# @param duration [Float] Conversion duration in seconds
|
|
19
|
+
# @param entry_count [Integer] Number of entries converted
|
|
20
|
+
# @param warnings [Array<String>] Conversion warnings
|
|
21
|
+
def initialize(
|
|
22
|
+
source_path:,
|
|
23
|
+
target_path:,
|
|
24
|
+
source_format:,
|
|
25
|
+
target_format:,
|
|
26
|
+
source_size:,
|
|
27
|
+
target_size:,
|
|
28
|
+
duration:,
|
|
29
|
+
entry_count:,
|
|
30
|
+
warnings: []
|
|
31
|
+
)
|
|
32
|
+
@source_path = source_path
|
|
33
|
+
@target_path = target_path
|
|
34
|
+
@source_format = source_format
|
|
35
|
+
@target_format = target_format
|
|
36
|
+
@source_size = source_size
|
|
37
|
+
@target_size = target_size
|
|
38
|
+
@duration = duration
|
|
39
|
+
@entry_count = entry_count
|
|
40
|
+
@warnings = warnings
|
|
41
|
+
@compression_ratio = calculate_compression_ratio
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Get size reduction percentage
|
|
45
|
+
# @return [Float] Size reduction as percentage
|
|
46
|
+
def size_reduction
|
|
47
|
+
return 0.0 if source_size.zero?
|
|
48
|
+
|
|
49
|
+
((source_size - target_size).to_f / source_size * 100).round(2)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Get size ratio
|
|
53
|
+
# @return [Float] Target size as percentage of source size
|
|
54
|
+
def size_ratio
|
|
55
|
+
return 0.0 if source_size.zero?
|
|
56
|
+
|
|
57
|
+
(target_size.to_f / source_size * 100).round(2)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Check if conversion resulted in smaller file
|
|
61
|
+
# @return [Boolean] True if target is smaller
|
|
62
|
+
def smaller?
|
|
63
|
+
target_size < source_size
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Check if conversion resulted in larger file
|
|
67
|
+
# @return [Boolean] True if target is larger
|
|
68
|
+
def larger?
|
|
69
|
+
target_size > source_size
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Check if there were warnings
|
|
73
|
+
# @return [Boolean] True if warnings exist
|
|
74
|
+
def warnings?
|
|
75
|
+
!warnings.empty?
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Get average processing speed
|
|
79
|
+
# @return [Float] MB/s processing speed
|
|
80
|
+
def processing_speed
|
|
81
|
+
return 0.0 if duration.zero? || source_size.zero?
|
|
82
|
+
|
|
83
|
+
speed = source_size / duration / 1_048_576.0
|
|
84
|
+
rounded = speed.round(2)
|
|
85
|
+
# Return actual speed if rounding would give 0 but speed is positive
|
|
86
|
+
rounded.zero? && speed.positive? ? speed : rounded
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Convert to hash
|
|
90
|
+
# @return [Hash] Result as hash
|
|
91
|
+
def to_h
|
|
92
|
+
{
|
|
93
|
+
source_path: source_path,
|
|
94
|
+
target_path: target_path,
|
|
95
|
+
source_format: source_format,
|
|
96
|
+
target_format: target_format,
|
|
97
|
+
source_size: source_size,
|
|
98
|
+
target_size: target_size,
|
|
99
|
+
size_reduction: size_reduction,
|
|
100
|
+
size_ratio: size_ratio,
|
|
101
|
+
duration: duration,
|
|
102
|
+
entry_count: entry_count,
|
|
103
|
+
processing_speed: processing_speed,
|
|
104
|
+
warnings: warnings,
|
|
105
|
+
}
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Format as human-readable string
|
|
109
|
+
# @return [String] Formatted result
|
|
110
|
+
def to_s
|
|
111
|
+
"Converted #{source_path} (#{format_size(source_size)}) to " \
|
|
112
|
+
"#{target_path} (#{format_size(target_size)}) in #{duration.round(2)}s. " \
|
|
113
|
+
"#{size_reduction.positive? ? "Saved #{size_reduction.to_i}%" : "Increased #{(-size_reduction).to_i}%"}"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
private
|
|
117
|
+
|
|
118
|
+
def calculate_compression_ratio
|
|
119
|
+
return 0.0 if source_size.zero?
|
|
120
|
+
|
|
121
|
+
(1.0 - (target_size.to_f / source_size)).round(4)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def format_size(bytes)
|
|
125
|
+
return "0 B" if bytes.zero?
|
|
126
|
+
|
|
127
|
+
units = %w[B KB MB GB TB]
|
|
128
|
+
exp = (Math.log(bytes) / Math.log(1024)).to_i
|
|
129
|
+
exp = [exp, units.size - 1].min
|
|
130
|
+
|
|
131
|
+
"%.1f %s" % [bytes.to_f / (1024**exp), units[exp]]
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
module Omnizip
|
|
8
|
+
module Models
|
|
9
|
+
# Model representing an ETA (Estimated Time to Arrival) calculation result.
|
|
10
|
+
#
|
|
11
|
+
# This class encapsulates the result of ETA calculations, including
|
|
12
|
+
# seconds remaining, formatted time string, and confidence interval.
|
|
13
|
+
class ETAResult
|
|
14
|
+
attr_accessor :seconds_remaining, :formatted, :confidence_lower,
|
|
15
|
+
:confidence_upper
|
|
16
|
+
|
|
17
|
+
# Get confidence interval as array
|
|
18
|
+
#
|
|
19
|
+
# @return [Array<Float>] [lower, upper] bounds in seconds
|
|
20
|
+
def confidence_interval
|
|
21
|
+
[confidence_lower, confidence_upper]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Check if ETA is reliable (confidence interval is reasonable)
|
|
25
|
+
#
|
|
26
|
+
# @return [Boolean] true if confidence interval is within 50% of estimate
|
|
27
|
+
def reliable?
|
|
28
|
+
unless seconds_remaining && confidence_lower && confidence_upper
|
|
29
|
+
return false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
range = confidence_upper - confidence_lower
|
|
33
|
+
range < (seconds_remaining * 0.5)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def to_h
|
|
37
|
+
{
|
|
38
|
+
seconds_remaining: @seconds_remaining,
|
|
39
|
+
formatted: @formatted,
|
|
40
|
+
confidence_lower: @confidence_lower,
|
|
41
|
+
confidence_upper: @confidence_upper,
|
|
42
|
+
}.compact
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Models
|
|
5
|
+
# Represents a rule for extracting files from an archive
|
|
6
|
+
#
|
|
7
|
+
# Defines what files to extract and how to extract them using
|
|
8
|
+
# patterns, predicates, and options.
|
|
9
|
+
class ExtractionRule
|
|
10
|
+
attr_reader :patterns, :predicates, :options
|
|
11
|
+
|
|
12
|
+
# Initialize a new extraction rule
|
|
13
|
+
#
|
|
14
|
+
# @param patterns [Array<String, Regexp>] Patterns to match
|
|
15
|
+
# @param predicates [Array<Proc>] Custom predicates for matching
|
|
16
|
+
# @param options [Hash] Extraction options
|
|
17
|
+
# @option options [Boolean] :preserve_paths Keep directory structure
|
|
18
|
+
# @option options [Boolean] :flatten Extract all to destination root
|
|
19
|
+
# @option options [Boolean] :overwrite Overwrite existing files
|
|
20
|
+
# @option options [String] :dest_prefix Prefix for destination paths
|
|
21
|
+
def initialize(patterns: [], predicates: [], options: {})
|
|
22
|
+
@patterns = Array(patterns)
|
|
23
|
+
@predicates = Array(predicates)
|
|
24
|
+
@options = default_options.merge(options)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Add a pattern to the rule
|
|
28
|
+
#
|
|
29
|
+
# @param pattern [String, Regexp] Pattern to add
|
|
30
|
+
# @return [self]
|
|
31
|
+
def add_pattern(pattern)
|
|
32
|
+
@patterns << pattern
|
|
33
|
+
self
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Add a predicate to the rule
|
|
37
|
+
#
|
|
38
|
+
# @param predicate [Proc] Predicate block to add
|
|
39
|
+
# @return [self]
|
|
40
|
+
def add_predicate(&predicate)
|
|
41
|
+
@predicates << predicate if predicate
|
|
42
|
+
self
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Check if any patterns are defined
|
|
46
|
+
#
|
|
47
|
+
# @return [Boolean]
|
|
48
|
+
def patterns?
|
|
49
|
+
!@patterns.empty?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Check if any predicates are defined
|
|
53
|
+
#
|
|
54
|
+
# @return [Boolean]
|
|
55
|
+
def predicates?
|
|
56
|
+
!@predicates.empty?
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Check if the rule has any conditions
|
|
60
|
+
#
|
|
61
|
+
# @return [Boolean]
|
|
62
|
+
def conditions?
|
|
63
|
+
patterns? || predicates?
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Get option value
|
|
67
|
+
#
|
|
68
|
+
# @param key [Symbol] Option key
|
|
69
|
+
# @return [Object] Option value
|
|
70
|
+
def [](key)
|
|
71
|
+
@options[key]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Set option value
|
|
75
|
+
#
|
|
76
|
+
# @param key [Symbol] Option key
|
|
77
|
+
# @param value [Object] Option value
|
|
78
|
+
def []=(key, value)
|
|
79
|
+
@options[key] = value
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Check if paths should be preserved
|
|
83
|
+
#
|
|
84
|
+
# @return [Boolean]
|
|
85
|
+
def preserve_paths?
|
|
86
|
+
@options[:preserve_paths]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Check if paths should be flattened
|
|
90
|
+
#
|
|
91
|
+
# @return [Boolean]
|
|
92
|
+
def flatten?
|
|
93
|
+
@options[:flatten]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Check if existing files should be overwritten
|
|
97
|
+
#
|
|
98
|
+
# @return [Boolean]
|
|
99
|
+
def overwrite?
|
|
100
|
+
@options[:overwrite]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
|
|
105
|
+
def default_options
|
|
106
|
+
{
|
|
107
|
+
preserve_paths: true,
|
|
108
|
+
flatten: false,
|
|
109
|
+
overwrite: false,
|
|
110
|
+
dest_prefix: nil,
|
|
111
|
+
}
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
5
|
+
#
|
|
6
|
+
# This file is part of Omnizip.
|
|
7
|
+
#
|
|
8
|
+
# Omnizip is a pure Ruby port of 7-Zip compression algorithms.
|
|
9
|
+
# Based on the 7-Zip LZMA SDK by Igor Pavlov.
|
|
10
|
+
#
|
|
11
|
+
# This library is free software; you can redistribute it and/or
|
|
12
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
# License as published by the Free Software Foundation; either
|
|
14
|
+
# version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
#
|
|
16
|
+
# See the COPYING file for the complete text of the license.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
require_relative "filter_config"
|
|
20
|
+
|
|
21
|
+
module Omnizip
|
|
22
|
+
module Models
|
|
23
|
+
# Ordered sequence of filters for compression/decompression
|
|
24
|
+
#
|
|
25
|
+
# Manages a pipeline of filters that are applied in sequence.
|
|
26
|
+
# Filters are applied in reverse order during decode.
|
|
27
|
+
#
|
|
28
|
+
# @example Create filter chain for XZ executable
|
|
29
|
+
# chain = FilterChain.new(format: :xz)
|
|
30
|
+
# chain.add_filter(name: :"bcj-x86", architecture: :x86)
|
|
31
|
+
# chain.add_filter(name: :lzma2) # Main compression
|
|
32
|
+
# encoded = chain.encode_all(data, position)
|
|
33
|
+
class FilterChain
|
|
34
|
+
# @return [Array<FilterConfig>] Ordered filter configurations
|
|
35
|
+
attr_reader :filters
|
|
36
|
+
|
|
37
|
+
# @return [Symbol] Format identifier (:xz, :seven_zip)
|
|
38
|
+
attr_reader :format
|
|
39
|
+
|
|
40
|
+
# Maximum filters in XZ format
|
|
41
|
+
MAX_FILTERS_XZ = 4
|
|
42
|
+
|
|
43
|
+
# Maximum filters in 7z format
|
|
44
|
+
MAX_FILTERS_SEVEN_ZIP = 4
|
|
45
|
+
|
|
46
|
+
# Initialize filter chain
|
|
47
|
+
#
|
|
48
|
+
# @param attributes [Hash] Initialization attributes
|
|
49
|
+
# @option attributes [Symbol] :format Target format
|
|
50
|
+
def initialize(attributes = {})
|
|
51
|
+
@format = attributes[:format] || :xz
|
|
52
|
+
@filters = attributes[:filters] || []
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Add a filter to the chain
|
|
56
|
+
#
|
|
57
|
+
# @param filter_attributes [Hash] Filter configuration
|
|
58
|
+
# @option filter_attributes [Symbol] :name Filter name
|
|
59
|
+
# @option filter_attributes [String] :properties Filter properties
|
|
60
|
+
# @option filter_attributes [Symbol] :architecture Target architecture
|
|
61
|
+
# @return [self] For chaining
|
|
62
|
+
def add_filter(filter_attributes = {})
|
|
63
|
+
filter = FilterConfig.new(filter_attributes)
|
|
64
|
+
filter.validate!
|
|
65
|
+
@filters << filter
|
|
66
|
+
self
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Get maximum filters for current format
|
|
70
|
+
#
|
|
71
|
+
# @return [Integer] Maximum number of filters allowed
|
|
72
|
+
def max_filters
|
|
73
|
+
case @format
|
|
74
|
+
when :xz then MAX_FILTERS_XZ
|
|
75
|
+
when :seven_zip then MAX_FILTERS_SEVEN_ZIP
|
|
76
|
+
else raise ArgumentError, "Unknown format: #{@format}"
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Validate filter chain
|
|
81
|
+
#
|
|
82
|
+
# @return [Boolean] True if valid
|
|
83
|
+
# @raise [ArgumentError] If validation fails
|
|
84
|
+
def validate!
|
|
85
|
+
if @filters.size > max_filters
|
|
86
|
+
raise ArgumentError,
|
|
87
|
+
"Too many filters for #{@format}: #{@filters.size} > #{max_filters}"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
@filters.each(&:validate!)
|
|
91
|
+
true
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Encode data through all filters in order
|
|
95
|
+
#
|
|
96
|
+
# @param data [String] Input data
|
|
97
|
+
# @param position [Integer] Stream position
|
|
98
|
+
# @return [String] Encoded data
|
|
99
|
+
def encode_all(data, position = 0)
|
|
100
|
+
result = data
|
|
101
|
+
@filters.each do |filter_config|
|
|
102
|
+
filter = filter_config.filter_instance
|
|
103
|
+
result = filter.encode(result, position)
|
|
104
|
+
end
|
|
105
|
+
result
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Decode data through all filters in reverse order
|
|
109
|
+
#
|
|
110
|
+
# @param data [String] Input data
|
|
111
|
+
# @param position [Integer] Stream position
|
|
112
|
+
# @return [String] Decoded data
|
|
113
|
+
def decode_all(data, position = 0)
|
|
114
|
+
result = data
|
|
115
|
+
@filters.reverse_each do |filter_config|
|
|
116
|
+
filter = filter_config.filter_instance
|
|
117
|
+
result = filter.decode(result, position)
|
|
118
|
+
end
|
|
119
|
+
result
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Get filter IDs for current format
|
|
123
|
+
#
|
|
124
|
+
# @return [Array<Integer>] Array of filter IDs in order
|
|
125
|
+
def filter_ids
|
|
126
|
+
@filters.map { |f| f.id_for_format(@format) }
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Check if chain is empty
|
|
130
|
+
#
|
|
131
|
+
# @return [Boolean] True if no filters
|
|
132
|
+
def empty?
|
|
133
|
+
@filters.empty?
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Get number of filters in chain
|
|
137
|
+
#
|
|
138
|
+
# @return [Integer] Filter count
|
|
139
|
+
def size
|
|
140
|
+
@filters.size
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|