omnizip 0.4.7-x86_64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +32 -0
- data/.rubocop_todo.yml +293 -0
- data/CHANGELOG.md +1647 -0
- data/CONTEXT.md +68 -0
- data/COPYING +502 -0
- data/Gemfile +19 -0
- data/LICENSE +12 -0
- data/README.adoc +1327 -0
- data/Rakefile +15 -0
- data/TODO.refactor/00-overview.md +67 -0
- data/TODO.refactor/01-registry-base-class.md +81 -0
- data/TODO.refactor/02-error-hierarchy.md +57 -0
- data/TODO.refactor/03-autoload-entry-point.md +69 -0
- data/TODO.refactor/04-filter-base-consolidation.md +49 -0
- data/TODO.refactor/05-send-private-methods.md +64 -0
- data/TODO.refactor/06-instance-variable-access.md +69 -0
- data/TODO.refactor/07-respond-to-replacement.md +237 -0
- data/TODO.refactor/08-spec-doubles.md +27 -0
- data/TODO.refactor/09-cli-shared-module.md +35 -0
- data/TODO.refactor/10-format-detector-ocp.md +34 -0
- data/TODO.refactor/11-convenience-decoupling.md +38 -0
- data/TODO.refactor/12-thread-safety.md +8 -0
- data/TODO.refactor/13-lutaml-model-migration.md +158 -0
- data/TODO.refactor/14-add-missing-specs.md +25 -0
- data/benchmark/README.md +260 -0
- data/benchmark/benchmark_suite.rb +125 -0
- data/benchmark/compression_bench.rb +181 -0
- data/benchmark/filter_bench.rb +180 -0
- data/benchmark/models/benchmark_result.rb +59 -0
- data/benchmark/models/comparison_result.rb +69 -0
- data/benchmark/profile_suite.rb +167 -0
- data/benchmark/reporter.rb +150 -0
- data/benchmark/run_benchmarks.rb +66 -0
- data/benchmark/test_data.rb +137 -0
- data/config/formats/rar3_spec.yml +92 -0
- data/config/formats/rar5_spec.yml +102 -0
- data/docs/.github/workflows/docs.yml +142 -0
- data/docs/.gitignore +21 -0
- data/docs/.lychee.toml +67 -0
- data/docs/Gemfile +13 -0
- data/docs/RAR_WRITE_SUPPORT.md +26 -0
- data/docs/README.md +101 -0
- data/docs/_config.yml +112 -0
- data/docs/assets/logo.svg +1 -0
- data/docs/assets/omnizip-logo.pdf +1540 -11
- data/docs/comparison/feature-matrix.adoc +694 -0
- data/docs/comparison/index.adoc +113 -0
- data/docs/comparison/vs-7zip.adoc +309 -0
- data/docs/comparison/vs-peazip.adoc +77 -0
- data/docs/comparison/vs-rubyzip.adoc +342 -0
- data/docs/comparison/vs-winrar.adoc +100 -0
- data/docs/compatibility.adoc +579 -0
- data/docs/concepts/index.adoc +129 -0
- data/docs/developer/architecture.adoc +256 -0
- data/docs/developer/contributing.adoc +158 -0
- data/docs/developer/index.adoc +25 -0
- data/docs/developer/testing.adoc +212 -0
- data/docs/getting-started/basic-usage.adoc +263 -0
- data/docs/getting-started/index.adoc +42 -0
- data/docs/getting-started/installation.adoc +138 -0
- data/docs/getting-started/quick-start.adoc +183 -0
- data/docs/getting-started/your-first-archive.adoc +219 -0
- data/docs/guides/advanced-features/encryption.adoc +277 -0
- data/docs/guides/advanced-features/index.adoc +59 -0
- data/docs/guides/advanced-features/parallel-processing.adoc +144 -0
- data/docs/guides/advanced-features/progress-tracking.adoc +124 -0
- data/docs/guides/advanced-features/streaming.adoc +142 -0
- data/docs/guides/archive-formats/gzip-format.adoc +105 -0
- data/docs/guides/archive-formats/index.adoc +160 -0
- data/docs/guides/archive-formats/ole-format.adoc +151 -0
- data/docs/guides/archive-formats/rar-format.adoc +104 -0
- data/docs/guides/archive-formats/rar5.adoc +521 -0
- data/docs/guides/archive-formats/rpm-format.adoc +108 -0
- data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
- data/docs/guides/archive-formats/tar-format.adoc +106 -0
- data/docs/guides/archive-formats/xz-format.adoc +118 -0
- data/docs/guides/archive-formats/zip-format.adoc +35 -0
- data/docs/guides/compression-algorithms/bzip2.adoc +114 -0
- data/docs/guides/compression-algorithms/deflate.adoc +313 -0
- data/docs/guides/compression-algorithms/index.adoc +190 -0
- data/docs/guides/compression-algorithms/lzma.adoc +394 -0
- data/docs/guides/compression-algorithms/lzma2.adoc +244 -0
- data/docs/guides/compression-algorithms/ppmd.adoc +313 -0
- data/docs/guides/compression-algorithms/zstandard.adoc +296 -0
- data/docs/guides/creating-archives.adoc +348 -0
- data/docs/guides/extracting-archives.adoc +53 -0
- data/docs/guides/format-conversion.adoc +64 -0
- data/docs/guides/index.adoc +49 -0
- data/docs/guides/migration-rubyzip.adoc +217 -0
- data/docs/guides/parity-archives.adoc +605 -0
- data/docs/guides/performance-tuning.adoc +88 -0
- data/docs/index.adoc +228 -0
- data/docs/lychee.toml +67 -0
- data/docs/reference/api/overview.adoc +187 -0
- data/docs/reference/cli/compress-command.adoc +114 -0
- data/docs/reference/cli/overview.adoc +140 -0
- data/docs/reference/index.adoc +26 -0
- data/docs/resources/faq.adoc +185 -0
- data/docs/resources/quick-reference.adoc +222 -0
- data/docs/rust-backend.md +0 -0
- data/docs/troubleshooting/index.adoc +207 -0
- data/docs/xar_format.md +216 -0
- data/examples/api_comparison.rb +205 -0
- data/examples/deflate64_example.rb +96 -0
- data/examples/par2_demo.rb +121 -0
- data/examples/quick_start_native.rb +150 -0
- data/examples/quick_start_rubyzip.rb +115 -0
- data/examples/rubyzip_compatibility_demo.rb +194 -0
- data/exe/omnizip +27 -0
- data/lib/omnizip/algorithm.rb +176 -0
- data/lib/omnizip/algorithm_registry.rb +65 -0
- data/lib/omnizip/algorithms/.keep +0 -0
- data/lib/omnizip/algorithms/bzip2/bwt.rb +236 -0
- data/lib/omnizip/algorithms/bzip2/bz2.rb +687 -0
- data/lib/omnizip/algorithms/bzip2/rle.rb +146 -0
- data/lib/omnizip/algorithms/bzip2.rb +108 -0
- data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
- data/lib/omnizip/algorithms/deflate/decoder.rb +37 -0
- data/lib/omnizip/algorithms/deflate/encoder.rb +45 -0
- data/lib/omnizip/algorithms/deflate.rb +135 -0
- data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
- data/lib/omnizip/algorithms/deflate64/decoder.rb +151 -0
- data/lib/omnizip/algorithms/deflate64/encoder.rb +95 -0
- data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +352 -0
- data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +140 -0
- data/lib/omnizip/algorithms/deflate64.rb +118 -0
- data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
- data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
- data/lib/omnizip/algorithms/lzma/decoder.rb +146 -0
- data/lib/omnizip/algorithms/lzma/dictionary.rb +70 -0
- data/lib/omnizip/algorithms/lzma/distance_coder.rb +326 -0
- data/lib/omnizip/algorithms/lzma/encoder.rb +139 -0
- data/lib/omnizip/algorithms/lzma/length_coder.rb +172 -0
- data/lib/omnizip/algorithms/lzma/literal_decoder.rb +204 -0
- data/lib/omnizip/algorithms/lzma/literal_encoder.rb +208 -0
- data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +368 -0
- data/lib/omnizip/algorithms/lzma/lzma1_encoder.rb +105 -0
- data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +194 -0
- data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
- data/lib/omnizip/algorithms/lzma/match.rb +32 -0
- data/lib/omnizip/algorithms/lzma/match_finder.rb +233 -0
- data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
- data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +84 -0
- data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +159 -0
- data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
- data/lib/omnizip/algorithms/lzma/range_coder.rb +82 -0
- data/lib/omnizip/algorithms/lzma/range_decoder.rb +274 -0
- data/lib/omnizip/algorithms/lzma/range_encoder.rb +202 -0
- data/lib/omnizip/algorithms/lzma/state.rb +127 -0
- data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +323 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder.rb +420 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +640 -0
- data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +224 -0
- data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +167 -0
- data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +258 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +314 -0
- data/lib/omnizip/algorithms/lzma/xz_state.rb +108 -0
- data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +1311 -0
- data/lib/omnizip/algorithms/lzma.rb +266 -0
- data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +180 -0
- data/lib/omnizip/algorithms/lzma2/constants.rb +38 -0
- data/lib/omnizip/algorithms/lzma2/encoder.rb +145 -0
- data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +165 -0
- data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
- data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +122 -0
- data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
- data/lib/omnizip/algorithms/lzma2.rb +133 -0
- data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
- data/lib/omnizip/algorithms/ppmd7/context.rb +151 -0
- data/lib/omnizip/algorithms/ppmd7/decoder.rb +127 -0
- data/lib/omnizip/algorithms/ppmd7/encoder.rb +153 -0
- data/lib/omnizip/algorithms/ppmd7/model.rb +245 -0
- data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
- data/lib/omnizip/algorithms/ppmd7.rb +146 -0
- data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
- data/lib/omnizip/algorithms/ppmd8/context.rb +32 -0
- data/lib/omnizip/algorithms/ppmd8/decoder.rb +104 -0
- data/lib/omnizip/algorithms/ppmd8/encoder.rb +135 -0
- data/lib/omnizip/algorithms/ppmd8/model.rb +246 -0
- data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
- data/lib/omnizip/algorithms/ppmd8.rb +122 -0
- data/lib/omnizip/algorithms/ppmd_base.rb +142 -0
- data/lib/omnizip/algorithms/registration.rb +28 -0
- data/lib/omnizip/algorithms/zstandard/constants.rb +158 -0
- data/lib/omnizip/algorithms/zstandard/decoder.rb +249 -0
- data/lib/omnizip/algorithms/zstandard/dictionary.rb +73 -0
- data/lib/omnizip/algorithms/zstandard/encoder.rb +294 -0
- data/lib/omnizip/algorithms/zstandard/frame/block.rb +143 -0
- data/lib/omnizip/algorithms/zstandard/frame/header.rb +233 -0
- data/lib/omnizip/algorithms/zstandard/frame.rb +33 -0
- data/lib/omnizip/algorithms/zstandard/fse/bitstream.rb +183 -0
- data/lib/omnizip/algorithms/zstandard/fse/encoder.rb +534 -0
- data/lib/omnizip/algorithms/zstandard/fse/interleaved.rb +92 -0
- data/lib/omnizip/algorithms/zstandard/fse/table.rb +188 -0
- data/lib/omnizip/algorithms/zstandard/fse/table_description.rb +203 -0
- data/lib/omnizip/algorithms/zstandard/fse.rb +53 -0
- data/lib/omnizip/algorithms/zstandard/huffman.rb +276 -0
- data/lib/omnizip/algorithms/zstandard/huffman_encoder.rb +327 -0
- data/lib/omnizip/algorithms/zstandard/ldm.rb +121 -0
- data/lib/omnizip/algorithms/zstandard/literals.rb +241 -0
- data/lib/omnizip/algorithms/zstandard/literals_encoder.rb +96 -0
- data/lib/omnizip/algorithms/zstandard/match_finder.rb +483 -0
- data/lib/omnizip/algorithms/zstandard/sequences.rb +350 -0
- data/lib/omnizip/algorithms/zstandard/sequences_encoder.rb +333 -0
- data/lib/omnizip/algorithms/zstandard/xxhash.rb +159 -0
- data/lib/omnizip/algorithms/zstandard.rb +210 -0
- data/lib/omnizip/algorithms.rb +35 -0
- data/lib/omnizip/archive/builder.rb +48 -0
- data/lib/omnizip/archive/reader_session.rb +67 -0
- data/lib/omnizip/archive.rb +86 -0
- data/lib/omnizip/archive_handler.rb +82 -0
- data/lib/omnizip/archive_handlers/cpio_handler.rb +47 -0
- data/lib/omnizip/archive_handlers/iso_handler.rb +54 -0
- data/lib/omnizip/archive_handlers/ole_handler.rb +37 -0
- data/lib/omnizip/archive_handlers/rar_handler.rb +96 -0
- data/lib/omnizip/archive_handlers/rpm_handler.rb +45 -0
- data/lib/omnizip/archive_handlers/seven_zip_handler.rb +89 -0
- data/lib/omnizip/archive_handlers/tar_handler.rb +75 -0
- data/lib/omnizip/archive_handlers/xar_handler.rb +49 -0
- data/lib/omnizip/archive_handlers/zip_handler.rb +115 -0
- data/lib/omnizip/archive_handlers.rb +18 -0
- data/lib/omnizip/backends.rb +160 -0
- data/lib/omnizip/buffer/memory_archive.rb +246 -0
- data/lib/omnizip/buffer/memory_extractor.rb +234 -0
- data/lib/omnizip/buffer/seven_zip_bridge.rb +171 -0
- data/lib/omnizip/buffer.rb +187 -0
- data/lib/omnizip/checksum_registry.rb +41 -0
- data/lib/omnizip/checksums/crc32.rb +101 -0
- data/lib/omnizip/checksums/crc64.rb +102 -0
- data/lib/omnizip/checksums/crc_base.rb +158 -0
- data/lib/omnizip/checksums/registration.rb +16 -0
- data/lib/omnizip/checksums/verifier.rb +130 -0
- data/lib/omnizip/checksums.rb +11 -0
- data/lib/omnizip/chunked/memory_manager.rb +194 -0
- data/lib/omnizip/chunked/reader.rb +78 -0
- data/lib/omnizip/chunked/writer.rb +123 -0
- data/lib/omnizip/chunked.rb +123 -0
- data/lib/omnizip/cli/output_formatter.rb +112 -0
- data/lib/omnizip/cli.rb +604 -0
- data/lib/omnizip/commands/.keep +0 -0
- data/lib/omnizip/commands/archive_create_command.rb +245 -0
- data/lib/omnizip/commands/archive_extract_command.rb +231 -0
- data/lib/omnizip/commands/archive_list_command.rb +204 -0
- data/lib/omnizip/commands/archive_repair_command.rb +129 -0
- data/lib/omnizip/commands/archive_verify_command.rb +115 -0
- data/lib/omnizip/commands/compress_command.rb +115 -0
- data/lib/omnizip/commands/decompress_command.rb +149 -0
- data/lib/omnizip/commands/list_command.rb +51 -0
- data/lib/omnizip/commands/metadata_command.rb +215 -0
- data/lib/omnizip/commands/parity_create_command.rb +114 -0
- data/lib/omnizip/commands/parity_repair_command.rb +120 -0
- data/lib/omnizip/commands/parity_verify_command.rb +122 -0
- data/lib/omnizip/commands/profile_list_command.rb +54 -0
- data/lib/omnizip/commands/profile_show_command.rb +44 -0
- data/lib/omnizip/commands.rb +21 -0
- data/lib/omnizip/convenience.rb +389 -0
- data/lib/omnizip/converter/conversion_registry.rb +50 -0
- data/lib/omnizip/converter/conversion_strategy.rb +108 -0
- data/lib/omnizip/converter/extract_repack_strategy.rb +51 -0
- data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +43 -0
- data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +54 -0
- data/lib/omnizip/converter.rb +124 -0
- data/lib/omnizip/crypto/aes256/cipher.rb +104 -0
- data/lib/omnizip/crypto/aes256/constants.rb +28 -0
- data/lib/omnizip/crypto/aes256/key_derivation.rb +100 -0
- data/lib/omnizip/crypto/aes256.rb +102 -0
- data/lib/omnizip/crypto.rb +11 -0
- data/lib/omnizip/entry.rb +44 -0
- data/lib/omnizip/error.rb +110 -0
- data/lib/omnizip/eta/exponential_smoothing_estimator.rb +95 -0
- data/lib/omnizip/eta/moving_average_estimator.rb +96 -0
- data/lib/omnizip/eta/rate_calculator.rb +104 -0
- data/lib/omnizip/eta/sample_history.rb +143 -0
- data/lib/omnizip/eta/time_estimator.rb +106 -0
- data/lib/omnizip/eta.rb +68 -0
- data/lib/omnizip/extraction/filter_chain.rb +179 -0
- data/lib/omnizip/extraction/glob_pattern.rb +140 -0
- data/lib/omnizip/extraction/pattern_matcher.rb +66 -0
- data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
- data/lib/omnizip/extraction/regex_pattern.rb +50 -0
- data/lib/omnizip/extraction/selective_extractor.rb +247 -0
- data/lib/omnizip/extraction.rb +115 -0
- data/lib/omnizip/file_type/mime_classifier.rb +144 -0
- data/lib/omnizip/file_type.rb +117 -0
- data/lib/omnizip/filter.rb +141 -0
- data/lib/omnizip/filter_pipeline.rb +108 -0
- data/lib/omnizip/filter_registry.rb +113 -0
- data/lib/omnizip/filters/bcj.rb +277 -0
- data/lib/omnizip/filters/bcj2/constants.rb +53 -0
- data/lib/omnizip/filters/bcj2/decoder.rb +263 -0
- data/lib/omnizip/filters/bcj2/encoder.rb +58 -0
- data/lib/omnizip/filters/bcj2/stream_data.rb +91 -0
- data/lib/omnizip/filters/bcj2.rb +93 -0
- data/lib/omnizip/filters/bcj_arm.rb +174 -0
- data/lib/omnizip/filters/bcj_arm64.rb +242 -0
- data/lib/omnizip/filters/bcj_ia64.rb +194 -0
- data/lib/omnizip/filters/bcj_ppc.rb +188 -0
- data/lib/omnizip/filters/bcj_sparc.rb +174 -0
- data/lib/omnizip/filters/bcj_x86.rb +191 -0
- data/lib/omnizip/filters/delta.rb +195 -0
- data/lib/omnizip/filters/xz_delta.rb +258 -0
- data/lib/omnizip/filters.rb +20 -0
- data/lib/omnizip/format_detector.rb +166 -0
- data/lib/omnizip/formats/.keep +0 -0
- data/lib/omnizip/formats/bzip2_file.rb +159 -0
- data/lib/omnizip/formats/cpio/bounded_io.rb +66 -0
- data/lib/omnizip/formats/cpio/constants.rb +55 -0
- data/lib/omnizip/formats/cpio/entry.rb +389 -0
- data/lib/omnizip/formats/cpio/reader.rb +194 -0
- data/lib/omnizip/formats/cpio/writer.rb +232 -0
- data/lib/omnizip/formats/cpio.rb +132 -0
- data/lib/omnizip/formats/format_spec_loader.rb +228 -0
- data/lib/omnizip/formats/gzip.rb +236 -0
- data/lib/omnizip/formats/iso/directory_builder.rb +321 -0
- data/lib/omnizip/formats/iso/directory_record.rb +162 -0
- data/lib/omnizip/formats/iso/joliet.rb +204 -0
- data/lib/omnizip/formats/iso/path_table.rb +125 -0
- data/lib/omnizip/formats/iso/reader.rb +194 -0
- data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
- data/lib/omnizip/formats/iso/volume_builder.rb +319 -0
- data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
- data/lib/omnizip/formats/iso/writer.rb +543 -0
- data/lib/omnizip/formats/iso.rb +133 -0
- data/lib/omnizip/formats/lzip.rb +161 -0
- data/lib/omnizip/formats/lzma_alone.rb +149 -0
- data/lib/omnizip/formats/msi/cab_extractor.rb +181 -0
- data/lib/omnizip/formats/msi/constants.rb +157 -0
- data/lib/omnizip/formats/msi/directory_resolver.rb +188 -0
- data/lib/omnizip/formats/msi/entry.rb +134 -0
- data/lib/omnizip/formats/msi/reader.rb +301 -0
- data/lib/omnizip/formats/msi/string_pool.rb +246 -0
- data/lib/omnizip/formats/msi/table_parser.rb +244 -0
- data/lib/omnizip/formats/msi.rb +73 -0
- data/lib/omnizip/formats/ole/allocation_table.rb +263 -0
- data/lib/omnizip/formats/ole/constants.rb +61 -0
- data/lib/omnizip/formats/ole/dirent.rb +439 -0
- data/lib/omnizip/formats/ole/header.rb +199 -0
- data/lib/omnizip/formats/ole/ranges_io.rb +347 -0
- data/lib/omnizip/formats/ole/storage.rb +482 -0
- data/lib/omnizip/formats/ole/types/variant.rb +338 -0
- data/lib/omnizip/formats/ole.rb +143 -0
- data/lib/omnizip/formats/rar/archive_repairer.rb +240 -0
- data/lib/omnizip/formats/rar/archive_verifier.rb +192 -0
- data/lib/omnizip/formats/rar/block_parser.rb +282 -0
- data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
- data/lib/omnizip/formats/rar/compression/dispatcher.rb +210 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +212 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +154 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman.rb +25 -0
- data/lib/omnizip/formats/rar/compression/ppmd/context.rb +103 -0
- data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +238 -0
- data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +250 -0
- data/lib/omnizip/formats/rar/compression/ppmd.rb +16 -0
- data/lib/omnizip/formats/rar/compression.rb +17 -0
- data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
- data/lib/omnizip/formats/rar/constants.rb +88 -0
- data/lib/omnizip/formats/rar/decompressor.rb +316 -0
- data/lib/omnizip/formats/rar/external_writer.rb +311 -0
- data/lib/omnizip/formats/rar/header.rb +209 -0
- data/lib/omnizip/formats/rar/license_validator.rb +111 -0
- data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
- data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
- data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
- data/lib/omnizip/formats/rar/models.rb +14 -0
- data/lib/omnizip/formats/rar/parity_handler.rb +299 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +200 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +584 -0
- data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
- data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
- data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +96 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +162 -0
- data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
- data/lib/omnizip/formats/rar/rar5/header.rb +208 -0
- data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +260 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +176 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +108 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +139 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
- data/lib/omnizip/formats/rar/rar5/vint.rb +53 -0
- data/lib/omnizip/formats/rar/rar5/writer.rb +540 -0
- data/lib/omnizip/formats/rar/rar_format_base.rb +239 -0
- data/lib/omnizip/formats/rar/reader.rb +377 -0
- data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
- data/lib/omnizip/formats/rar/volume_manager.rb +166 -0
- data/lib/omnizip/formats/rar/writer.rb +437 -0
- data/lib/omnizip/formats/rar.rb +193 -0
- data/lib/omnizip/formats/rar3/compressor.rb +71 -0
- data/lib/omnizip/formats/rar3/decompressor.rb +64 -0
- data/lib/omnizip/formats/rar3/reader.rb +107 -0
- data/lib/omnizip/formats/rar3/writer.rb +220 -0
- data/lib/omnizip/formats/rar3.rb +15 -0
- data/lib/omnizip/formats/rar5/compressor.rb +71 -0
- data/lib/omnizip/formats/rar5/decompressor.rb +64 -0
- data/lib/omnizip/formats/rar5/reader.rb +130 -0
- data/lib/omnizip/formats/rar5/writer.rb +65 -0
- data/lib/omnizip/formats/rar5.rb +15 -0
- data/lib/omnizip/formats/rpm/constants.rb +58 -0
- data/lib/omnizip/formats/rpm/entry.rb +106 -0
- data/lib/omnizip/formats/rpm/header.rb +106 -0
- data/lib/omnizip/formats/rpm/lead.rb +132 -0
- data/lib/omnizip/formats/rpm/tag.rb +228 -0
- data/lib/omnizip/formats/rpm/writer.rb +652 -0
- data/lib/omnizip/formats/rpm.rb +458 -0
- data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +274 -0
- data/lib/omnizip/formats/seven_zip/coder_chain.rb +169 -0
- data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
- data/lib/omnizip/formats/seven_zip/encoded_header.rb +110 -0
- data/lib/omnizip/formats/seven_zip/encrypted_header.rb +139 -0
- data/lib/omnizip/formats/seven_zip/file_collector.rb +143 -0
- data/lib/omnizip/formats/seven_zip/header.rb +102 -0
- data/lib/omnizip/formats/seven_zip/header_encryptor.rb +132 -0
- data/lib/omnizip/formats/seven_zip/header_writer.rb +425 -0
- data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
- data/lib/omnizip/formats/seven_zip/models/file_entry.rb +65 -0
- data/lib/omnizip/formats/seven_zip/models/folder.rb +67 -0
- data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
- data/lib/omnizip/formats/seven_zip/models.rb +20 -0
- data/lib/omnizip/formats/seven_zip/parser.rb +671 -0
- data/lib/omnizip/formats/seven_zip/reader.rb +626 -0
- data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +611 -0
- data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +308 -0
- data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
- data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +166 -0
- data/lib/omnizip/formats/seven_zip/writer.rb +801 -0
- data/lib/omnizip/formats/seven_zip.rb +179 -0
- data/lib/omnizip/formats/tar/constants.rb +73 -0
- data/lib/omnizip/formats/tar/entry.rb +98 -0
- data/lib/omnizip/formats/tar/header.rb +206 -0
- data/lib/omnizip/formats/tar/reader.rb +119 -0
- data/lib/omnizip/formats/tar/writer.rb +212 -0
- data/lib/omnizip/formats/tar.rb +74 -0
- data/lib/omnizip/formats/xar/constants.rb +119 -0
- data/lib/omnizip/formats/xar/entry.rb +268 -0
- data/lib/omnizip/formats/xar/header.rb +223 -0
- data/lib/omnizip/formats/xar/reader.rb +400 -0
- data/lib/omnizip/formats/xar/toc.rb +570 -0
- data/lib/omnizip/formats/xar/writer.rb +461 -0
- data/lib/omnizip/formats/xar.rb +145 -0
- data/lib/omnizip/formats/xz/reader.rb +121 -0
- data/lib/omnizip/formats/xz/writer.rb +416 -0
- data/lib/omnizip/formats/xz.rb +210 -0
- data/lib/omnizip/formats/xz_const.rb +49 -0
- data/lib/omnizip/formats/xz_impl/block_decoder.rb +761 -0
- data/lib/omnizip/formats/xz_impl/block_encoder.rb +304 -0
- data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
- data/lib/omnizip/formats/xz_impl/block_header_parser.rb +182 -0
- data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
- data/lib/omnizip/formats/xz_impl/index_encoder.rb +120 -0
- data/lib/omnizip/formats/xz_impl/stream_decoder.rb +470 -0
- data/lib/omnizip/formats/xz_impl/stream_encoder.rb +95 -0
- data/lib/omnizip/formats/xz_impl/stream_footer.rb +79 -0
- data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +115 -0
- data/lib/omnizip/formats/xz_impl/stream_header.rb +53 -0
- data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +106 -0
- data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
- data/lib/omnizip/formats/xz_impl.rb +52 -0
- data/lib/omnizip/formats/zip/central_directory_header.rb +223 -0
- data/lib/omnizip/formats/zip/constants.rb +69 -0
- data/lib/omnizip/formats/zip/end_of_central_directory.rb +132 -0
- data/lib/omnizip/formats/zip/local_file_header.rb +136 -0
- data/lib/omnizip/formats/zip/reader.rb +376 -0
- data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
- data/lib/omnizip/formats/zip/writer.rb +489 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +102 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +64 -0
- data/lib/omnizip/formats/zip/zip64_extra_field.rb +112 -0
- data/lib/omnizip/formats/zip.rb +50 -0
- data/lib/omnizip/formats.rb +29 -0
- data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
- data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
- data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
- data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
- data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
- data/lib/omnizip/implementations/base.rb +19 -0
- data/lib/omnizip/implementations/rust/archive.rb +93 -0
- data/lib/omnizip/implementations/rust/library.rb +221 -0
- data/lib/omnizip/implementations/rust.rb +26 -0
- data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +428 -0
- data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +456 -0
- data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +285 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +197 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +194 -0
- data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +139 -0
- data/lib/omnizip/implementations/seven_zip/lzma.rb +21 -0
- data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +56 -0
- data/lib/omnizip/implementations/seven_zip/lzma2.rb +12 -0
- data/lib/omnizip/implementations/seven_zip.rb +11 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +547 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +748 -0
- data/lib/omnizip/implementations/xz_utils/lzma2.rb +13 -0
- data/lib/omnizip/implementations/xz_utils.rb +10 -0
- data/lib/omnizip/implementations.rb +25 -0
- data/lib/omnizip/io/buffered_input.rb +147 -0
- data/lib/omnizip/io/buffered_output.rb +106 -0
- data/lib/omnizip/io/source.rb +143 -0
- data/lib/omnizip/io/stream_manager.rb +117 -0
- data/lib/omnizip/io.rb +15 -0
- data/lib/omnizip/link_handler/hard_link.rb +79 -0
- data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
- data/lib/omnizip/link_handler.rb +129 -0
- data/lib/omnizip/metadata/archive_metadata.rb +114 -0
- data/lib/omnizip/metadata/entry_metadata.rb +153 -0
- data/lib/omnizip/metadata/metadata_editor.rb +169 -0
- data/lib/omnizip/metadata/metadata_registry.rb +71 -0
- data/lib/omnizip/metadata/metadata_validator.rb +101 -0
- data/lib/omnizip/metadata.rb +58 -0
- data/lib/omnizip/models/.keep +0 -0
- data/lib/omnizip/models/algorithm_metadata.rb +41 -0
- data/lib/omnizip/models/attribute_apply.rb +40 -0
- data/lib/omnizip/models/compression_options.rb +53 -0
- data/lib/omnizip/models/conversion_options.rb +79 -0
- data/lib/omnizip/models/conversion_result.rb +141 -0
- data/lib/omnizip/models/eta_result.rb +45 -0
- data/lib/omnizip/models/extraction_rule.rb +115 -0
- data/lib/omnizip/models/filter_chain.rb +142 -0
- data/lib/omnizip/models/filter_config.rb +148 -0
- data/lib/omnizip/models/match_result.rb +141 -0
- data/lib/omnizip/models/optimization_suggestion.rb +95 -0
- data/lib/omnizip/models/parallel_options.rb +116 -0
- data/lib/omnizip/models/performance_result.rb +85 -0
- data/lib/omnizip/models/profile_report.rb +116 -0
- data/lib/omnizip/models/progress_options.rb +39 -0
- data/lib/omnizip/models/split_options.rb +116 -0
- data/lib/omnizip/optimization_registry.rb +45 -0
- data/lib/omnizip/parallel/engine.rb +52 -0
- data/lib/omnizip/parallel/job_queue.rb +209 -0
- data/lib/omnizip/parallel/job_scheduler.rb +225 -0
- data/lib/omnizip/parallel/parallel_compressor.rb +326 -0
- data/lib/omnizip/parallel/parallel_extractor.rb +238 -0
- data/lib/omnizip/parallel/thread_pool.rb +60 -0
- data/lib/omnizip/parallel/worker_pool.rb +227 -0
- data/lib/omnizip/parallel.rb +156 -0
- data/lib/omnizip/parity/chunked_block_processor.rb +194 -0
- data/lib/omnizip/parity/galois16.rb +145 -0
- data/lib/omnizip/parity/models/creator_packet.rb +71 -0
- data/lib/omnizip/parity/models/file_description_packet.rb +131 -0
- data/lib/omnizip/parity/models/ifsc_packet.rb +111 -0
- data/lib/omnizip/parity/models/main_packet.rb +126 -0
- data/lib/omnizip/parity/models/packet.rb +156 -0
- data/lib/omnizip/parity/models/packet_registry.rb +102 -0
- data/lib/omnizip/parity/models/recovery_slice_packet.rb +76 -0
- data/lib/omnizip/parity/models.rb +27 -0
- data/lib/omnizip/parity/par2_creator.rb +496 -0
- data/lib/omnizip/parity/par2_repairer.rb +409 -0
- data/lib/omnizip/parity/par2_verifier.rb +373 -0
- data/lib/omnizip/parity/par2cmdline_algorithm.rb +108 -0
- data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
- data/lib/omnizip/parity/reed_solomon_decoder.rb +263 -0
- data/lib/omnizip/parity/reed_solomon_encoder.rb +108 -0
- data/lib/omnizip/parity/reed_solomon_matrix.rb +339 -0
- data/lib/omnizip/parity.rb +207 -0
- data/lib/omnizip/password/encryption_registry.rb +26 -0
- data/lib/omnizip/password/encryption_strategy.rb +96 -0
- data/lib/omnizip/password/password_validator.rb +129 -0
- data/lib/omnizip/password/winzip_aes_strategy.rb +190 -0
- data/lib/omnizip/password/zip_crypto_strategy.rb +135 -0
- data/lib/omnizip/password.rb +88 -0
- data/lib/omnizip/pipe/stream_compressor.rb +124 -0
- data/lib/omnizip/pipe/stream_decompressor.rb +173 -0
- data/lib/omnizip/pipe.rb +120 -0
- data/lib/omnizip/platform/ntfs_streams.rb +200 -0
- data/lib/omnizip/platform.rb +189 -0
- data/lib/omnizip/profile/archive_profile.rb +36 -0
- data/lib/omnizip/profile/balanced_profile.rb +31 -0
- data/lib/omnizip/profile/binary_profile.rb +33 -0
- data/lib/omnizip/profile/compression_profile.rb +157 -0
- data/lib/omnizip/profile/custom_profile.rb +155 -0
- data/lib/omnizip/profile/fast_profile.rb +31 -0
- data/lib/omnizip/profile/maximum_profile.rb +31 -0
- data/lib/omnizip/profile/profile_detector.rb +108 -0
- data/lib/omnizip/profile/profile_registry.rb +160 -0
- data/lib/omnizip/profile/text_profile.rb +33 -0
- data/lib/omnizip/profile.rb +261 -0
- data/lib/omnizip/profiler/memory_profiler.rb +66 -0
- data/lib/omnizip/profiler/method_profiler.rb +49 -0
- data/lib/omnizip/profiler/report_generator.rb +158 -0
- data/lib/omnizip/profiler.rb +192 -0
- data/lib/omnizip/progress/callback_reporter.rb +34 -0
- data/lib/omnizip/progress/console_reporter.rb +59 -0
- data/lib/omnizip/progress/log_reporter.rb +89 -0
- data/lib/omnizip/progress/operation_progress.rb +118 -0
- data/lib/omnizip/progress/progress_bar.rb +156 -0
- data/lib/omnizip/progress/progress_reporter.rb +40 -0
- data/lib/omnizip/progress/progress_tracker.rb +215 -0
- data/lib/omnizip/progress/silent_reporter.rb +22 -0
- data/lib/omnizip/progress.rb +131 -0
- data/lib/omnizip/registry.rb +111 -0
- data/lib/omnizip/rubyzip_compat.rb +61 -0
- data/lib/omnizip/temp/safe_extract.rb +124 -0
- data/lib/omnizip/temp/temp_file.rb +123 -0
- data/lib/omnizip/temp/temp_file_pool.rb +109 -0
- data/lib/omnizip/temp.rb +184 -0
- data/lib/omnizip/version.rb +5 -0
- data/lib/omnizip/zip/entry.rb +160 -0
- data/lib/omnizip/zip/file.rb +485 -0
- data/lib/omnizip/zip/input_stream.rb +270 -0
- data/lib/omnizip/zip/output_stream.rb +320 -0
- data/lib/omnizip/zip.rb +23 -0
- data/lib/omnizip.rb +157 -0
- data/lib/tasks/msi_test_files.rake +66 -0
- data/lib/tasks/platform_gems.rake +147 -0
- data/lib/tasks/rust_backend.rake +48 -0
- data/readme-docs/advanced-features.adoc +514 -0
- data/readme-docs/api-usage.adoc +445 -0
- data/readme-docs/architecture.adoc +450 -0
- data/readme-docs/archive-formats.adoc +479 -0
- data/readme-docs/cli-usage.adoc +222 -0
- data/readme-docs/compression-algorithms.adoc +446 -0
- data/readme-docs/compression-profiles.adoc +247 -0
- data/readme-docs/encryption-checksums.adoc +328 -0
- data/readme-docs/format-converter.adoc +316 -0
- data/readme-docs/installation.adoc +228 -0
- data/readme-docs/par2-archives.adoc +608 -0
- data/readme-docs/performance-profiler.adoc +389 -0
- data/readme-docs/preprocessing-filters.adoc +280 -0
- data/vendor/libomnizip_ffi.so +0 -0
- data/xz-file-format-1.2.1.txt +1174 -0
- metadata +768 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
# Archive format conversion module
|
|
5
|
+
# Provides conversion between different archive formats
|
|
6
|
+
module Converter
|
|
7
|
+
# Nested classes - autoloaded
|
|
8
|
+
autoload :ConversionStrategy, "omnizip/converter/conversion_strategy"
|
|
9
|
+
autoload :ZipToSevenZipStrategy,
|
|
10
|
+
"omnizip/converter/zip_to_seven_zip_strategy"
|
|
11
|
+
autoload :SevenZipToZipStrategy,
|
|
12
|
+
"omnizip/converter/seven_zip_to_zip_strategy"
|
|
13
|
+
autoload :ConversionRegistry, "omnizip/converter/conversion_registry"
|
|
14
|
+
autoload :ExtractRepackStrategy,
|
|
15
|
+
"omnizip/converter/extract_repack_strategy"
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
# Convert archive from one format to another
|
|
19
|
+
# @param source_path [String] Source archive path
|
|
20
|
+
# @param target_path [String] Target archive path
|
|
21
|
+
# @param options [Hash, ConversionOptions] Conversion options
|
|
22
|
+
# @return [ConversionResult] Conversion result
|
|
23
|
+
def convert(source_path, target_path, **options)
|
|
24
|
+
# Find appropriate strategy first
|
|
25
|
+
strategy_class = ConversionRegistry.find_strategy(source_path,
|
|
26
|
+
target_path)
|
|
27
|
+
unless strategy_class
|
|
28
|
+
raise ArgumentError, "No conversion strategy available for " \
|
|
29
|
+
"#{source_path} -> #{target_path}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Then validate input files
|
|
33
|
+
unless File.exist?(source_path)
|
|
34
|
+
raise Errno::ENOENT, "Source file not found: #{source_path}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Create options object
|
|
38
|
+
opts = options.is_a?(Models::ConversionOptions) ? options : create_options(**options)
|
|
39
|
+
opts.validate_options!
|
|
40
|
+
|
|
41
|
+
# Perform conversion
|
|
42
|
+
strategy = strategy_class.new(source_path, target_path, opts)
|
|
43
|
+
result = strategy.convert
|
|
44
|
+
|
|
45
|
+
# Delete source if requested
|
|
46
|
+
File.delete(source_path) if opts.delete_source && File.exist?(source_path)
|
|
47
|
+
|
|
48
|
+
result
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Convert with explicit options object
|
|
52
|
+
# @param source_path [String] Source archive path
|
|
53
|
+
# @param target_path [String] Target archive path
|
|
54
|
+
# @param options [ConversionOptions] Conversion options
|
|
55
|
+
# @return [ConversionResult] Conversion result
|
|
56
|
+
def convert_with_options(source_path, target_path, options)
|
|
57
|
+
convert(source_path, target_path, options)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Check if conversion is supported
|
|
61
|
+
# @param source_path [String] Source archive path
|
|
62
|
+
# @param target_path [String] Target archive path
|
|
63
|
+
# @return [Boolean] True if conversion is supported
|
|
64
|
+
def supported?(source_path, target_path)
|
|
65
|
+
ConversionRegistry.supported?(source_path, target_path)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Get available conversion strategies
|
|
69
|
+
# @return [Array<Class>] List of strategy classes
|
|
70
|
+
def strategies
|
|
71
|
+
ConversionRegistry.strategies
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Batch convert multiple archives
|
|
75
|
+
# @param sources [Array<String>] Source file paths
|
|
76
|
+
# @param target_format [Symbol] Target format (:zip or :seven_zip)
|
|
77
|
+
# @param options [Hash] Conversion options
|
|
78
|
+
# @yield [result] Optional block called for each conversion
|
|
79
|
+
# @return [Array<ConversionResult>] Conversion results
|
|
80
|
+
def batch_convert(sources, target_format: :seven_zip, **options, &block)
|
|
81
|
+
results = []
|
|
82
|
+
|
|
83
|
+
sources.each do |source|
|
|
84
|
+
target = generate_target_path(source, target_format)
|
|
85
|
+
result = convert(source, target, target_format: target_format,
|
|
86
|
+
**options)
|
|
87
|
+
results << result
|
|
88
|
+
yield(result) if block
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
results
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
# Build a ConversionOptions model from caller-supplied keywords.
|
|
97
|
+
#
|
|
98
|
+
# lutaml-model silently discards unknown constructor keys, so a
|
|
99
|
+
# mistyped option (e.g. +level:+ instead of +compression_level:+)
|
|
100
|
+
# would fall back to defaults without warning. Reject unknown keys
|
|
101
|
+
# up front instead.
|
|
102
|
+
#
|
|
103
|
+
# @raise [ArgumentError] if any key is not a declared attribute
|
|
104
|
+
def create_options(**options)
|
|
105
|
+
known = Models::ConversionOptions.attributes.keys.map(&:to_sym)
|
|
106
|
+
unknown = options.keys.map(&:to_sym) - known
|
|
107
|
+
unless unknown.empty?
|
|
108
|
+
raise ArgumentError,
|
|
109
|
+
"Unknown option(s): #{unknown.join(', ')}. " \
|
|
110
|
+
"Valid options: #{known.join(', ')}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
Models::ConversionOptions.new(**options)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def generate_target_path(source, target_format)
|
|
117
|
+
base = File.basename(source, File.extname(source))
|
|
118
|
+
dir = File.dirname(source)
|
|
119
|
+
ext = target_format == :seven_zip ? ".7z" : ".zip"
|
|
120
|
+
File.join(dir, base + ext)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
4
|
+
|
|
5
|
+
require "openssl"
|
|
6
|
+
|
|
7
|
+
module Omnizip
|
|
8
|
+
module Crypto
|
|
9
|
+
class Aes256
|
|
10
|
+
# AES-256-CBC cipher operations
|
|
11
|
+
#
|
|
12
|
+
# Wraps OpenSSL's AES-256-CBC implementation with proper
|
|
13
|
+
# padding and error handling for 7-Zip compatibility.
|
|
14
|
+
class Cipher
|
|
15
|
+
include Constants
|
|
16
|
+
|
|
17
|
+
attr_reader :key, :iv
|
|
18
|
+
|
|
19
|
+
# Initialize cipher with key and IV
|
|
20
|
+
#
|
|
21
|
+
# @param key [String] 32-byte AES-256 key
|
|
22
|
+
# @param iv [String] 16-byte initialization vector
|
|
23
|
+
def initialize(key, iv)
|
|
24
|
+
validate_key_iv(key, iv)
|
|
25
|
+
@key = key
|
|
26
|
+
@iv = iv
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Encrypt data using AES-256-CBC
|
|
30
|
+
#
|
|
31
|
+
# @param plaintext [String] Data to encrypt
|
|
32
|
+
# @return [String] Encrypted data
|
|
33
|
+
def encrypt(plaintext)
|
|
34
|
+
cipher = create_cipher(:encrypt)
|
|
35
|
+
|
|
36
|
+
# Handle empty data - just call final() for padding
|
|
37
|
+
if plaintext.empty?
|
|
38
|
+
return cipher.final
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
result = cipher.update(plaintext)
|
|
42
|
+
result << cipher.final
|
|
43
|
+
|
|
44
|
+
result
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Decrypt data using AES-256-CBC
|
|
48
|
+
#
|
|
49
|
+
# @param ciphertext [String] Encrypted data
|
|
50
|
+
# @return [String] Decrypted data
|
|
51
|
+
def decrypt(ciphertext)
|
|
52
|
+
cipher = create_cipher(:decrypt)
|
|
53
|
+
|
|
54
|
+
# Handle empty or very small ciphertext
|
|
55
|
+
if ciphertext.empty?
|
|
56
|
+
return ""
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
result = cipher.update(ciphertext)
|
|
60
|
+
result << cipher.final
|
|
61
|
+
|
|
62
|
+
result
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
# Validate key and IV parameters
|
|
68
|
+
#
|
|
69
|
+
# @param key [String] Key to validate
|
|
70
|
+
# @param iv [String] IV to validate
|
|
71
|
+
# @return [void]
|
|
72
|
+
# @raise [ArgumentError] If key or IV invalid
|
|
73
|
+
def validate_key_iv(key, iv)
|
|
74
|
+
if key.bytesize != KEY_SIZE
|
|
75
|
+
raise ArgumentError,
|
|
76
|
+
"Key must be #{KEY_SIZE} bytes"
|
|
77
|
+
end
|
|
78
|
+
return unless iv.bytesize != IV_SIZE
|
|
79
|
+
|
|
80
|
+
raise ArgumentError,
|
|
81
|
+
"IV must be #{IV_SIZE} bytes"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Create OpenSSL cipher instance
|
|
85
|
+
#
|
|
86
|
+
# @param mode [Symbol] :encrypt or :decrypt
|
|
87
|
+
# @return [OpenSSL::Cipher] Configured cipher
|
|
88
|
+
def create_cipher(mode)
|
|
89
|
+
cipher = OpenSSL::Cipher.new("AES-256-CBC")
|
|
90
|
+
case mode
|
|
91
|
+
when :encrypt then cipher.encrypt
|
|
92
|
+
when :decrypt then cipher.decrypt
|
|
93
|
+
else
|
|
94
|
+
raise ArgumentError, "Unknown cipher mode: #{mode.inspect}"
|
|
95
|
+
end
|
|
96
|
+
cipher.key = @key # Then set key
|
|
97
|
+
cipher.iv = @iv # Then set IV
|
|
98
|
+
cipher.padding = 1 # PKCS7 padding
|
|
99
|
+
cipher
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
4
|
+
|
|
5
|
+
module Omnizip
|
|
6
|
+
module Crypto
|
|
7
|
+
class Aes256
|
|
8
|
+
# Constants for AES-256 encryption in 7-Zip format
|
|
9
|
+
module Constants
|
|
10
|
+
# Key size for AES-256 (32 bytes = 256 bits)
|
|
11
|
+
KEY_SIZE = 32
|
|
12
|
+
|
|
13
|
+
# Maximum salt size (16 bytes)
|
|
14
|
+
SALT_SIZE_MAX = 16
|
|
15
|
+
SALT_SIZE = 16
|
|
16
|
+
|
|
17
|
+
# IV size (16 bytes = AES block size)
|
|
18
|
+
IV_SIZE = 16
|
|
19
|
+
BLOCK_SIZE = 16
|
|
20
|
+
|
|
21
|
+
# Default number of SHA-256 cycles (2^19 = 524288)
|
|
22
|
+
DEFAULT_CYCLES_POWER = 19
|
|
23
|
+
MIN_CYCLES_POWER = 0
|
|
24
|
+
MAX_CYCLES_POWER = 24
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
4
|
+
|
|
5
|
+
require "digest/sha2"
|
|
6
|
+
|
|
7
|
+
module Omnizip
|
|
8
|
+
module Crypto
|
|
9
|
+
class Aes256
|
|
10
|
+
# 7-Zip password-based key derivation
|
|
11
|
+
#
|
|
12
|
+
# Uses SHA-256 iterative hashing to derive encryption keys
|
|
13
|
+
# from passwords. The number of iterations is 2^cycles_power.
|
|
14
|
+
class KeyDerivation
|
|
15
|
+
include Constants
|
|
16
|
+
|
|
17
|
+
# Derive AES-256 key from password
|
|
18
|
+
#
|
|
19
|
+
# This implements 7-Zip's key derivation:
|
|
20
|
+
# 1. Concatenate salt and password
|
|
21
|
+
# 2. Hash with SHA-256 for 2^cycles_power iterations
|
|
22
|
+
# 3. Extract first 32 bytes as key
|
|
23
|
+
#
|
|
24
|
+
# @param password [String] User password
|
|
25
|
+
# @param salt [String] Random salt
|
|
26
|
+
# @param cycles_power [Integer] Power of 2 for iterations
|
|
27
|
+
# @return [String] 32-byte AES-256 key
|
|
28
|
+
def self.derive_key(password, salt, cycles_power = DEFAULT_CYCLES_POWER)
|
|
29
|
+
validate_inputs(password, salt, cycles_power)
|
|
30
|
+
|
|
31
|
+
# Calculate number of iterations
|
|
32
|
+
num_cycles = 1 << cycles_power
|
|
33
|
+
|
|
34
|
+
# Initial input: salt + password (in UTF-16LE for 7-Zip compat)
|
|
35
|
+
# Force binary encoding to make concatenation work
|
|
36
|
+
encoded_password = encode_password(password).force_encoding(Encoding::BINARY)
|
|
37
|
+
input = salt.dup.force_encoding(Encoding::BINARY) + encoded_password
|
|
38
|
+
|
|
39
|
+
# Iterative SHA-256 hashing
|
|
40
|
+
key = perform_hashing(input, num_cycles)
|
|
41
|
+
|
|
42
|
+
# Return first 32 bytes
|
|
43
|
+
key[0, KEY_SIZE]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Validate key derivation inputs
|
|
47
|
+
#
|
|
48
|
+
# @param password [String] Password to validate
|
|
49
|
+
# @param salt [String] Salt to validate
|
|
50
|
+
# @param cycles_power [Integer] Cycles power to validate
|
|
51
|
+
# @return [void]
|
|
52
|
+
# @raise [ArgumentError] If inputs are invalid
|
|
53
|
+
def self.validate_inputs(password, salt, cycles_power)
|
|
54
|
+
if password.nil? || password.empty?
|
|
55
|
+
raise ArgumentError,
|
|
56
|
+
"Password cannot be empty"
|
|
57
|
+
end
|
|
58
|
+
if salt.bytesize != SALT_SIZE
|
|
59
|
+
raise ArgumentError,
|
|
60
|
+
"Salt must be #{SALT_SIZE} bytes"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
return if cycles_power.between?(MIN_CYCLES_POWER, MAX_CYCLES_POWER)
|
|
64
|
+
|
|
65
|
+
raise ArgumentError,
|
|
66
|
+
"Cycles power must be between #{MIN_CYCLES_POWER} and #{MAX_CYCLES_POWER}"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Encode password to UTF-16LE (7-Zip format)
|
|
70
|
+
#
|
|
71
|
+
# @param password [String] Password in any encoding
|
|
72
|
+
# @return [String] UTF-16LE encoded password
|
|
73
|
+
def self.encode_password(password)
|
|
74
|
+
password.encode(Encoding::UTF_16LE)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Perform iterative SHA-256 hashing
|
|
78
|
+
#
|
|
79
|
+
# @param input [String] Initial input (salt + password)
|
|
80
|
+
# @param num_cycles [Integer] Number of hash iterations
|
|
81
|
+
# @return [String] Final hash result
|
|
82
|
+
def self.perform_hashing(input, num_cycles)
|
|
83
|
+
digest = Digest::SHA256.new
|
|
84
|
+
result = input
|
|
85
|
+
|
|
86
|
+
num_cycles.times do
|
|
87
|
+
digest.reset
|
|
88
|
+
digest << result
|
|
89
|
+
result = digest.digest
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
result
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
private_class_method :validate_inputs, :encode_password,
|
|
96
|
+
:perform_hashing
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
6
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
7
|
+
# to deal in the Software without restriction, including without limitation
|
|
8
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
9
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
10
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
|
13
|
+
# all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
20
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
21
|
+
# DEALINGS IN THE SOFTWARE.
|
|
22
|
+
|
|
23
|
+
require "openssl"
|
|
24
|
+
require "digest/sha2"
|
|
25
|
+
|
|
26
|
+
module Omnizip
|
|
27
|
+
module Crypto
|
|
28
|
+
# AES-256 encryption for 7-Zip archives
|
|
29
|
+
#
|
|
30
|
+
# Implements 7-Zip's AES-256-CBC encryption with:
|
|
31
|
+
# - Password-based key derivation (SHA-256)
|
|
32
|
+
# - Configurable salt and cycles
|
|
33
|
+
# - CBC mode with IV
|
|
34
|
+
#
|
|
35
|
+
# This follows 7-Zip's encryption specification.
|
|
36
|
+
class Aes256
|
|
37
|
+
autoload :Constants, "omnizip/crypto/aes256/constants"
|
|
38
|
+
autoload :KeyDerivation, "omnizip/crypto/aes256/key_derivation"
|
|
39
|
+
autoload :Cipher, "omnizip/crypto/aes256/cipher"
|
|
40
|
+
include Constants
|
|
41
|
+
|
|
42
|
+
# Encrypt data with AES-256
|
|
43
|
+
#
|
|
44
|
+
# @param data [String] Data to encrypt
|
|
45
|
+
# @param password [String] Encryption password
|
|
46
|
+
# @param options [Hash] Encryption options
|
|
47
|
+
# @option options [Integer] :num_cycles_power Power of 2 for key
|
|
48
|
+
# derivation iterations
|
|
49
|
+
# @option options [String] :salt Random salt (auto-generated if nil)
|
|
50
|
+
# @option options [String] :iv Initialization vector
|
|
51
|
+
# (auto-generated if nil)
|
|
52
|
+
# @return [Hash] Encrypted data with metadata
|
|
53
|
+
def self.encrypt(data, password, options = {})
|
|
54
|
+
salt = options[:salt] || generate_salt
|
|
55
|
+
iv = options[:iv] || generate_iv
|
|
56
|
+
cycles_power = options[:num_cycles_power] || DEFAULT_CYCLES_POWER
|
|
57
|
+
|
|
58
|
+
key = KeyDerivation.derive_key(password, salt, cycles_power)
|
|
59
|
+
cipher = Cipher.new(key, iv)
|
|
60
|
+
|
|
61
|
+
encrypted_data = cipher.encrypt(data)
|
|
62
|
+
|
|
63
|
+
{
|
|
64
|
+
data: encrypted_data,
|
|
65
|
+
salt: salt,
|
|
66
|
+
iv: iv,
|
|
67
|
+
cycles_power: cycles_power,
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Decrypt data with AES-256
|
|
72
|
+
#
|
|
73
|
+
# @param encrypted_data [String] Encrypted data
|
|
74
|
+
# @param password [String] Decryption password
|
|
75
|
+
# @param salt [String] Salt used during encryption
|
|
76
|
+
# @param iv [String] IV used during encryption
|
|
77
|
+
# @param cycles_power [Integer] Cycles power used during encryption
|
|
78
|
+
# @return [String] Decrypted data
|
|
79
|
+
def self.decrypt(encrypted_data, password, salt, iv, cycles_power)
|
|
80
|
+
key = KeyDerivation.derive_key(password, salt, cycles_power)
|
|
81
|
+
cipher = Cipher.new(key, iv)
|
|
82
|
+
|
|
83
|
+
cipher.decrypt(encrypted_data)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Generate random salt
|
|
87
|
+
#
|
|
88
|
+
# @param size [Integer] Salt size in bytes (default 16)
|
|
89
|
+
# @return [String] Random salt
|
|
90
|
+
def self.generate_salt(size = SALT_SIZE)
|
|
91
|
+
OpenSSL::Random.random_bytes(size)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Generate random IV
|
|
95
|
+
#
|
|
96
|
+
# @return [String] Random IV
|
|
97
|
+
def self.generate_iv
|
|
98
|
+
OpenSSL::Random.random_bytes(IV_SIZE)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
# Cryptographic utilities module
|
|
5
|
+
#
|
|
6
|
+
# Provides encryption and decryption capabilities for archive formats
|
|
7
|
+
# that support password protection.
|
|
8
|
+
module Crypto
|
|
9
|
+
autoload :Aes256, "omnizip/crypto/aes256"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
# Mix-in that establishes the common contract every archive entry
|
|
5
|
+
# satisfies, regardless of format.
|
|
6
|
+
#
|
|
7
|
+
# Each format-specific entry class (Zip::Entry, Tar::Entry,
|
|
8
|
+
# SevenZip::Models::FileEntry, Iso::DirectoryRecord, Ole::Dirent,
|
|
9
|
+
# Xar::Entry, Rpm::Entry, Msi::Entry, Cpio::Entry, Rar3::Entry,
|
|
10
|
+
# Rar5::Entry, Metadata::EntryMetadata) includes this
|
|
11
|
+
# module so callers can rely on a single narrow interface instead
|
|
12
|
+
# of duck-typing through `respond_to?(:name) / :path / :filename`
|
|
13
|
+
# cascades.
|
|
14
|
+
#
|
|
15
|
+
# Including classes MUST override the four methods below. The
|
|
16
|
+
# defaults raise `NotImplementedError` to surface missing
|
|
17
|
+
# implementations at call time rather than at include time.
|
|
18
|
+
module Entry
|
|
19
|
+
# @return [String, nil] in-archive path, or nil if the entry has
|
|
20
|
+
# no name (e.g. empty anti-entry)
|
|
21
|
+
def entry_name
|
|
22
|
+
raise NotImplementedError,
|
|
23
|
+
"#{self.class} must implement #entry_name"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @return [Boolean] true if the entry is a directory
|
|
27
|
+
def entry_directory?
|
|
28
|
+
raise NotImplementedError,
|
|
29
|
+
"#{self.class} must implement #entry_directory?"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @return [Integer, nil] uncompressed size in bytes
|
|
33
|
+
def entry_size
|
|
34
|
+
raise NotImplementedError,
|
|
35
|
+
"#{self.class} must implement #entry_size"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @return [Time, nil] modification time
|
|
39
|
+
def entry_mtime
|
|
40
|
+
raise NotImplementedError,
|
|
41
|
+
"#{self.class} must implement #entry_mtime"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2025 Ribose Inc.
|
|
4
|
+
|
|
5
|
+
module Omnizip
|
|
6
|
+
class Error < StandardError
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class CompressionError < Error
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class DecompressionError < Error
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class AlgorithmNotFoundError < Error
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Canonical alias of +AlgorithmNotFoundError+. Older code referenced
|
|
19
|
+
# +UnknownAlgorithmError+; both names are kept for backward
|
|
20
|
+
# compatibility.
|
|
21
|
+
UnknownAlgorithmError = AlgorithmNotFoundError
|
|
22
|
+
|
|
23
|
+
class UnknownChecksumError < Error
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class UnknownFilterError < Error
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class UnknownEncryptionStrategyError < Error
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class ConversionNotSupportedError < Error
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class UnsupportedFormatError < Error
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class FormatError < Error
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class InvalidArchiveError < Error
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Renamed from +IOError+ to avoid shadowing Ruby's built-in IOError.
|
|
45
|
+
# The legacy name is kept as an alias.
|
|
46
|
+
class IOOperationError < Error
|
|
47
|
+
end
|
|
48
|
+
IOError = IOOperationError
|
|
49
|
+
|
|
50
|
+
class ChecksumError < Error
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Canonical name. +OptimizationNotFound+ kept as alias.
|
|
54
|
+
class OptimizationNotFoundError < Error
|
|
55
|
+
end
|
|
56
|
+
OptimizationNotFound = OptimizationNotFoundError
|
|
57
|
+
|
|
58
|
+
class ProgressError < Error
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
class ETAError < Error
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class NotLicensedError < Error
|
|
65
|
+
def initialize(message = default_message)
|
|
66
|
+
super
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
def default_message
|
|
72
|
+
<<~MSG
|
|
73
|
+
RAR creation requires a licensed copy of WinRAR.
|
|
74
|
+
|
|
75
|
+
To use RAR creation:
|
|
76
|
+
1. Purchase a WinRAR license from https://www.rarlab.com/
|
|
77
|
+
2. Install WinRAR on your system
|
|
78
|
+
3. Confirm license ownership when prompted
|
|
79
|
+
|
|
80
|
+
Alternatively, use 7z format which provides similar compression
|
|
81
|
+
with no licensing restrictions:
|
|
82
|
+
|
|
83
|
+
Omnizip::Formats::SevenZip.create('archive.7z') do |sz|
|
|
84
|
+
sz.add_directory('files/')
|
|
85
|
+
end
|
|
86
|
+
MSG
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
class RarNotAvailableError < Error
|
|
91
|
+
def initialize(message = default_message)
|
|
92
|
+
super
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
private
|
|
96
|
+
|
|
97
|
+
def default_message
|
|
98
|
+
<<~MSG
|
|
99
|
+
WinRAR executable not found.
|
|
100
|
+
|
|
101
|
+
Please install WinRAR:
|
|
102
|
+
- Windows: Download from https://www.rarlab.com/
|
|
103
|
+
- Linux: Install 'rar' package (requires license)
|
|
104
|
+
- macOS: Install via Homebrew: brew install rar (requires license)
|
|
105
|
+
|
|
106
|
+
After installation, ensure 'rar' or 'Rar.exe' is in your PATH.
|
|
107
|
+
MSG
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|