omnizip 0.4.7-aarch64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +32 -0
- data/.rubocop_todo.yml +293 -0
- data/CHANGELOG.md +1647 -0
- data/CONTEXT.md +68 -0
- data/COPYING +502 -0
- data/Gemfile +19 -0
- data/LICENSE +12 -0
- data/README.adoc +1327 -0
- data/Rakefile +15 -0
- data/TODO.refactor/00-overview.md +67 -0
- data/TODO.refactor/01-registry-base-class.md +81 -0
- data/TODO.refactor/02-error-hierarchy.md +57 -0
- data/TODO.refactor/03-autoload-entry-point.md +69 -0
- data/TODO.refactor/04-filter-base-consolidation.md +49 -0
- data/TODO.refactor/05-send-private-methods.md +64 -0
- data/TODO.refactor/06-instance-variable-access.md +69 -0
- data/TODO.refactor/07-respond-to-replacement.md +237 -0
- data/TODO.refactor/08-spec-doubles.md +27 -0
- data/TODO.refactor/09-cli-shared-module.md +35 -0
- data/TODO.refactor/10-format-detector-ocp.md +34 -0
- data/TODO.refactor/11-convenience-decoupling.md +38 -0
- data/TODO.refactor/12-thread-safety.md +8 -0
- data/TODO.refactor/13-lutaml-model-migration.md +158 -0
- data/TODO.refactor/14-add-missing-specs.md +25 -0
- data/benchmark/README.md +260 -0
- data/benchmark/benchmark_suite.rb +125 -0
- data/benchmark/compression_bench.rb +181 -0
- data/benchmark/filter_bench.rb +180 -0
- data/benchmark/models/benchmark_result.rb +59 -0
- data/benchmark/models/comparison_result.rb +69 -0
- data/benchmark/profile_suite.rb +167 -0
- data/benchmark/reporter.rb +150 -0
- data/benchmark/run_benchmarks.rb +66 -0
- data/benchmark/test_data.rb +137 -0
- data/config/formats/rar3_spec.yml +92 -0
- data/config/formats/rar5_spec.yml +102 -0
- data/docs/.github/workflows/docs.yml +142 -0
- data/docs/.gitignore +21 -0
- data/docs/.lychee.toml +67 -0
- data/docs/Gemfile +13 -0
- data/docs/RAR_WRITE_SUPPORT.md +26 -0
- data/docs/README.md +101 -0
- data/docs/_config.yml +112 -0
- data/docs/assets/logo.svg +1 -0
- data/docs/assets/omnizip-logo.pdf +1540 -11
- data/docs/comparison/feature-matrix.adoc +694 -0
- data/docs/comparison/index.adoc +113 -0
- data/docs/comparison/vs-7zip.adoc +309 -0
- data/docs/comparison/vs-peazip.adoc +77 -0
- data/docs/comparison/vs-rubyzip.adoc +342 -0
- data/docs/comparison/vs-winrar.adoc +100 -0
- data/docs/compatibility.adoc +579 -0
- data/docs/concepts/index.adoc +129 -0
- data/docs/developer/architecture.adoc +256 -0
- data/docs/developer/contributing.adoc +158 -0
- data/docs/developer/index.adoc +25 -0
- data/docs/developer/testing.adoc +212 -0
- data/docs/getting-started/basic-usage.adoc +263 -0
- data/docs/getting-started/index.adoc +42 -0
- data/docs/getting-started/installation.adoc +138 -0
- data/docs/getting-started/quick-start.adoc +183 -0
- data/docs/getting-started/your-first-archive.adoc +219 -0
- data/docs/guides/advanced-features/encryption.adoc +277 -0
- data/docs/guides/advanced-features/index.adoc +59 -0
- data/docs/guides/advanced-features/parallel-processing.adoc +144 -0
- data/docs/guides/advanced-features/progress-tracking.adoc +124 -0
- data/docs/guides/advanced-features/streaming.adoc +142 -0
- data/docs/guides/archive-formats/gzip-format.adoc +105 -0
- data/docs/guides/archive-formats/index.adoc +160 -0
- data/docs/guides/archive-formats/ole-format.adoc +151 -0
- data/docs/guides/archive-formats/rar-format.adoc +104 -0
- data/docs/guides/archive-formats/rar5.adoc +521 -0
- data/docs/guides/archive-formats/rpm-format.adoc +108 -0
- data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
- data/docs/guides/archive-formats/tar-format.adoc +106 -0
- data/docs/guides/archive-formats/xz-format.adoc +118 -0
- data/docs/guides/archive-formats/zip-format.adoc +35 -0
- data/docs/guides/compression-algorithms/bzip2.adoc +114 -0
- data/docs/guides/compression-algorithms/deflate.adoc +313 -0
- data/docs/guides/compression-algorithms/index.adoc +190 -0
- data/docs/guides/compression-algorithms/lzma.adoc +394 -0
- data/docs/guides/compression-algorithms/lzma2.adoc +244 -0
- data/docs/guides/compression-algorithms/ppmd.adoc +313 -0
- data/docs/guides/compression-algorithms/zstandard.adoc +296 -0
- data/docs/guides/creating-archives.adoc +348 -0
- data/docs/guides/extracting-archives.adoc +53 -0
- data/docs/guides/format-conversion.adoc +64 -0
- data/docs/guides/index.adoc +49 -0
- data/docs/guides/migration-rubyzip.adoc +217 -0
- data/docs/guides/parity-archives.adoc +605 -0
- data/docs/guides/performance-tuning.adoc +88 -0
- data/docs/index.adoc +228 -0
- data/docs/lychee.toml +67 -0
- data/docs/reference/api/overview.adoc +187 -0
- data/docs/reference/cli/compress-command.adoc +114 -0
- data/docs/reference/cli/overview.adoc +140 -0
- data/docs/reference/index.adoc +26 -0
- data/docs/resources/faq.adoc +185 -0
- data/docs/resources/quick-reference.adoc +222 -0
- data/docs/rust-backend.md +0 -0
- data/docs/troubleshooting/index.adoc +207 -0
- data/docs/xar_format.md +216 -0
- data/examples/api_comparison.rb +205 -0
- data/examples/deflate64_example.rb +96 -0
- data/examples/par2_demo.rb +121 -0
- data/examples/quick_start_native.rb +150 -0
- data/examples/quick_start_rubyzip.rb +115 -0
- data/examples/rubyzip_compatibility_demo.rb +194 -0
- data/exe/omnizip +27 -0
- data/lib/omnizip/algorithm.rb +176 -0
- data/lib/omnizip/algorithm_registry.rb +65 -0
- data/lib/omnizip/algorithms/.keep +0 -0
- data/lib/omnizip/algorithms/bzip2/bwt.rb +236 -0
- data/lib/omnizip/algorithms/bzip2/bz2.rb +687 -0
- data/lib/omnizip/algorithms/bzip2/rle.rb +146 -0
- data/lib/omnizip/algorithms/bzip2.rb +108 -0
- data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
- data/lib/omnizip/algorithms/deflate/decoder.rb +37 -0
- data/lib/omnizip/algorithms/deflate/encoder.rb +45 -0
- data/lib/omnizip/algorithms/deflate.rb +135 -0
- data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
- data/lib/omnizip/algorithms/deflate64/decoder.rb +151 -0
- data/lib/omnizip/algorithms/deflate64/encoder.rb +95 -0
- data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +352 -0
- data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +140 -0
- data/lib/omnizip/algorithms/deflate64.rb +118 -0
- data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
- data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
- data/lib/omnizip/algorithms/lzma/decoder.rb +146 -0
- data/lib/omnizip/algorithms/lzma/dictionary.rb +70 -0
- data/lib/omnizip/algorithms/lzma/distance_coder.rb +326 -0
- data/lib/omnizip/algorithms/lzma/encoder.rb +139 -0
- data/lib/omnizip/algorithms/lzma/length_coder.rb +172 -0
- data/lib/omnizip/algorithms/lzma/literal_decoder.rb +204 -0
- data/lib/omnizip/algorithms/lzma/literal_encoder.rb +208 -0
- data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +368 -0
- data/lib/omnizip/algorithms/lzma/lzma1_encoder.rb +105 -0
- data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +194 -0
- data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
- data/lib/omnizip/algorithms/lzma/match.rb +32 -0
- data/lib/omnizip/algorithms/lzma/match_finder.rb +233 -0
- data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
- data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +84 -0
- data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +159 -0
- data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
- data/lib/omnizip/algorithms/lzma/range_coder.rb +82 -0
- data/lib/omnizip/algorithms/lzma/range_decoder.rb +274 -0
- data/lib/omnizip/algorithms/lzma/range_encoder.rb +202 -0
- data/lib/omnizip/algorithms/lzma/state.rb +127 -0
- data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +323 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder.rb +420 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +640 -0
- data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +224 -0
- data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +167 -0
- data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +258 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +314 -0
- data/lib/omnizip/algorithms/lzma/xz_state.rb +108 -0
- data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +1311 -0
- data/lib/omnizip/algorithms/lzma.rb +266 -0
- data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +180 -0
- data/lib/omnizip/algorithms/lzma2/constants.rb +38 -0
- data/lib/omnizip/algorithms/lzma2/encoder.rb +145 -0
- data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +165 -0
- data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
- data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +122 -0
- data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
- data/lib/omnizip/algorithms/lzma2.rb +133 -0
- data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
- data/lib/omnizip/algorithms/ppmd7/context.rb +151 -0
- data/lib/omnizip/algorithms/ppmd7/decoder.rb +127 -0
- data/lib/omnizip/algorithms/ppmd7/encoder.rb +153 -0
- data/lib/omnizip/algorithms/ppmd7/model.rb +245 -0
- data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
- data/lib/omnizip/algorithms/ppmd7.rb +146 -0
- data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
- data/lib/omnizip/algorithms/ppmd8/context.rb +32 -0
- data/lib/omnizip/algorithms/ppmd8/decoder.rb +104 -0
- data/lib/omnizip/algorithms/ppmd8/encoder.rb +135 -0
- data/lib/omnizip/algorithms/ppmd8/model.rb +246 -0
- data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
- data/lib/omnizip/algorithms/ppmd8.rb +122 -0
- data/lib/omnizip/algorithms/ppmd_base.rb +142 -0
- data/lib/omnizip/algorithms/registration.rb +28 -0
- data/lib/omnizip/algorithms/zstandard/constants.rb +158 -0
- data/lib/omnizip/algorithms/zstandard/decoder.rb +249 -0
- data/lib/omnizip/algorithms/zstandard/dictionary.rb +73 -0
- data/lib/omnizip/algorithms/zstandard/encoder.rb +294 -0
- data/lib/omnizip/algorithms/zstandard/frame/block.rb +143 -0
- data/lib/omnizip/algorithms/zstandard/frame/header.rb +233 -0
- data/lib/omnizip/algorithms/zstandard/frame.rb +33 -0
- data/lib/omnizip/algorithms/zstandard/fse/bitstream.rb +183 -0
- data/lib/omnizip/algorithms/zstandard/fse/encoder.rb +534 -0
- data/lib/omnizip/algorithms/zstandard/fse/interleaved.rb +92 -0
- data/lib/omnizip/algorithms/zstandard/fse/table.rb +188 -0
- data/lib/omnizip/algorithms/zstandard/fse/table_description.rb +203 -0
- data/lib/omnizip/algorithms/zstandard/fse.rb +53 -0
- data/lib/omnizip/algorithms/zstandard/huffman.rb +276 -0
- data/lib/omnizip/algorithms/zstandard/huffman_encoder.rb +327 -0
- data/lib/omnizip/algorithms/zstandard/ldm.rb +121 -0
- data/lib/omnizip/algorithms/zstandard/literals.rb +241 -0
- data/lib/omnizip/algorithms/zstandard/literals_encoder.rb +96 -0
- data/lib/omnizip/algorithms/zstandard/match_finder.rb +483 -0
- data/lib/omnizip/algorithms/zstandard/sequences.rb +350 -0
- data/lib/omnizip/algorithms/zstandard/sequences_encoder.rb +333 -0
- data/lib/omnizip/algorithms/zstandard/xxhash.rb +159 -0
- data/lib/omnizip/algorithms/zstandard.rb +210 -0
- data/lib/omnizip/algorithms.rb +35 -0
- data/lib/omnizip/archive/builder.rb +48 -0
- data/lib/omnizip/archive/reader_session.rb +67 -0
- data/lib/omnizip/archive.rb +86 -0
- data/lib/omnizip/archive_handler.rb +82 -0
- data/lib/omnizip/archive_handlers/cpio_handler.rb +47 -0
- data/lib/omnizip/archive_handlers/iso_handler.rb +54 -0
- data/lib/omnizip/archive_handlers/ole_handler.rb +37 -0
- data/lib/omnizip/archive_handlers/rar_handler.rb +96 -0
- data/lib/omnizip/archive_handlers/rpm_handler.rb +45 -0
- data/lib/omnizip/archive_handlers/seven_zip_handler.rb +89 -0
- data/lib/omnizip/archive_handlers/tar_handler.rb +75 -0
- data/lib/omnizip/archive_handlers/xar_handler.rb +49 -0
- data/lib/omnizip/archive_handlers/zip_handler.rb +115 -0
- data/lib/omnizip/archive_handlers.rb +18 -0
- data/lib/omnizip/backends.rb +160 -0
- data/lib/omnizip/buffer/memory_archive.rb +246 -0
- data/lib/omnizip/buffer/memory_extractor.rb +234 -0
- data/lib/omnizip/buffer/seven_zip_bridge.rb +171 -0
- data/lib/omnizip/buffer.rb +187 -0
- data/lib/omnizip/checksum_registry.rb +41 -0
- data/lib/omnizip/checksums/crc32.rb +101 -0
- data/lib/omnizip/checksums/crc64.rb +102 -0
- data/lib/omnizip/checksums/crc_base.rb +158 -0
- data/lib/omnizip/checksums/registration.rb +16 -0
- data/lib/omnizip/checksums/verifier.rb +130 -0
- data/lib/omnizip/checksums.rb +11 -0
- data/lib/omnizip/chunked/memory_manager.rb +194 -0
- data/lib/omnizip/chunked/reader.rb +78 -0
- data/lib/omnizip/chunked/writer.rb +123 -0
- data/lib/omnizip/chunked.rb +123 -0
- data/lib/omnizip/cli/output_formatter.rb +112 -0
- data/lib/omnizip/cli.rb +604 -0
- data/lib/omnizip/commands/.keep +0 -0
- data/lib/omnizip/commands/archive_create_command.rb +245 -0
- data/lib/omnizip/commands/archive_extract_command.rb +231 -0
- data/lib/omnizip/commands/archive_list_command.rb +204 -0
- data/lib/omnizip/commands/archive_repair_command.rb +129 -0
- data/lib/omnizip/commands/archive_verify_command.rb +115 -0
- data/lib/omnizip/commands/compress_command.rb +115 -0
- data/lib/omnizip/commands/decompress_command.rb +149 -0
- data/lib/omnizip/commands/list_command.rb +51 -0
- data/lib/omnizip/commands/metadata_command.rb +215 -0
- data/lib/omnizip/commands/parity_create_command.rb +114 -0
- data/lib/omnizip/commands/parity_repair_command.rb +120 -0
- data/lib/omnizip/commands/parity_verify_command.rb +122 -0
- data/lib/omnizip/commands/profile_list_command.rb +54 -0
- data/lib/omnizip/commands/profile_show_command.rb +44 -0
- data/lib/omnizip/commands.rb +21 -0
- data/lib/omnizip/convenience.rb +389 -0
- data/lib/omnizip/converter/conversion_registry.rb +50 -0
- data/lib/omnizip/converter/conversion_strategy.rb +108 -0
- data/lib/omnizip/converter/extract_repack_strategy.rb +51 -0
- data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +43 -0
- data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +54 -0
- data/lib/omnizip/converter.rb +124 -0
- data/lib/omnizip/crypto/aes256/cipher.rb +104 -0
- data/lib/omnizip/crypto/aes256/constants.rb +28 -0
- data/lib/omnizip/crypto/aes256/key_derivation.rb +100 -0
- data/lib/omnizip/crypto/aes256.rb +102 -0
- data/lib/omnizip/crypto.rb +11 -0
- data/lib/omnizip/entry.rb +44 -0
- data/lib/omnizip/error.rb +110 -0
- data/lib/omnizip/eta/exponential_smoothing_estimator.rb +95 -0
- data/lib/omnizip/eta/moving_average_estimator.rb +96 -0
- data/lib/omnizip/eta/rate_calculator.rb +104 -0
- data/lib/omnizip/eta/sample_history.rb +143 -0
- data/lib/omnizip/eta/time_estimator.rb +106 -0
- data/lib/omnizip/eta.rb +68 -0
- data/lib/omnizip/extraction/filter_chain.rb +179 -0
- data/lib/omnizip/extraction/glob_pattern.rb +140 -0
- data/lib/omnizip/extraction/pattern_matcher.rb +66 -0
- data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
- data/lib/omnizip/extraction/regex_pattern.rb +50 -0
- data/lib/omnizip/extraction/selective_extractor.rb +247 -0
- data/lib/omnizip/extraction.rb +115 -0
- data/lib/omnizip/file_type/mime_classifier.rb +144 -0
- data/lib/omnizip/file_type.rb +117 -0
- data/lib/omnizip/filter.rb +141 -0
- data/lib/omnizip/filter_pipeline.rb +108 -0
- data/lib/omnizip/filter_registry.rb +113 -0
- data/lib/omnizip/filters/bcj.rb +277 -0
- data/lib/omnizip/filters/bcj2/constants.rb +53 -0
- data/lib/omnizip/filters/bcj2/decoder.rb +263 -0
- data/lib/omnizip/filters/bcj2/encoder.rb +58 -0
- data/lib/omnizip/filters/bcj2/stream_data.rb +91 -0
- data/lib/omnizip/filters/bcj2.rb +93 -0
- data/lib/omnizip/filters/bcj_arm.rb +174 -0
- data/lib/omnizip/filters/bcj_arm64.rb +242 -0
- data/lib/omnizip/filters/bcj_ia64.rb +194 -0
- data/lib/omnizip/filters/bcj_ppc.rb +188 -0
- data/lib/omnizip/filters/bcj_sparc.rb +174 -0
- data/lib/omnizip/filters/bcj_x86.rb +191 -0
- data/lib/omnizip/filters/delta.rb +195 -0
- data/lib/omnizip/filters/xz_delta.rb +258 -0
- data/lib/omnizip/filters.rb +20 -0
- data/lib/omnizip/format_detector.rb +166 -0
- data/lib/omnizip/formats/.keep +0 -0
- data/lib/omnizip/formats/bzip2_file.rb +159 -0
- data/lib/omnizip/formats/cpio/bounded_io.rb +66 -0
- data/lib/omnizip/formats/cpio/constants.rb +55 -0
- data/lib/omnizip/formats/cpio/entry.rb +389 -0
- data/lib/omnizip/formats/cpio/reader.rb +194 -0
- data/lib/omnizip/formats/cpio/writer.rb +232 -0
- data/lib/omnizip/formats/cpio.rb +132 -0
- data/lib/omnizip/formats/format_spec_loader.rb +228 -0
- data/lib/omnizip/formats/gzip.rb +236 -0
- data/lib/omnizip/formats/iso/directory_builder.rb +321 -0
- data/lib/omnizip/formats/iso/directory_record.rb +162 -0
- data/lib/omnizip/formats/iso/joliet.rb +204 -0
- data/lib/omnizip/formats/iso/path_table.rb +125 -0
- data/lib/omnizip/formats/iso/reader.rb +194 -0
- data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
- data/lib/omnizip/formats/iso/volume_builder.rb +319 -0
- data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
- data/lib/omnizip/formats/iso/writer.rb +543 -0
- data/lib/omnizip/formats/iso.rb +133 -0
- data/lib/omnizip/formats/lzip.rb +161 -0
- data/lib/omnizip/formats/lzma_alone.rb +149 -0
- data/lib/omnizip/formats/msi/cab_extractor.rb +181 -0
- data/lib/omnizip/formats/msi/constants.rb +157 -0
- data/lib/omnizip/formats/msi/directory_resolver.rb +188 -0
- data/lib/omnizip/formats/msi/entry.rb +134 -0
- data/lib/omnizip/formats/msi/reader.rb +301 -0
- data/lib/omnizip/formats/msi/string_pool.rb +246 -0
- data/lib/omnizip/formats/msi/table_parser.rb +244 -0
- data/lib/omnizip/formats/msi.rb +73 -0
- data/lib/omnizip/formats/ole/allocation_table.rb +263 -0
- data/lib/omnizip/formats/ole/constants.rb +61 -0
- data/lib/omnizip/formats/ole/dirent.rb +439 -0
- data/lib/omnizip/formats/ole/header.rb +199 -0
- data/lib/omnizip/formats/ole/ranges_io.rb +347 -0
- data/lib/omnizip/formats/ole/storage.rb +482 -0
- data/lib/omnizip/formats/ole/types/variant.rb +338 -0
- data/lib/omnizip/formats/ole.rb +143 -0
- data/lib/omnizip/formats/rar/archive_repairer.rb +240 -0
- data/lib/omnizip/formats/rar/archive_verifier.rb +192 -0
- data/lib/omnizip/formats/rar/block_parser.rb +282 -0
- data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
- data/lib/omnizip/formats/rar/compression/dispatcher.rb +210 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +212 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +154 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman.rb +25 -0
- data/lib/omnizip/formats/rar/compression/ppmd/context.rb +103 -0
- data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +238 -0
- data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +250 -0
- data/lib/omnizip/formats/rar/compression/ppmd.rb +16 -0
- data/lib/omnizip/formats/rar/compression.rb +17 -0
- data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
- data/lib/omnizip/formats/rar/constants.rb +88 -0
- data/lib/omnizip/formats/rar/decompressor.rb +316 -0
- data/lib/omnizip/formats/rar/external_writer.rb +311 -0
- data/lib/omnizip/formats/rar/header.rb +209 -0
- data/lib/omnizip/formats/rar/license_validator.rb +111 -0
- data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
- data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
- data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
- data/lib/omnizip/formats/rar/models.rb +14 -0
- data/lib/omnizip/formats/rar/parity_handler.rb +299 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +200 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +584 -0
- data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
- data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
- data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +96 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +162 -0
- data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
- data/lib/omnizip/formats/rar/rar5/header.rb +208 -0
- data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +260 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +176 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +108 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +139 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
- data/lib/omnizip/formats/rar/rar5/vint.rb +53 -0
- data/lib/omnizip/formats/rar/rar5/writer.rb +540 -0
- data/lib/omnizip/formats/rar/rar_format_base.rb +239 -0
- data/lib/omnizip/formats/rar/reader.rb +377 -0
- data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
- data/lib/omnizip/formats/rar/volume_manager.rb +166 -0
- data/lib/omnizip/formats/rar/writer.rb +437 -0
- data/lib/omnizip/formats/rar.rb +193 -0
- data/lib/omnizip/formats/rar3/compressor.rb +71 -0
- data/lib/omnizip/formats/rar3/decompressor.rb +64 -0
- data/lib/omnizip/formats/rar3/reader.rb +107 -0
- data/lib/omnizip/formats/rar3/writer.rb +220 -0
- data/lib/omnizip/formats/rar3.rb +15 -0
- data/lib/omnizip/formats/rar5/compressor.rb +71 -0
- data/lib/omnizip/formats/rar5/decompressor.rb +64 -0
- data/lib/omnizip/formats/rar5/reader.rb +130 -0
- data/lib/omnizip/formats/rar5/writer.rb +65 -0
- data/lib/omnizip/formats/rar5.rb +15 -0
- data/lib/omnizip/formats/rpm/constants.rb +58 -0
- data/lib/omnizip/formats/rpm/entry.rb +106 -0
- data/lib/omnizip/formats/rpm/header.rb +106 -0
- data/lib/omnizip/formats/rpm/lead.rb +132 -0
- data/lib/omnizip/formats/rpm/tag.rb +228 -0
- data/lib/omnizip/formats/rpm/writer.rb +652 -0
- data/lib/omnizip/formats/rpm.rb +458 -0
- data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +274 -0
- data/lib/omnizip/formats/seven_zip/coder_chain.rb +169 -0
- data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
- data/lib/omnizip/formats/seven_zip/encoded_header.rb +110 -0
- data/lib/omnizip/formats/seven_zip/encrypted_header.rb +139 -0
- data/lib/omnizip/formats/seven_zip/file_collector.rb +143 -0
- data/lib/omnizip/formats/seven_zip/header.rb +102 -0
- data/lib/omnizip/formats/seven_zip/header_encryptor.rb +132 -0
- data/lib/omnizip/formats/seven_zip/header_writer.rb +425 -0
- data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
- data/lib/omnizip/formats/seven_zip/models/file_entry.rb +65 -0
- data/lib/omnizip/formats/seven_zip/models/folder.rb +67 -0
- data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
- data/lib/omnizip/formats/seven_zip/models.rb +20 -0
- data/lib/omnizip/formats/seven_zip/parser.rb +671 -0
- data/lib/omnizip/formats/seven_zip/reader.rb +626 -0
- data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +611 -0
- data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +308 -0
- data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
- data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +166 -0
- data/lib/omnizip/formats/seven_zip/writer.rb +801 -0
- data/lib/omnizip/formats/seven_zip.rb +179 -0
- data/lib/omnizip/formats/tar/constants.rb +73 -0
- data/lib/omnizip/formats/tar/entry.rb +98 -0
- data/lib/omnizip/formats/tar/header.rb +206 -0
- data/lib/omnizip/formats/tar/reader.rb +119 -0
- data/lib/omnizip/formats/tar/writer.rb +212 -0
- data/lib/omnizip/formats/tar.rb +74 -0
- data/lib/omnizip/formats/xar/constants.rb +119 -0
- data/lib/omnizip/formats/xar/entry.rb +268 -0
- data/lib/omnizip/formats/xar/header.rb +223 -0
- data/lib/omnizip/formats/xar/reader.rb +400 -0
- data/lib/omnizip/formats/xar/toc.rb +570 -0
- data/lib/omnizip/formats/xar/writer.rb +461 -0
- data/lib/omnizip/formats/xar.rb +145 -0
- data/lib/omnizip/formats/xz/reader.rb +121 -0
- data/lib/omnizip/formats/xz/writer.rb +416 -0
- data/lib/omnizip/formats/xz.rb +210 -0
- data/lib/omnizip/formats/xz_const.rb +49 -0
- data/lib/omnizip/formats/xz_impl/block_decoder.rb +761 -0
- data/lib/omnizip/formats/xz_impl/block_encoder.rb +304 -0
- data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
- data/lib/omnizip/formats/xz_impl/block_header_parser.rb +182 -0
- data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
- data/lib/omnizip/formats/xz_impl/index_encoder.rb +120 -0
- data/lib/omnizip/formats/xz_impl/stream_decoder.rb +470 -0
- data/lib/omnizip/formats/xz_impl/stream_encoder.rb +95 -0
- data/lib/omnizip/formats/xz_impl/stream_footer.rb +79 -0
- data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +115 -0
- data/lib/omnizip/formats/xz_impl/stream_header.rb +53 -0
- data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +106 -0
- data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
- data/lib/omnizip/formats/xz_impl.rb +52 -0
- data/lib/omnizip/formats/zip/central_directory_header.rb +223 -0
- data/lib/omnizip/formats/zip/constants.rb +69 -0
- data/lib/omnizip/formats/zip/end_of_central_directory.rb +132 -0
- data/lib/omnizip/formats/zip/local_file_header.rb +136 -0
- data/lib/omnizip/formats/zip/reader.rb +376 -0
- data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
- data/lib/omnizip/formats/zip/writer.rb +489 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +102 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +64 -0
- data/lib/omnizip/formats/zip/zip64_extra_field.rb +112 -0
- data/lib/omnizip/formats/zip.rb +50 -0
- data/lib/omnizip/formats.rb +29 -0
- data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
- data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
- data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
- data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
- data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
- data/lib/omnizip/implementations/base.rb +19 -0
- data/lib/omnizip/implementations/rust/archive.rb +93 -0
- data/lib/omnizip/implementations/rust/library.rb +221 -0
- data/lib/omnizip/implementations/rust.rb +26 -0
- data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +428 -0
- data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +456 -0
- data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +285 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +197 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +194 -0
- data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +139 -0
- data/lib/omnizip/implementations/seven_zip/lzma.rb +21 -0
- data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +56 -0
- data/lib/omnizip/implementations/seven_zip/lzma2.rb +12 -0
- data/lib/omnizip/implementations/seven_zip.rb +11 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +547 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +748 -0
- data/lib/omnizip/implementations/xz_utils/lzma2.rb +13 -0
- data/lib/omnizip/implementations/xz_utils.rb +10 -0
- data/lib/omnizip/implementations.rb +25 -0
- data/lib/omnizip/io/buffered_input.rb +147 -0
- data/lib/omnizip/io/buffered_output.rb +106 -0
- data/lib/omnizip/io/source.rb +143 -0
- data/lib/omnizip/io/stream_manager.rb +117 -0
- data/lib/omnizip/io.rb +15 -0
- data/lib/omnizip/link_handler/hard_link.rb +79 -0
- data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
- data/lib/omnizip/link_handler.rb +129 -0
- data/lib/omnizip/metadata/archive_metadata.rb +114 -0
- data/lib/omnizip/metadata/entry_metadata.rb +153 -0
- data/lib/omnizip/metadata/metadata_editor.rb +169 -0
- data/lib/omnizip/metadata/metadata_registry.rb +71 -0
- data/lib/omnizip/metadata/metadata_validator.rb +101 -0
- data/lib/omnizip/metadata.rb +58 -0
- data/lib/omnizip/models/.keep +0 -0
- data/lib/omnizip/models/algorithm_metadata.rb +41 -0
- data/lib/omnizip/models/attribute_apply.rb +40 -0
- data/lib/omnizip/models/compression_options.rb +53 -0
- data/lib/omnizip/models/conversion_options.rb +79 -0
- data/lib/omnizip/models/conversion_result.rb +141 -0
- data/lib/omnizip/models/eta_result.rb +45 -0
- data/lib/omnizip/models/extraction_rule.rb +115 -0
- data/lib/omnizip/models/filter_chain.rb +142 -0
- data/lib/omnizip/models/filter_config.rb +148 -0
- data/lib/omnizip/models/match_result.rb +141 -0
- data/lib/omnizip/models/optimization_suggestion.rb +95 -0
- data/lib/omnizip/models/parallel_options.rb +116 -0
- data/lib/omnizip/models/performance_result.rb +85 -0
- data/lib/omnizip/models/profile_report.rb +116 -0
- data/lib/omnizip/models/progress_options.rb +39 -0
- data/lib/omnizip/models/split_options.rb +116 -0
- data/lib/omnizip/optimization_registry.rb +45 -0
- data/lib/omnizip/parallel/engine.rb +52 -0
- data/lib/omnizip/parallel/job_queue.rb +209 -0
- data/lib/omnizip/parallel/job_scheduler.rb +225 -0
- data/lib/omnizip/parallel/parallel_compressor.rb +326 -0
- data/lib/omnizip/parallel/parallel_extractor.rb +238 -0
- data/lib/omnizip/parallel/thread_pool.rb +60 -0
- data/lib/omnizip/parallel/worker_pool.rb +227 -0
- data/lib/omnizip/parallel.rb +156 -0
- data/lib/omnizip/parity/chunked_block_processor.rb +194 -0
- data/lib/omnizip/parity/galois16.rb +145 -0
- data/lib/omnizip/parity/models/creator_packet.rb +71 -0
- data/lib/omnizip/parity/models/file_description_packet.rb +131 -0
- data/lib/omnizip/parity/models/ifsc_packet.rb +111 -0
- data/lib/omnizip/parity/models/main_packet.rb +126 -0
- data/lib/omnizip/parity/models/packet.rb +156 -0
- data/lib/omnizip/parity/models/packet_registry.rb +102 -0
- data/lib/omnizip/parity/models/recovery_slice_packet.rb +76 -0
- data/lib/omnizip/parity/models.rb +27 -0
- data/lib/omnizip/parity/par2_creator.rb +496 -0
- data/lib/omnizip/parity/par2_repairer.rb +409 -0
- data/lib/omnizip/parity/par2_verifier.rb +373 -0
- data/lib/omnizip/parity/par2cmdline_algorithm.rb +108 -0
- data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
- data/lib/omnizip/parity/reed_solomon_decoder.rb +263 -0
- data/lib/omnizip/parity/reed_solomon_encoder.rb +108 -0
- data/lib/omnizip/parity/reed_solomon_matrix.rb +339 -0
- data/lib/omnizip/parity.rb +207 -0
- data/lib/omnizip/password/encryption_registry.rb +26 -0
- data/lib/omnizip/password/encryption_strategy.rb +96 -0
- data/lib/omnizip/password/password_validator.rb +129 -0
- data/lib/omnizip/password/winzip_aes_strategy.rb +190 -0
- data/lib/omnizip/password/zip_crypto_strategy.rb +135 -0
- data/lib/omnizip/password.rb +88 -0
- data/lib/omnizip/pipe/stream_compressor.rb +124 -0
- data/lib/omnizip/pipe/stream_decompressor.rb +173 -0
- data/lib/omnizip/pipe.rb +120 -0
- data/lib/omnizip/platform/ntfs_streams.rb +200 -0
- data/lib/omnizip/platform.rb +189 -0
- data/lib/omnizip/profile/archive_profile.rb +36 -0
- data/lib/omnizip/profile/balanced_profile.rb +31 -0
- data/lib/omnizip/profile/binary_profile.rb +33 -0
- data/lib/omnizip/profile/compression_profile.rb +157 -0
- data/lib/omnizip/profile/custom_profile.rb +155 -0
- data/lib/omnizip/profile/fast_profile.rb +31 -0
- data/lib/omnizip/profile/maximum_profile.rb +31 -0
- data/lib/omnizip/profile/profile_detector.rb +108 -0
- data/lib/omnizip/profile/profile_registry.rb +160 -0
- data/lib/omnizip/profile/text_profile.rb +33 -0
- data/lib/omnizip/profile.rb +261 -0
- data/lib/omnizip/profiler/memory_profiler.rb +66 -0
- data/lib/omnizip/profiler/method_profiler.rb +49 -0
- data/lib/omnizip/profiler/report_generator.rb +158 -0
- data/lib/omnizip/profiler.rb +192 -0
- data/lib/omnizip/progress/callback_reporter.rb +34 -0
- data/lib/omnizip/progress/console_reporter.rb +59 -0
- data/lib/omnizip/progress/log_reporter.rb +89 -0
- data/lib/omnizip/progress/operation_progress.rb +118 -0
- data/lib/omnizip/progress/progress_bar.rb +156 -0
- data/lib/omnizip/progress/progress_reporter.rb +40 -0
- data/lib/omnizip/progress/progress_tracker.rb +215 -0
- data/lib/omnizip/progress/silent_reporter.rb +22 -0
- data/lib/omnizip/progress.rb +131 -0
- data/lib/omnizip/registry.rb +111 -0
- data/lib/omnizip/rubyzip_compat.rb +61 -0
- data/lib/omnizip/temp/safe_extract.rb +124 -0
- data/lib/omnizip/temp/temp_file.rb +123 -0
- data/lib/omnizip/temp/temp_file_pool.rb +109 -0
- data/lib/omnizip/temp.rb +184 -0
- data/lib/omnizip/version.rb +5 -0
- data/lib/omnizip/zip/entry.rb +160 -0
- data/lib/omnizip/zip/file.rb +485 -0
- data/lib/omnizip/zip/input_stream.rb +270 -0
- data/lib/omnizip/zip/output_stream.rb +320 -0
- data/lib/omnizip/zip.rb +23 -0
- data/lib/omnizip.rb +157 -0
- data/lib/tasks/msi_test_files.rake +66 -0
- data/lib/tasks/platform_gems.rake +147 -0
- data/lib/tasks/rust_backend.rake +48 -0
- data/readme-docs/advanced-features.adoc +514 -0
- data/readme-docs/api-usage.adoc +445 -0
- data/readme-docs/architecture.adoc +450 -0
- data/readme-docs/archive-formats.adoc +479 -0
- data/readme-docs/cli-usage.adoc +222 -0
- data/readme-docs/compression-algorithms.adoc +446 -0
- data/readme-docs/compression-profiles.adoc +247 -0
- data/readme-docs/encryption-checksums.adoc +328 -0
- data/readme-docs/format-converter.adoc +316 -0
- data/readme-docs/installation.adoc +228 -0
- data/readme-docs/par2-archives.adoc +608 -0
- data/readme-docs/performance-profiler.adoc +389 -0
- data/readme-docs/preprocessing-filters.adoc +280 -0
- data/vendor/libomnizip_ffi.so +0 -0
- data/xz-file-format-1.2.1.txt +1174 -0
- metadata +768 -0
|
@@ -0,0 +1,142 @@
|
|
|
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
|
+
module Omnizip
|
|
20
|
+
module Models
|
|
21
|
+
# Ordered sequence of filters for compression/decompression
|
|
22
|
+
#
|
|
23
|
+
# Manages a pipeline of filters that are applied in sequence.
|
|
24
|
+
# Filters are applied in reverse order during decode.
|
|
25
|
+
#
|
|
26
|
+
# @example Create filter chain for XZ executable
|
|
27
|
+
# chain = FilterChain.new(format: :xz)
|
|
28
|
+
# chain.add_filter(name: :"bcj-x86", architecture: :x86)
|
|
29
|
+
# chain.add_filter(name: :lzma2) # Main compression
|
|
30
|
+
# encoded = chain.encode_all(data, position)
|
|
31
|
+
class FilterChain
|
|
32
|
+
# @return [Array<FilterConfig>] Ordered filter configurations
|
|
33
|
+
attr_reader :filters
|
|
34
|
+
|
|
35
|
+
# @return [Symbol] Format identifier (:xz, :seven_zip)
|
|
36
|
+
attr_reader :format
|
|
37
|
+
|
|
38
|
+
# Maximum filters in XZ format
|
|
39
|
+
MAX_FILTERS_XZ = 4
|
|
40
|
+
|
|
41
|
+
# Maximum filters in 7z format
|
|
42
|
+
MAX_FILTERS_SEVEN_ZIP = 4
|
|
43
|
+
|
|
44
|
+
# Initialize filter chain
|
|
45
|
+
#
|
|
46
|
+
# @param attributes [Hash] Initialization attributes
|
|
47
|
+
# @option attributes [Symbol] :format Target format
|
|
48
|
+
def initialize(attributes = {})
|
|
49
|
+
@format = attributes[:format] || :xz
|
|
50
|
+
@filters = attributes[:filters] || []
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Add a filter to the chain
|
|
54
|
+
#
|
|
55
|
+
# @param filter_attributes [Hash] Filter configuration
|
|
56
|
+
# @option filter_attributes [Symbol] :name Filter name
|
|
57
|
+
# @option filter_attributes [String] :properties Filter properties
|
|
58
|
+
# @option filter_attributes [Symbol] :architecture Target architecture
|
|
59
|
+
# @return [self] For chaining
|
|
60
|
+
def add_filter(filter_attributes = {})
|
|
61
|
+
filter = FilterConfig.new(filter_attributes)
|
|
62
|
+
filter.validate!
|
|
63
|
+
@filters << filter
|
|
64
|
+
self
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Get maximum filters for current format
|
|
68
|
+
#
|
|
69
|
+
# @return [Integer] Maximum number of filters allowed
|
|
70
|
+
def max_filters
|
|
71
|
+
case @format
|
|
72
|
+
when :xz then MAX_FILTERS_XZ
|
|
73
|
+
when :seven_zip then MAX_FILTERS_SEVEN_ZIP
|
|
74
|
+
else raise ArgumentError, "Unknown format: #{@format}"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Validate filter chain
|
|
79
|
+
#
|
|
80
|
+
# @return [Boolean] True if valid
|
|
81
|
+
# @raise [ArgumentError] If validation fails
|
|
82
|
+
def validate!
|
|
83
|
+
if @filters.size > max_filters
|
|
84
|
+
raise ArgumentError,
|
|
85
|
+
"Too many filters for #{@format}: #{@filters.size} > #{max_filters}"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
@filters.each(&:validate!)
|
|
89
|
+
true
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Encode data through all filters in order
|
|
93
|
+
#
|
|
94
|
+
# @param data [String] Input data
|
|
95
|
+
# @param position [Integer] Stream position
|
|
96
|
+
# @return [String] Encoded data
|
|
97
|
+
def encode_all(data, position = 0)
|
|
98
|
+
result = data
|
|
99
|
+
@filters.each do |filter_config|
|
|
100
|
+
filter = filter_config.filter_instance
|
|
101
|
+
result = filter.encode(result, position)
|
|
102
|
+
end
|
|
103
|
+
result
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Decode data through all filters in reverse order
|
|
107
|
+
#
|
|
108
|
+
# @param data [String] Input data
|
|
109
|
+
# @param position [Integer] Stream position
|
|
110
|
+
# @return [String] Decoded data
|
|
111
|
+
def decode_all(data, position = 0)
|
|
112
|
+
result = data
|
|
113
|
+
@filters.reverse_each do |filter_config|
|
|
114
|
+
filter = filter_config.filter_instance
|
|
115
|
+
result = filter.decode(result, position)
|
|
116
|
+
end
|
|
117
|
+
result
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Get filter IDs for current format
|
|
121
|
+
#
|
|
122
|
+
# @return [Array<Integer>] Array of filter IDs in order
|
|
123
|
+
def filter_ids
|
|
124
|
+
@filters.map { |f| f.id_for_format(@format) }
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Check if chain is empty
|
|
128
|
+
#
|
|
129
|
+
# @return [Boolean] True if no filters
|
|
130
|
+
def empty?
|
|
131
|
+
@filters.empty?
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Get number of filters in chain
|
|
135
|
+
#
|
|
136
|
+
# @return [Integer] Filter count
|
|
137
|
+
def size
|
|
138
|
+
@filters.size
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -0,0 +1,148 @@
|
|
|
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 "lutaml/model"
|
|
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
|
+
# Serialized via lutaml-model — no hand-rolled +to_h+ / +to_json+.
|
|
29
|
+
#
|
|
30
|
+
# @example Create a BCJ filter configuration
|
|
31
|
+
# config = FilterConfig.new(name: :bcj_x86, architecture: :x86)
|
|
32
|
+
# config.id_for_format(:xz) # => 0x04
|
|
33
|
+
# config.id_for_format(:seven_zip) # => 0x03030103
|
|
34
|
+
#
|
|
35
|
+
# @example Create a Delta filter configuration
|
|
36
|
+
# config = FilterConfig.new(name: :delta)
|
|
37
|
+
# config.delta? # => true
|
|
38
|
+
class FilterConfig < Lutaml::Model::Serializable
|
|
39
|
+
attribute :name, :symbol
|
|
40
|
+
attribute :properties, :string, default: ""
|
|
41
|
+
attribute :architecture, :symbol
|
|
42
|
+
|
|
43
|
+
key_value do
|
|
44
|
+
map "name", to: :name, render_default: true, render_nil: true
|
|
45
|
+
map "properties", to: :properties,
|
|
46
|
+
render_default: true, render_nil: true
|
|
47
|
+
map "architecture", to: :architecture,
|
|
48
|
+
render_default: true, render_nil: true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Initialize filter configuration. The legacy +name_sym+ key is
|
|
52
|
+
# accepted as an alias for +name+.
|
|
53
|
+
#
|
|
54
|
+
# @param attributes [Hash] Initialization attributes
|
|
55
|
+
# @option attributes [Symbol] :name Filter name
|
|
56
|
+
# @option attributes [Symbol] :name_sym Filter name (alias)
|
|
57
|
+
# @option attributes [String] :properties Binary properties data
|
|
58
|
+
# @option attributes [Symbol] :architecture Target architecture
|
|
59
|
+
def initialize(attributes = {})
|
|
60
|
+
attrs = attributes.dup
|
|
61
|
+
attrs[:name] ||= attrs.delete(:name_sym)
|
|
62
|
+
attrs[:properties] ||= "" # empty-string defaults do not render
|
|
63
|
+
super(attrs)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Get filter name as symbol (legacy alias for #name).
|
|
67
|
+
#
|
|
68
|
+
# @return [Symbol] Filter name
|
|
69
|
+
def name_sym
|
|
70
|
+
name
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Get filter instance from registry.
|
|
74
|
+
#
|
|
75
|
+
# @return [Object] Filter instance from FilterRegistry
|
|
76
|
+
# @raise [KeyError] If filter not found in registry
|
|
77
|
+
def filter_instance
|
|
78
|
+
filter = Omnizip::FilterRegistry.get(name)
|
|
79
|
+
|
|
80
|
+
# Handle architecture parameter if needed
|
|
81
|
+
if architecture && requires_initialize_kwargs?(filter)
|
|
82
|
+
filter.new(architecture: architecture)
|
|
83
|
+
else
|
|
84
|
+
filter.new
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Get filter ID for specific format.
|
|
89
|
+
#
|
|
90
|
+
# Delegates to filter instance's id_for_format method if available.
|
|
91
|
+
# For older filters without id_for_format, returns a default value.
|
|
92
|
+
#
|
|
93
|
+
# @param format [Symbol] Format identifier (:seven_zip, :xz)
|
|
94
|
+
# @return [Integer] Format-specific filter ID
|
|
95
|
+
# @raise [NotImplementedError] If filter doesn't support id_for_format
|
|
96
|
+
def id_for_format(format)
|
|
97
|
+
filter = filter_instance
|
|
98
|
+
# FilterRegistry accepts any class, with no inheritance check.
|
|
99
|
+
# allowed: keeps NotImplementedError for filters without the method
|
|
100
|
+
if filter.respond_to?(:id_for_format)
|
|
101
|
+
filter.id_for_format(format)
|
|
102
|
+
else
|
|
103
|
+
raise NotImplementedError,
|
|
104
|
+
"Filter #{name} doesn't support format-aware IDs. " \
|
|
105
|
+
"Use the newer BCJ filter instead."
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Check if this is a BCJ filter.
|
|
110
|
+
#
|
|
111
|
+
# @return [Boolean] True if BCJ filter variant
|
|
112
|
+
def bcj?
|
|
113
|
+
name.to_s.start_with?("bcj_")
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Check if this is a Delta filter.
|
|
117
|
+
#
|
|
118
|
+
# @return [Boolean] True if Delta filter
|
|
119
|
+
def delta?
|
|
120
|
+
name == :delta
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Validate configuration.
|
|
124
|
+
#
|
|
125
|
+
# @return [Boolean] True if valid
|
|
126
|
+
# @raise [ArgumentError] If filter name is nil or not registered
|
|
127
|
+
def validate!
|
|
128
|
+
raise ArgumentError, "Filter name is required" if name.nil?
|
|
129
|
+
|
|
130
|
+
unless Omnizip::FilterRegistry.registered?(name)
|
|
131
|
+
raise ArgumentError, "Filter not registered: #{name}"
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
true
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
private
|
|
138
|
+
|
|
139
|
+
# Check if filter class requires keyword arguments for initialize.
|
|
140
|
+
#
|
|
141
|
+
# @param klass [Class] Filter class to check
|
|
142
|
+
# @return [Boolean] True if kwargs are required
|
|
143
|
+
def requires_initialize_kwargs?(klass)
|
|
144
|
+
klass.name.include?("BCJ") && !klass.name.include?("BcjX86")
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Omnizip
|
|
6
|
+
module Models
|
|
7
|
+
# Represents the result of pattern matching against archive entries.
|
|
8
|
+
#
|
|
9
|
+
# Serialized via lutaml-model — no hand-rolled +to_h+ / +to_json+.
|
|
10
|
+
# The serialized "matches" is the match COUNT (not the entry
|
|
11
|
+
# objects, which are arbitrary caller types); the live entry
|
|
12
|
+
# collection stays a plain reader.
|
|
13
|
+
class MatchResult < Lutaml::Model::Serializable
|
|
14
|
+
include Enumerable
|
|
15
|
+
|
|
16
|
+
attribute :total_scanned, :integer, default: 0
|
|
17
|
+
|
|
18
|
+
attribute :pattern_repr, :string, method: :pattern_to_s
|
|
19
|
+
attribute :match_count, :integer, method: :count
|
|
20
|
+
attribute :rate, :double, method: :match_rate
|
|
21
|
+
|
|
22
|
+
key_value do
|
|
23
|
+
map "pattern", to: :pattern_repr,
|
|
24
|
+
render_default: true, render_nil: true
|
|
25
|
+
map "matches", to: :match_count,
|
|
26
|
+
render_default: true, render_nil: true
|
|
27
|
+
map "scanned", to: :total_scanned,
|
|
28
|
+
render_default: true, render_nil: true
|
|
29
|
+
map "match_rate", to: :rate,
|
|
30
|
+
render_default: true, render_nil: true
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
attr_reader :matches, :pattern
|
|
34
|
+
|
|
35
|
+
# Initialize a new match result
|
|
36
|
+
#
|
|
37
|
+
# @param pattern [Object] The pattern that was matched
|
|
38
|
+
# @param matches [Array] Array of matched entries
|
|
39
|
+
# @param total_scanned [Integer] Total entries scanned
|
|
40
|
+
def initialize(pattern = nil, matches: [], total_scanned: 0)
|
|
41
|
+
super(total_scanned: total_scanned)
|
|
42
|
+
@pattern = pattern
|
|
43
|
+
@matches = Array(matches)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Add a matched entry
|
|
47
|
+
#
|
|
48
|
+
# @param entry [Object] Entry that matched
|
|
49
|
+
# @return [self]
|
|
50
|
+
def add_match(entry)
|
|
51
|
+
@matches << entry
|
|
52
|
+
self
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Increment the scan counter
|
|
56
|
+
#
|
|
57
|
+
# @param count [Integer] Number to increment by
|
|
58
|
+
# @return [self]
|
|
59
|
+
def increment_scanned(count = 1)
|
|
60
|
+
self.total_scanned = total_scanned + count
|
|
61
|
+
self
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Get the number of matches
|
|
65
|
+
#
|
|
66
|
+
# @return [Integer]
|
|
67
|
+
def count
|
|
68
|
+
@matches.size
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Check if any matches were found
|
|
72
|
+
#
|
|
73
|
+
# @return [Boolean]
|
|
74
|
+
def any?
|
|
75
|
+
!@matches.empty?
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Check if no matches were found
|
|
79
|
+
#
|
|
80
|
+
# @return [Boolean]
|
|
81
|
+
def none?
|
|
82
|
+
@matches.empty?
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Get match rate (matches/scanned)
|
|
86
|
+
#
|
|
87
|
+
# @return [Float] Match rate between 0.0 and 1.0
|
|
88
|
+
def match_rate
|
|
89
|
+
return 0.0 if total_scanned.zero?
|
|
90
|
+
|
|
91
|
+
count.to_f / total_scanned
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Get match percentage
|
|
95
|
+
#
|
|
96
|
+
# @return [Float] Match percentage between 0.0 and 100.0
|
|
97
|
+
def match_percentage
|
|
98
|
+
match_rate * 100.0
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Iterate over matches
|
|
102
|
+
#
|
|
103
|
+
# @yield [entry] Each matched entry
|
|
104
|
+
# @return [Enumerator, self]
|
|
105
|
+
def each(&block)
|
|
106
|
+
return matches.to_enum unless block
|
|
107
|
+
|
|
108
|
+
matches.each(&block)
|
|
109
|
+
self
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Get first match
|
|
113
|
+
#
|
|
114
|
+
# @return [Object, nil]
|
|
115
|
+
def first
|
|
116
|
+
@matches.first
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Get last match
|
|
120
|
+
#
|
|
121
|
+
# @return [Object, nil]
|
|
122
|
+
def last
|
|
123
|
+
@matches.last
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Convert to array
|
|
127
|
+
#
|
|
128
|
+
# @return [Array]
|
|
129
|
+
def to_a
|
|
130
|
+
@matches.dup
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Serialized pattern representation.
|
|
134
|
+
#
|
|
135
|
+
# @return [String] The pattern as a string
|
|
136
|
+
def pattern_to_s
|
|
137
|
+
@pattern.to_s
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Omnizip
|
|
6
|
+
module Models
|
|
7
|
+
# Represents a performance optimization suggestion based on
|
|
8
|
+
# profiling data.
|
|
9
|
+
#
|
|
10
|
+
# Serialized via lutaml-model — no hand-rolled +to_h+ / +to_json+.
|
|
11
|
+
# The priority_score key serializes the derived #priority_score
|
|
12
|
+
# method under a distinct attribute name.
|
|
13
|
+
class OptimizationSuggestion < Lutaml::Model::Serializable
|
|
14
|
+
SEVERITY_LEVELS = %i[low medium high critical].freeze
|
|
15
|
+
CATEGORIES = %i[
|
|
16
|
+
memory cpu hotpath algorithm io gc allocation concurrency
|
|
17
|
+
].freeze
|
|
18
|
+
|
|
19
|
+
attribute :title, :string
|
|
20
|
+
attribute :description, :string
|
|
21
|
+
attribute :severity, :symbol
|
|
22
|
+
attribute :category, :symbol
|
|
23
|
+
attribute :impact_estimate, :double
|
|
24
|
+
attribute :implementation_effort, :double
|
|
25
|
+
attribute :related_operations, :string, collection: true, default: []
|
|
26
|
+
attribute :code_locations, :string, collection: true, default: []
|
|
27
|
+
attribute :metrics, :hash, default: {}
|
|
28
|
+
|
|
29
|
+
attribute :priority, :double, method: :priority_score
|
|
30
|
+
|
|
31
|
+
key_value do
|
|
32
|
+
map "title", to: :title, render_default: true, render_nil: true
|
|
33
|
+
map "description", to: :description,
|
|
34
|
+
render_default: true, render_nil: true
|
|
35
|
+
map "severity", to: :severity, render_default: true, render_nil: true
|
|
36
|
+
map "category", to: :category, render_default: true, render_nil: true
|
|
37
|
+
map "impact_estimate", to: :impact_estimate,
|
|
38
|
+
render_default: true, render_nil: true
|
|
39
|
+
map "implementation_effort", to: :implementation_effort,
|
|
40
|
+
render_default: true, render_nil: true
|
|
41
|
+
map "priority_score", to: :priority,
|
|
42
|
+
render_default: true, render_nil: true
|
|
43
|
+
map "related_operations", to: :related_operations,
|
|
44
|
+
render_default: true, render_nil: true
|
|
45
|
+
map "code_locations", to: :code_locations,
|
|
46
|
+
render_default: true, render_nil: true
|
|
47
|
+
map "metrics", to: :metrics, render_default: true, render_nil: true
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Severity and category are validated after the framework
|
|
51
|
+
# constructor assigns the attributes. Empty-collection defaults
|
|
52
|
+
# are assigned explicitly (lutaml-model 0.8.x drops them).
|
|
53
|
+
def initialize(attrs = {})
|
|
54
|
+
super({ related_operations: [], code_locations: [],
|
|
55
|
+
metrics: {} }.merge(attrs))
|
|
56
|
+
validate_severity!(severity)
|
|
57
|
+
validate_category!(category)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def critical?
|
|
61
|
+
severity == :critical
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def high_priority?
|
|
65
|
+
severity == :high || critical?
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def priority_score
|
|
69
|
+
severity_weight = SEVERITY_LEVELS.index(severity) + 1
|
|
70
|
+
impact_weight = impact_estimate || 1.0
|
|
71
|
+
effort_weight = implementation_effort ? (1.0 / implementation_effort) : 1.0
|
|
72
|
+
|
|
73
|
+
severity_weight * impact_weight * effort_weight
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def validate_severity!(severity)
|
|
79
|
+
return if SEVERITY_LEVELS.include?(severity)
|
|
80
|
+
|
|
81
|
+
raise ArgumentError,
|
|
82
|
+
"Invalid severity: #{severity}. " \
|
|
83
|
+
"Must be one of: #{SEVERITY_LEVELS.join(', ')}"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def validate_category!(category)
|
|
87
|
+
return if CATEGORIES.include?(category)
|
|
88
|
+
|
|
89
|
+
raise ArgumentError,
|
|
90
|
+
"Invalid category: #{category}. " \
|
|
91
|
+
"Must be one of: #{CATEGORIES.join(', ')}"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Omnizip
|
|
6
|
+
module Models
|
|
7
|
+
# Model for parallel processing configuration
|
|
8
|
+
#
|
|
9
|
+
# Stores settings for parallel compression and extraction operations
|
|
10
|
+
# including thread count, queue size, and load balancing strategy.
|
|
11
|
+
#
|
|
12
|
+
# Serialized via lutaml-model — no hand-rolled +to_h+ / +to_json+.
|
|
13
|
+
#
|
|
14
|
+
# @example Create parallel options
|
|
15
|
+
# options = Omnizip::Models::ParallelOptions.new
|
|
16
|
+
# options.threads = 8
|
|
17
|
+
# options.queue_size = 100
|
|
18
|
+
# options.strategy = :dynamic
|
|
19
|
+
#
|
|
20
|
+
# @example Use with parallel compression
|
|
21
|
+
# Omnizip::Parallel.compress_directory('files/', 'backup.zip', options)
|
|
22
|
+
class ParallelOptions < Lutaml::Model::Serializable
|
|
23
|
+
include AttributeApply
|
|
24
|
+
|
|
25
|
+
# @return [Integer] Number of worker threads (default: auto-detect)
|
|
26
|
+
attribute :threads, :integer, default: -> { detect_cpu_count }
|
|
27
|
+
|
|
28
|
+
# @return [Integer] Maximum size of job queue (default: 1000)
|
|
29
|
+
attribute :queue_size, :integer, default: 1000
|
|
30
|
+
|
|
31
|
+
# @return [Integer] Chunk size for chunked operations in bytes
|
|
32
|
+
attribute :chunk_size, :integer, default: 64 * 1024 * 1024 # 64MB default
|
|
33
|
+
|
|
34
|
+
# @return [Symbol] Load balancing strategy (:dynamic or :static)
|
|
35
|
+
attribute :strategy, :symbol, default: :dynamic
|
|
36
|
+
|
|
37
|
+
# @return [Boolean] Enable verbose progress output
|
|
38
|
+
attribute :verbose, :boolean, default: false
|
|
39
|
+
|
|
40
|
+
# @return [Integer] Batch size for work queue polling
|
|
41
|
+
attribute :batch_size, :integer, default: 10
|
|
42
|
+
|
|
43
|
+
key_value do
|
|
44
|
+
map "threads", to: :threads, render_default: true, render_nil: true
|
|
45
|
+
map "queue_size", to: :queue_size,
|
|
46
|
+
render_default: true, render_nil: true
|
|
47
|
+
map "chunk_size", to: :chunk_size,
|
|
48
|
+
render_default: true, render_nil: true
|
|
49
|
+
map "strategy", to: :strategy, render_default: true, render_nil: true
|
|
50
|
+
map "verbose", to: :verbose, render_default: true, render_nil: true
|
|
51
|
+
map "batch_size", to: :batch_size,
|
|
52
|
+
render_default: true, render_nil: true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Validate options
|
|
56
|
+
#
|
|
57
|
+
# Named +validate_options!+ rather than +validate!+ so it does not
|
|
58
|
+
# shadow Lutaml::Model::Validation#validate!(register:).
|
|
59
|
+
#
|
|
60
|
+
# @raise [ArgumentError] if options are invalid
|
|
61
|
+
# @return [Boolean] true if valid
|
|
62
|
+
def validate_options!
|
|
63
|
+
validate_positive(:threads)
|
|
64
|
+
validate_positive(:queue_size)
|
|
65
|
+
validate_positive(:chunk_size)
|
|
66
|
+
validate_strategy
|
|
67
|
+
validate_positive(:batch_size)
|
|
68
|
+
|
|
69
|
+
true
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Apply a hash of attributes. Only keys declared as +attribute+s
|
|
73
|
+
# above are applied; unknown keys are silently ignored.
|
|
74
|
+
#
|
|
75
|
+
# Keys must be Symbols. String keys are ignored, so +#to_hash+ output
|
|
76
|
+
# cannot be fed back in directly — use +.from_hash+ for that.
|
|
77
|
+
#
|
|
78
|
+
# @param values [Hash{Symbol=>Object}] attributes to set
|
|
79
|
+
# @return [self]
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
# Raise unless +name+ holds a positive Integer. A nil or non-Integer
|
|
84
|
+
# value fails with the same message as a zero or negative one, so
|
|
85
|
+
# callers get +ArgumentError+ rather than +NoMethodError+.
|
|
86
|
+
#
|
|
87
|
+
# @param name [Symbol] attribute to check
|
|
88
|
+
# @raise [ArgumentError] if the value is not a positive Integer
|
|
89
|
+
# @return [void]
|
|
90
|
+
def validate_positive(name)
|
|
91
|
+
value = public_send(name)
|
|
92
|
+
return if value.is_a?(Integer) && value.positive?
|
|
93
|
+
|
|
94
|
+
raise ArgumentError, "#{name} must be > 0"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @raise [ArgumentError] unless +strategy+ is one of the known values
|
|
98
|
+
# @return [void]
|
|
99
|
+
def validate_strategy
|
|
100
|
+
return if %i[dynamic static].include?(strategy)
|
|
101
|
+
|
|
102
|
+
raise ArgumentError, "strategy must be :dynamic or :static"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Detect number of available CPU cores
|
|
106
|
+
#
|
|
107
|
+
# @return [Integer] number of CPUs
|
|
108
|
+
def detect_cpu_count
|
|
109
|
+
require "etc"
|
|
110
|
+
Etc.nprocessors
|
|
111
|
+
rescue StandardError
|
|
112
|
+
4 # fallback to 4 threads
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|