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,183 @@
|
|
|
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_registry"
|
|
20
|
+
|
|
21
|
+
module Omnizip
|
|
22
|
+
module Models
|
|
23
|
+
# Configuration model for a filter in a compression pipeline.
|
|
24
|
+
#
|
|
25
|
+
# This class replaces hash-based filter configuration with a proper
|
|
26
|
+
# model class. It provides format-aware ID resolution and validation.
|
|
27
|
+
#
|
|
28
|
+
# @example Create a BCJ filter configuration
|
|
29
|
+
# config = FilterConfig.new(name: :bcj_x86, architecture: :x86)
|
|
30
|
+
# config.id_for_format(:xz) # => 0x04
|
|
31
|
+
# config.id_for_format(:seven_zip) # => 0x03030103
|
|
32
|
+
#
|
|
33
|
+
# @example Create a Delta filter configuration
|
|
34
|
+
# config = FilterConfig.new(name: :delta)
|
|
35
|
+
# config.delta? # => true
|
|
36
|
+
class FilterConfig
|
|
37
|
+
# @return [Symbol] Filter name (:bcj_x86, :delta, etc.)
|
|
38
|
+
attr_reader :name_sym
|
|
39
|
+
|
|
40
|
+
# @return [String] Binary properties data for filter configuration
|
|
41
|
+
attr_accessor :properties
|
|
42
|
+
|
|
43
|
+
# @return [Symbol] Target architecture for BCJ filters
|
|
44
|
+
attr_accessor :architecture
|
|
45
|
+
|
|
46
|
+
# Initialize filter configuration.
|
|
47
|
+
#
|
|
48
|
+
# @param attributes [Hash] Initialization attributes
|
|
49
|
+
# @option attributes [Symbol] :name Filter name
|
|
50
|
+
# @option attributes [Symbol] :name_sym Filter name (alternative key)
|
|
51
|
+
# @option attributes [String] :properties Binary properties data
|
|
52
|
+
# @option attributes [Symbol] :architecture Target architecture
|
|
53
|
+
def initialize(attributes = {})
|
|
54
|
+
@name_sym = attributes[:name] || attributes[:name_sym]
|
|
55
|
+
@properties = attributes[:properties] || "".b
|
|
56
|
+
@architecture = attributes[:architecture]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Set filter name.
|
|
60
|
+
#
|
|
61
|
+
# @param value [Symbol] Filter name
|
|
62
|
+
# @return [void]
|
|
63
|
+
def name=(value)
|
|
64
|
+
@name_sym = value
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Get filter name as symbol.
|
|
68
|
+
#
|
|
69
|
+
# @return [Symbol] Filter name
|
|
70
|
+
def name_sym
|
|
71
|
+
@name_sym
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Get filter instance from registry.
|
|
75
|
+
#
|
|
76
|
+
# Returns a new instance of the filter. Handles both old-style
|
|
77
|
+
# registration (direct class) and new-style registration (hash with :class).
|
|
78
|
+
#
|
|
79
|
+
# @return [Object] Filter instance from FilterRegistry
|
|
80
|
+
# @raise [KeyError] If filter not found in registry
|
|
81
|
+
def filter_instance
|
|
82
|
+
filter = Omnizip::FilterRegistry.get(@name_sym)
|
|
83
|
+
|
|
84
|
+
# Handle both hash-style and direct class registration
|
|
85
|
+
if filter.is_a?(Hash)
|
|
86
|
+
# New-style registration - check if architecture is needed
|
|
87
|
+
klass = filter[:class]
|
|
88
|
+
if architecture_required?(klass)
|
|
89
|
+
klass.new(architecture: @architecture) if @architecture
|
|
90
|
+
else
|
|
91
|
+
klass.new
|
|
92
|
+
end
|
|
93
|
+
elsif filter.is_a?(Class)
|
|
94
|
+
# Old-style registration - try with architecture if available
|
|
95
|
+
if @architecture && requires_initialize_kwargs?(filter)
|
|
96
|
+
filter.new(architecture: @architecture)
|
|
97
|
+
else
|
|
98
|
+
filter.new
|
|
99
|
+
end
|
|
100
|
+
else
|
|
101
|
+
# Already an instance
|
|
102
|
+
filter
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Get filter ID for specific format.
|
|
107
|
+
#
|
|
108
|
+
# Delegates to filter instance's id_for_format method if available.
|
|
109
|
+
# For older filters without id_for_format, returns a default value.
|
|
110
|
+
#
|
|
111
|
+
# @param format [Symbol] Format identifier (:seven_zip, :xz)
|
|
112
|
+
# @return [Integer] Format-specific filter ID
|
|
113
|
+
# @raise [NotImplementedError] If filter doesn't support id_for_format
|
|
114
|
+
def id_for_format(format)
|
|
115
|
+
filter = filter_instance
|
|
116
|
+
if filter.respond_to?(:id_for_format)
|
|
117
|
+
filter.id_for_format(format)
|
|
118
|
+
else
|
|
119
|
+
raise NotImplementedError,
|
|
120
|
+
"Filter #{@name_sym} doesn't support format-aware IDs. " \
|
|
121
|
+
"Use the newer BCJ filter instead."
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Check if this is a BCJ filter.
|
|
126
|
+
#
|
|
127
|
+
# @return [Boolean] True if BCJ filter variant
|
|
128
|
+
def bcj?
|
|
129
|
+
@name_sym.to_s.start_with?("bcj_")
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Check if this is a Delta filter.
|
|
133
|
+
#
|
|
134
|
+
# @return [Boolean] True if Delta filter
|
|
135
|
+
def delta?
|
|
136
|
+
@name_sym == :delta
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Validate configuration.
|
|
140
|
+
#
|
|
141
|
+
# @return [Boolean] True if valid
|
|
142
|
+
# @raise [ArgumentError] If filter name is nil or not registered
|
|
143
|
+
def validate!
|
|
144
|
+
raise ArgumentError, "Filter name is required" if @name_sym.nil?
|
|
145
|
+
|
|
146
|
+
unless Omnizip::FilterRegistry.registered?(@name_sym)
|
|
147
|
+
raise ArgumentError, "Filter not registered: #{@name_sym}"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
true
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Convert to hash for backward compatibility.
|
|
154
|
+
#
|
|
155
|
+
# @return [Hash] Hash representation with :name, :properties, :architecture
|
|
156
|
+
def to_h
|
|
157
|
+
{
|
|
158
|
+
name: @name_sym,
|
|
159
|
+
properties: @properties,
|
|
160
|
+
architecture: @architecture,
|
|
161
|
+
}
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
private
|
|
165
|
+
|
|
166
|
+
# Check if filter class requires architecture argument.
|
|
167
|
+
#
|
|
168
|
+
# @param klass [Class] Filter class to check
|
|
169
|
+
# @return [Boolean] True if architecture is required
|
|
170
|
+
def architecture_required?(klass)
|
|
171
|
+
klass.name.include?("BCJ") && !klass.name.include?("BcjX86")
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Check if filter class requires keyword arguments for initialize.
|
|
175
|
+
#
|
|
176
|
+
# @param klass [Class] Filter class to check
|
|
177
|
+
# @return [Boolean] True if kwargs are required
|
|
178
|
+
def requires_initialize_kwargs?(klass)
|
|
179
|
+
klass.name.include?("BCJ") && !klass.name.include?("BcjX86")
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Models
|
|
5
|
+
# Represents the result of pattern matching against archive entries
|
|
6
|
+
#
|
|
7
|
+
# Contains matched entries with metadata about the matching process.
|
|
8
|
+
class MatchResult
|
|
9
|
+
include Enumerable
|
|
10
|
+
|
|
11
|
+
attr_reader :matches, :total_scanned, :pattern
|
|
12
|
+
|
|
13
|
+
# Initialize a new match result
|
|
14
|
+
#
|
|
15
|
+
# @param pattern [Object] The pattern that was matched
|
|
16
|
+
# @param matches [Array] Array of matched entries
|
|
17
|
+
# @param total_scanned [Integer] Total entries scanned
|
|
18
|
+
def initialize(pattern, matches: [], total_scanned: 0)
|
|
19
|
+
@pattern = pattern
|
|
20
|
+
@matches = Array(matches)
|
|
21
|
+
@total_scanned = total_scanned
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Add a matched entry
|
|
25
|
+
#
|
|
26
|
+
# @param entry [Object] Entry that matched
|
|
27
|
+
# @return [self]
|
|
28
|
+
def add_match(entry)
|
|
29
|
+
@matches << entry
|
|
30
|
+
self
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Increment the scan counter
|
|
34
|
+
#
|
|
35
|
+
# @param count [Integer] Number to increment by
|
|
36
|
+
# @return [self]
|
|
37
|
+
def increment_scanned(count = 1)
|
|
38
|
+
@total_scanned += count
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Get the number of matches
|
|
43
|
+
#
|
|
44
|
+
# @return [Integer]
|
|
45
|
+
def count
|
|
46
|
+
@matches.size
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Check if any matches were found
|
|
50
|
+
#
|
|
51
|
+
# @return [Boolean]
|
|
52
|
+
def any?
|
|
53
|
+
!@matches.empty?
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Check if no matches were found
|
|
57
|
+
#
|
|
58
|
+
# @return [Boolean]
|
|
59
|
+
def none?
|
|
60
|
+
@matches.empty?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Get match rate (matches/scanned)
|
|
64
|
+
#
|
|
65
|
+
# @return [Float] Match rate between 0.0 and 1.0
|
|
66
|
+
def match_rate
|
|
67
|
+
return 0.0 if @total_scanned.zero?
|
|
68
|
+
|
|
69
|
+
count.to_f / @total_scanned
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Get match percentage
|
|
73
|
+
#
|
|
74
|
+
# @return [Float] Match percentage between 0.0 and 100.0
|
|
75
|
+
def match_percentage
|
|
76
|
+
match_rate * 100.0
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Iterate over matches
|
|
80
|
+
#
|
|
81
|
+
# @yield [entry] Each matched entry
|
|
82
|
+
# @return [Enumerator, self]
|
|
83
|
+
def each(&block)
|
|
84
|
+
return matches.to_enum unless block
|
|
85
|
+
|
|
86
|
+
matches.each(&block)
|
|
87
|
+
self
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Get first match
|
|
91
|
+
#
|
|
92
|
+
# @return [Object, nil]
|
|
93
|
+
def first
|
|
94
|
+
@matches.first
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Get last match
|
|
98
|
+
#
|
|
99
|
+
# @return [Object, nil]
|
|
100
|
+
def last
|
|
101
|
+
@matches.last
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Convert to array
|
|
105
|
+
#
|
|
106
|
+
# @return [Array]
|
|
107
|
+
def to_a
|
|
108
|
+
@matches.dup
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Get summary hash
|
|
112
|
+
#
|
|
113
|
+
# @return [Hash]
|
|
114
|
+
def to_h
|
|
115
|
+
{
|
|
116
|
+
pattern: @pattern.to_s,
|
|
117
|
+
matches: count,
|
|
118
|
+
scanned: @total_scanned,
|
|
119
|
+
match_rate: match_rate,
|
|
120
|
+
}
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Models
|
|
5
|
+
# Represents a performance optimization suggestion based on profiling data
|
|
6
|
+
class OptimizationSuggestion
|
|
7
|
+
SEVERITY_LEVELS = %i[low medium high critical].freeze
|
|
8
|
+
CATEGORIES = %i[
|
|
9
|
+
memory cpu hotpath algorithm io gc allocation concurrency
|
|
10
|
+
].freeze
|
|
11
|
+
|
|
12
|
+
attr_reader :title, :description, :severity, :category, :impact_estimate,
|
|
13
|
+
:implementation_effort, :related_operations, :code_locations,
|
|
14
|
+
:metrics
|
|
15
|
+
|
|
16
|
+
def initialize(
|
|
17
|
+
title:,
|
|
18
|
+
description:,
|
|
19
|
+
severity:,
|
|
20
|
+
category:,
|
|
21
|
+
impact_estimate: nil,
|
|
22
|
+
implementation_effort: nil,
|
|
23
|
+
related_operations: [],
|
|
24
|
+
code_locations: [],
|
|
25
|
+
metrics: {}
|
|
26
|
+
)
|
|
27
|
+
validate_severity!(severity)
|
|
28
|
+
validate_category!(category)
|
|
29
|
+
|
|
30
|
+
@title = title
|
|
31
|
+
@description = description
|
|
32
|
+
@severity = severity
|
|
33
|
+
@category = category
|
|
34
|
+
@impact_estimate = impact_estimate
|
|
35
|
+
@implementation_effort = implementation_effort
|
|
36
|
+
@related_operations = related_operations
|
|
37
|
+
@code_locations = code_locations
|
|
38
|
+
@metrics = metrics
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def critical?
|
|
42
|
+
severity == :critical
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def high_priority?
|
|
46
|
+
severity == :high || critical?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def priority_score
|
|
50
|
+
severity_weight = SEVERITY_LEVELS.index(severity) + 1
|
|
51
|
+
impact_weight = impact_estimate || 1.0
|
|
52
|
+
effort_weight = implementation_effort ? (1.0 / implementation_effort) : 1.0
|
|
53
|
+
|
|
54
|
+
severity_weight * impact_weight * effort_weight
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def to_h
|
|
58
|
+
{
|
|
59
|
+
title: title,
|
|
60
|
+
description: description,
|
|
61
|
+
severity: severity,
|
|
62
|
+
category: category,
|
|
63
|
+
impact_estimate: impact_estimate,
|
|
64
|
+
implementation_effort: implementation_effort,
|
|
65
|
+
priority_score: priority_score,
|
|
66
|
+
related_operations: related_operations,
|
|
67
|
+
code_locations: code_locations,
|
|
68
|
+
metrics: metrics,
|
|
69
|
+
}
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def validate_severity!(severity)
|
|
75
|
+
return if SEVERITY_LEVELS.include?(severity)
|
|
76
|
+
|
|
77
|
+
raise ArgumentError,
|
|
78
|
+
"Invalid severity: #{severity}. " \
|
|
79
|
+
"Must be one of: #{SEVERITY_LEVELS.join(', ')}"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def validate_category!(category)
|
|
83
|
+
return if CATEGORIES.include?(category)
|
|
84
|
+
|
|
85
|
+
raise ArgumentError,
|
|
86
|
+
"Invalid category: #{category}. " \
|
|
87
|
+
"Must be one of: #{CATEGORIES.join(', ')}"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Models
|
|
5
|
+
# Model for parallel processing configuration
|
|
6
|
+
#
|
|
7
|
+
# Stores settings for parallel compression and extraction operations
|
|
8
|
+
# including thread count, queue size, and load balancing strategy.
|
|
9
|
+
#
|
|
10
|
+
# @example Create parallel options
|
|
11
|
+
# options = Omnizip::Models::ParallelOptions.new
|
|
12
|
+
# options.threads = 8
|
|
13
|
+
# options.queue_size = 100
|
|
14
|
+
# options.strategy = :dynamic
|
|
15
|
+
#
|
|
16
|
+
# @example Use with parallel compression
|
|
17
|
+
# Omnizip::Parallel.compress_directory('files/', 'backup.zip', options)
|
|
18
|
+
class ParallelOptions
|
|
19
|
+
# @return [Integer] Number of worker threads (default: auto-detect)
|
|
20
|
+
attr_accessor :threads
|
|
21
|
+
|
|
22
|
+
# @return [Integer] Maximum size of job queue (default: 1000)
|
|
23
|
+
attr_accessor :queue_size
|
|
24
|
+
|
|
25
|
+
# @return [Integer] Chunk size for chunked operations in bytes
|
|
26
|
+
attr_accessor :chunk_size
|
|
27
|
+
|
|
28
|
+
# @return [Symbol] Load balancing strategy (:dynamic or :static)
|
|
29
|
+
attr_accessor :strategy
|
|
30
|
+
|
|
31
|
+
# @return [Boolean] Enable verbose progress output
|
|
32
|
+
attr_accessor :verbose
|
|
33
|
+
|
|
34
|
+
# @return [Integer] Batch size for work queue polling
|
|
35
|
+
attr_accessor :batch_size
|
|
36
|
+
|
|
37
|
+
# Initialize parallel options with default values
|
|
38
|
+
def initialize
|
|
39
|
+
@threads = detect_cpu_count
|
|
40
|
+
@queue_size = 1000
|
|
41
|
+
@chunk_size = 64 * 1024 * 1024 # 64MB default
|
|
42
|
+
@strategy = :dynamic
|
|
43
|
+
@verbose = false
|
|
44
|
+
@batch_size = 10
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Validate options
|
|
48
|
+
#
|
|
49
|
+
# @raise [ArgumentError] if options are invalid
|
|
50
|
+
# @return [Boolean] true if valid
|
|
51
|
+
def validate!
|
|
52
|
+
raise ArgumentError, "threads must be > 0" if threads <= 0
|
|
53
|
+
raise ArgumentError, "queue_size must be > 0" if queue_size <= 0
|
|
54
|
+
raise ArgumentError, "chunk_size must be > 0" if chunk_size <= 0
|
|
55
|
+
raise ArgumentError, "strategy must be :dynamic or :static" unless %i[
|
|
56
|
+
dynamic static
|
|
57
|
+
].include?(strategy)
|
|
58
|
+
raise ArgumentError, "batch_size must be > 0" if batch_size <= 0
|
|
59
|
+
|
|
60
|
+
true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Create a copy of options
|
|
64
|
+
#
|
|
65
|
+
# @return [ParallelOptions] new instance with same values
|
|
66
|
+
def dup
|
|
67
|
+
copy = self.class.new
|
|
68
|
+
copy.threads = threads
|
|
69
|
+
copy.queue_size = queue_size
|
|
70
|
+
copy.chunk_size = chunk_size
|
|
71
|
+
copy.strategy = strategy
|
|
72
|
+
copy.verbose = verbose
|
|
73
|
+
copy.batch_size = batch_size
|
|
74
|
+
copy
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Convert to hash
|
|
78
|
+
#
|
|
79
|
+
# @return [Hash] options as hash
|
|
80
|
+
def to_h
|
|
81
|
+
{
|
|
82
|
+
threads: threads,
|
|
83
|
+
queue_size: queue_size,
|
|
84
|
+
chunk_size: chunk_size,
|
|
85
|
+
strategy: strategy,
|
|
86
|
+
verbose: verbose,
|
|
87
|
+
batch_size: batch_size,
|
|
88
|
+
}
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
# Detect number of available CPU cores
|
|
94
|
+
#
|
|
95
|
+
# @return [Integer] number of CPUs
|
|
96
|
+
def detect_cpu_count
|
|
97
|
+
require "etc"
|
|
98
|
+
Etc.nprocessors
|
|
99
|
+
rescue StandardError
|
|
100
|
+
4 # fallback to 4 threads
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Models
|
|
5
|
+
# Represents the performance characteristics of a profiled operation
|
|
6
|
+
class PerformanceResult
|
|
7
|
+
attr_reader :operation_name, :total_time, :cpu_time, :wall_time,
|
|
8
|
+
:memory_allocated, :memory_retained, :object_allocations,
|
|
9
|
+
:gc_runs, :call_count, :timestamp
|
|
10
|
+
|
|
11
|
+
def initialize(
|
|
12
|
+
operation_name:,
|
|
13
|
+
total_time: nil,
|
|
14
|
+
cpu_time: nil,
|
|
15
|
+
wall_time: nil,
|
|
16
|
+
memory_allocated: nil,
|
|
17
|
+
memory_retained: nil,
|
|
18
|
+
object_allocations: nil,
|
|
19
|
+
gc_runs: nil,
|
|
20
|
+
call_count: nil,
|
|
21
|
+
timestamp: Time.now
|
|
22
|
+
)
|
|
23
|
+
@operation_name = operation_name
|
|
24
|
+
@total_time = total_time
|
|
25
|
+
@cpu_time = cpu_time
|
|
26
|
+
@wall_time = wall_time
|
|
27
|
+
@memory_allocated = memory_allocated
|
|
28
|
+
@memory_retained = memory_retained
|
|
29
|
+
@object_allocations = object_allocations
|
|
30
|
+
@gc_runs = gc_runs
|
|
31
|
+
@call_count = call_count
|
|
32
|
+
@timestamp = timestamp
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def throughput_ops_per_second
|
|
36
|
+
return nil unless call_count && total_time&.positive?
|
|
37
|
+
|
|
38
|
+
call_count.to_f / total_time
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def average_time_per_operation
|
|
42
|
+
return nil unless call_count && total_time && call_count.positive?
|
|
43
|
+
|
|
44
|
+
total_time / call_count.to_f
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def memory_per_operation
|
|
48
|
+
return nil unless call_count && memory_allocated && call_count.positive?
|
|
49
|
+
|
|
50
|
+
memory_allocated / call_count.to_f
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def gc_pressure
|
|
54
|
+
return nil unless gc_runs && total_time&.positive?
|
|
55
|
+
|
|
56
|
+
gc_runs.to_f / total_time
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def to_h
|
|
60
|
+
{
|
|
61
|
+
operation_name: operation_name,
|
|
62
|
+
total_time: total_time,
|
|
63
|
+
cpu_time: cpu_time,
|
|
64
|
+
wall_time: wall_time,
|
|
65
|
+
memory_allocated: memory_allocated,
|
|
66
|
+
memory_retained: memory_retained,
|
|
67
|
+
object_allocations: object_allocations,
|
|
68
|
+
gc_runs: gc_runs,
|
|
69
|
+
call_count: call_count,
|
|
70
|
+
throughput_ops_per_second: throughput_ops_per_second,
|
|
71
|
+
average_time_per_operation: average_time_per_operation,
|
|
72
|
+
memory_per_operation: memory_per_operation,
|
|
73
|
+
gc_pressure: gc_pressure,
|
|
74
|
+
timestamp: timestamp.iso8601,
|
|
75
|
+
}
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Models
|
|
5
|
+
# Represents an aggregated profiling report with hot path analysis
|
|
6
|
+
class ProfileReport
|
|
7
|
+
attr_reader :profile_name, :results, :hot_paths, :bottlenecks,
|
|
8
|
+
:timestamp, :metadata
|
|
9
|
+
|
|
10
|
+
def initialize(
|
|
11
|
+
profile_name:,
|
|
12
|
+
results: [],
|
|
13
|
+
hot_paths: [],
|
|
14
|
+
bottlenecks: [],
|
|
15
|
+
timestamp: Time.now,
|
|
16
|
+
metadata: {}
|
|
17
|
+
)
|
|
18
|
+
@profile_name = profile_name
|
|
19
|
+
@results = results
|
|
20
|
+
@hot_paths = hot_paths
|
|
21
|
+
@bottlenecks = bottlenecks
|
|
22
|
+
@timestamp = timestamp
|
|
23
|
+
@metadata = metadata
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def total_execution_time
|
|
27
|
+
results.filter_map(&:total_time).sum
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def total_memory_allocated
|
|
31
|
+
results.filter_map(&:memory_allocated).sum
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def total_gc_runs
|
|
35
|
+
results.filter_map(&:gc_runs).sum
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def slowest_operations(limit: 5)
|
|
39
|
+
results.select(&:total_time)
|
|
40
|
+
.sort_by(&:total_time)
|
|
41
|
+
.reverse
|
|
42
|
+
.take(limit)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def memory_intensive_operations(limit: 5)
|
|
46
|
+
results.select(&:memory_allocated)
|
|
47
|
+
.sort_by(&:memory_allocated)
|
|
48
|
+
.reverse
|
|
49
|
+
.take(limit)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def add_result(result)
|
|
53
|
+
@results << result
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def add_hot_path(hot_path)
|
|
57
|
+
@hot_paths << hot_path
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def add_bottleneck(bottleneck)
|
|
61
|
+
@bottlenecks << bottleneck
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def to_h
|
|
65
|
+
{
|
|
66
|
+
profile_name: profile_name,
|
|
67
|
+
timestamp: timestamp.iso8601,
|
|
68
|
+
summary: {
|
|
69
|
+
total_execution_time: total_execution_time,
|
|
70
|
+
total_memory_allocated: total_memory_allocated,
|
|
71
|
+
total_gc_runs: total_gc_runs,
|
|
72
|
+
operation_count: results.size,
|
|
73
|
+
},
|
|
74
|
+
results: results.map(&:to_h),
|
|
75
|
+
hot_paths: hot_paths,
|
|
76
|
+
bottlenecks: bottlenecks,
|
|
77
|
+
metadata: metadata,
|
|
78
|
+
}
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
module Omnizip
|
|
8
|
+
module Models
|
|
9
|
+
# Model representing progress tracking options.
|
|
10
|
+
#
|
|
11
|
+
# This class encapsulates configuration for progress tracking,
|
|
12
|
+
# including reporter type, update interval, and display preferences.
|
|
13
|
+
class ProgressOptions
|
|
14
|
+
attr_accessor :reporter, :update_interval, :show_rate,
|
|
15
|
+
:show_eta, :show_files, :show_bytes
|
|
16
|
+
|
|
17
|
+
def initialize
|
|
18
|
+
@reporter = "auto"
|
|
19
|
+
@update_interval = 0.5
|
|
20
|
+
@show_rate = true
|
|
21
|
+
@show_eta = true
|
|
22
|
+
@show_files = true
|
|
23
|
+
@show_bytes = true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_h
|
|
27
|
+
{
|
|
28
|
+
reporter: @reporter,
|
|
29
|
+
update_interval: @update_interval,
|
|
30
|
+
show_rate: @show_rate,
|
|
31
|
+
show_eta: @show_eta,
|
|
32
|
+
show_files: @show_files,
|
|
33
|
+
show_bytes: @show_bytes,
|
|
34
|
+
}.compact
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|