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,126 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Parity
|
|
5
|
+
module Models
|
|
6
|
+
# PAR2 Main packet
|
|
7
|
+
#
|
|
8
|
+
# Contains recovery set metadata including block size and file IDs.
|
|
9
|
+
#
|
|
10
|
+
# Body structure:
|
|
11
|
+
# - block_size (8 bytes, Q<): Size of each data block
|
|
12
|
+
# - file_ids (16 bytes each): List of file IDs in the recovery set
|
|
13
|
+
#
|
|
14
|
+
# Note: In current Par2Creator implementation, the body includes
|
|
15
|
+
# additional fields after block_size that are not part of the
|
|
16
|
+
# standard PAR2 spec. This model follows the actual PAR2 spec.
|
|
17
|
+
class MainPacket < Packet
|
|
18
|
+
# Packet type identifier
|
|
19
|
+
PACKET_TYPE = "PAR 2.0\x00Main\x00\x00\x00\x00"
|
|
20
|
+
|
|
21
|
+
# Block size in bytes
|
|
22
|
+
attribute :block_size, :integer
|
|
23
|
+
|
|
24
|
+
# Array of 16-byte file IDs
|
|
25
|
+
attribute :file_ids, :string, collection: true, default: -> { [] }
|
|
26
|
+
|
|
27
|
+
# Initialize main packet
|
|
28
|
+
#
|
|
29
|
+
# @param attributes [Hash] Packet attributes
|
|
30
|
+
def initialize(**attributes)
|
|
31
|
+
super
|
|
32
|
+
self.type = PACKET_TYPE
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Parse body data into attributes
|
|
36
|
+
#
|
|
37
|
+
# Body format (PAR2 spec):
|
|
38
|
+
# - block_size: 8 bytes (Q<)
|
|
39
|
+
# - file_ids: 16 bytes each, until end of body
|
|
40
|
+
#
|
|
41
|
+
# par2cmdline variant also includes:
|
|
42
|
+
# - file_count: 4 bytes (L<) after block_size
|
|
43
|
+
# - then file_ids: 16 bytes each
|
|
44
|
+
#
|
|
45
|
+
# This method detects which format is used.
|
|
46
|
+
def parse_body
|
|
47
|
+
return if body_data.nil? || body_data.empty?
|
|
48
|
+
|
|
49
|
+
pos = 0
|
|
50
|
+
|
|
51
|
+
# Read block_size (8 bytes, little-endian unsigned 64-bit)
|
|
52
|
+
self.block_size = body_data[pos, 8].unpack1("Q<")
|
|
53
|
+
pos += 8
|
|
54
|
+
|
|
55
|
+
# Detect format: check if next 4 bytes are a file_count
|
|
56
|
+
remaining = body_data.bytesize - pos
|
|
57
|
+
|
|
58
|
+
if remaining >= 4
|
|
59
|
+
# Try to read potential file_count
|
|
60
|
+
potential_count = body_data[pos, 4].unpack1("L<")
|
|
61
|
+
expected_size = potential_count * 16
|
|
62
|
+
|
|
63
|
+
# Check if this looks like par2cmdline format:
|
|
64
|
+
# - Remaining bytes should be: 4 (count) + count * 16 (file_ids)
|
|
65
|
+
# - Count should be reasonable (> 0, < 10000 for sanity)
|
|
66
|
+
if remaining == (4 + expected_size) &&
|
|
67
|
+
potential_count.positive? &&
|
|
68
|
+
potential_count < 10_000
|
|
69
|
+
# par2cmdline format detected
|
|
70
|
+
pos += 4 # Skip the file_count field
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Read file IDs (16 bytes each) until end of body
|
|
75
|
+
self.file_ids = []
|
|
76
|
+
while pos < body_data.bytesize
|
|
77
|
+
file_id = body_data[pos, 16]
|
|
78
|
+
break if file_id.nil? || file_id.bytesize < 16
|
|
79
|
+
|
|
80
|
+
file_ids << file_id
|
|
81
|
+
pos += 16
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Build body data from attributes
|
|
86
|
+
#
|
|
87
|
+
# Constructs binary body data from block_size and file_ids
|
|
88
|
+
#
|
|
89
|
+
# @return [String] Binary body data
|
|
90
|
+
def build_body
|
|
91
|
+
data = +""
|
|
92
|
+
|
|
93
|
+
# Write block_size (8 bytes, little-endian)
|
|
94
|
+
data << [block_size].pack("Q<")
|
|
95
|
+
|
|
96
|
+
# Write file IDs (16 bytes each)
|
|
97
|
+
file_ids.each do |file_id|
|
|
98
|
+
# Ensure file_id is exactly 16 bytes
|
|
99
|
+
if file_id.bytesize != 16
|
|
100
|
+
raise ArgumentError,
|
|
101
|
+
"File ID must be 16 bytes, got #{file_id.bytesize}"
|
|
102
|
+
end
|
|
103
|
+
data << file_id
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
self.body_data = data
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Get number of files in recovery set
|
|
110
|
+
#
|
|
111
|
+
# @return [Integer] File count
|
|
112
|
+
def file_count
|
|
113
|
+
file_ids.size
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Check if packet contains specific file ID
|
|
117
|
+
#
|
|
118
|
+
# @param file_id [String] 16-byte file ID to check
|
|
119
|
+
# @return [Boolean] true if file ID is present
|
|
120
|
+
def includes_file?(file_id)
|
|
121
|
+
file_ids.include?(file_id)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require "lutaml/model"
|
|
5
|
+
rescue LoadError, ArgumentError
|
|
6
|
+
# lutaml-model not available, using simple classes
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require "digest"
|
|
10
|
+
|
|
11
|
+
module Omnizip
|
|
12
|
+
module Parity
|
|
13
|
+
module Models
|
|
14
|
+
# Base class for PAR2 packets
|
|
15
|
+
#
|
|
16
|
+
# All PAR2 packets share a common 64-byte header structure:
|
|
17
|
+
# - magic (8 bytes): "PAR2\0PKT"
|
|
18
|
+
# - length (8 bytes): Total packet length including header (Q<)
|
|
19
|
+
# - packet_hash (16 bytes): MD5 hash of (set_id + type + data)
|
|
20
|
+
# - set_id (16 bytes): Recovery set identifier
|
|
21
|
+
# - type (16 bytes): Packet type identifier
|
|
22
|
+
#
|
|
23
|
+
# The packet body follows the header and varies by packet type.
|
|
24
|
+
class Packet < Lutaml::Model::Serializable
|
|
25
|
+
# PAR2 packet signature
|
|
26
|
+
PACKET_SIGNATURE = "PAR2\x00PKT".b.freeze
|
|
27
|
+
|
|
28
|
+
# Common header fields (64 bytes total)
|
|
29
|
+
attribute :magic, :string, default: -> { PACKET_SIGNATURE }
|
|
30
|
+
attribute :length, :integer # Total packet length (header + body)
|
|
31
|
+
attribute :packet_hash, :string # MD5 hash (16 bytes)
|
|
32
|
+
attribute :set_id, :string # Recovery set ID (16 bytes)
|
|
33
|
+
attribute :type, :string # Packet type (16 bytes)
|
|
34
|
+
|
|
35
|
+
# Packet body data (variable length, subclass-specific)
|
|
36
|
+
# NOT a lutaml-model attribute because it contains raw binary data
|
|
37
|
+
# that can include null bytes and invalid UTF-8 sequences
|
|
38
|
+
attr_accessor :body_data
|
|
39
|
+
|
|
40
|
+
# Initialize packet
|
|
41
|
+
#
|
|
42
|
+
# @param attributes [Hash] Packet attributes
|
|
43
|
+
def initialize(**attributes)
|
|
44
|
+
@body_data = "" # Initialize body_data with empty binary string
|
|
45
|
+
super
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Read packet from IO stream
|
|
49
|
+
#
|
|
50
|
+
# @param io [IO] Input stream
|
|
51
|
+
# @return [Packet, nil] Parsed packet or nil if EOF/invalid
|
|
52
|
+
def self.read_from(io)
|
|
53
|
+
# Read header (64 bytes total)
|
|
54
|
+
magic = io.read(8)
|
|
55
|
+
return nil unless magic == PACKET_SIGNATURE
|
|
56
|
+
|
|
57
|
+
length = io.read(8).unpack1("Q<")
|
|
58
|
+
packet_hash = io.read(16)
|
|
59
|
+
set_id = io.read(16)
|
|
60
|
+
type = io.read(16)
|
|
61
|
+
|
|
62
|
+
# Read body data
|
|
63
|
+
data_length = length - 64
|
|
64
|
+
body_data = io.read(data_length)
|
|
65
|
+
|
|
66
|
+
# Create instance
|
|
67
|
+
packet = new(
|
|
68
|
+
magic: magic,
|
|
69
|
+
length: length,
|
|
70
|
+
packet_hash: packet_hash,
|
|
71
|
+
set_id: set_id,
|
|
72
|
+
type: type,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Set body_data directly to avoid lutaml-model attribute
|
|
76
|
+
# corruption of binary data
|
|
77
|
+
packet.body_data = body_data
|
|
78
|
+
|
|
79
|
+
# Verify packet hash
|
|
80
|
+
# NOTE: Hash validation temporarily disabled for par2cmdline compatibility testing
|
|
81
|
+
# unless packet.valid_hash?
|
|
82
|
+
# warn "Invalid packet hash detected"
|
|
83
|
+
# end
|
|
84
|
+
|
|
85
|
+
packet
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Write packet to IO stream
|
|
89
|
+
#
|
|
90
|
+
# @param io [IO] Output stream
|
|
91
|
+
def write_to(io)
|
|
92
|
+
# Calculate total length
|
|
93
|
+
self.length = 64 + body_data.bytesize
|
|
94
|
+
|
|
95
|
+
# Calculate packet hash (MD5 of set_id + type + body_data)
|
|
96
|
+
self.packet_hash = calculate_hash
|
|
97
|
+
|
|
98
|
+
# Write header
|
|
99
|
+
io.write(magic)
|
|
100
|
+
io.write([length].pack("Q<"))
|
|
101
|
+
io.write(packet_hash)
|
|
102
|
+
io.write(set_id)
|
|
103
|
+
io.write(type)
|
|
104
|
+
|
|
105
|
+
# Write body
|
|
106
|
+
io.write(body_data)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Calculate MD5 hash of packet body
|
|
110
|
+
#
|
|
111
|
+
# Hash is computed over: set_id + type + body_data
|
|
112
|
+
#
|
|
113
|
+
# @return [String] 16-byte MD5 digest
|
|
114
|
+
def calculate_hash
|
|
115
|
+
data = +""
|
|
116
|
+
data << set_id
|
|
117
|
+
data << type
|
|
118
|
+
data << body_data
|
|
119
|
+
Digest::MD5.digest(data)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Verify packet hash is correct
|
|
123
|
+
#
|
|
124
|
+
# @return [Boolean] true if hash matches
|
|
125
|
+
def valid_hash?
|
|
126
|
+
calculate_hash == packet_hash
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Get packet type identifier
|
|
130
|
+
#
|
|
131
|
+
# @return [String] 16-byte type identifier
|
|
132
|
+
def packet_type
|
|
133
|
+
type
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Parse body data into structured attributes
|
|
137
|
+
#
|
|
138
|
+
# Subclasses must implement this to parse body_data
|
|
139
|
+
# into their specific attributes.
|
|
140
|
+
def parse_body
|
|
141
|
+
raise NotImplementedError,
|
|
142
|
+
"#{self.class} must implement parse_body"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Build body data from structured attributes
|
|
146
|
+
#
|
|
147
|
+
# Subclasses must implement this to build body_data
|
|
148
|
+
# from their specific attributes.
|
|
149
|
+
def build_body
|
|
150
|
+
raise NotImplementedError,
|
|
151
|
+
"#{self.class} must implement build_body"
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Parity
|
|
5
|
+
module Models
|
|
6
|
+
# Registry for PAR2 packet types
|
|
7
|
+
#
|
|
8
|
+
# Maps 16-byte packet type identifiers to their corresponding
|
|
9
|
+
# packet class implementations. Enables polymorphic packet
|
|
10
|
+
# parsing based on type field.
|
|
11
|
+
class PacketRegistry
|
|
12
|
+
@registry = {}
|
|
13
|
+
|
|
14
|
+
class << self
|
|
15
|
+
# Register a packet type
|
|
16
|
+
#
|
|
17
|
+
# @param type_id [String] 16-byte type identifier
|
|
18
|
+
# @param klass [Class] Packet class
|
|
19
|
+
def register(type_id, klass)
|
|
20
|
+
unless type_id.bytesize == 16
|
|
21
|
+
raise ArgumentError,
|
|
22
|
+
"Type ID must be 16 bytes, got #{type_id.bytesize}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
@registry[type_id] = klass
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Get packet class for type identifier
|
|
29
|
+
#
|
|
30
|
+
# @param type_id [String] 16-byte type identifier
|
|
31
|
+
# @return [Class, nil] Packet class or nil if not registered
|
|
32
|
+
def get(type_id)
|
|
33
|
+
@registry[type_id]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Check if type is registered
|
|
37
|
+
#
|
|
38
|
+
# @param type_id [String] 16-byte type identifier
|
|
39
|
+
# @return [Boolean] true if type is registered
|
|
40
|
+
def registered?(type_id)
|
|
41
|
+
@registry.key?(type_id)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Get all registered packet types
|
|
45
|
+
#
|
|
46
|
+
# @return [Array<String>] Array of 16-byte type identifiers
|
|
47
|
+
def types
|
|
48
|
+
@registry.keys
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Parse packet from IO and return appropriate subclass
|
|
52
|
+
#
|
|
53
|
+
# Reads a packet header, determines the type, and returns
|
|
54
|
+
# an instance of the appropriate packet subclass.
|
|
55
|
+
#
|
|
56
|
+
# @param io [IO] Input stream
|
|
57
|
+
# @return [Packet, nil] Parsed packet or nil if EOF/unknown type
|
|
58
|
+
def read_packet(io)
|
|
59
|
+
# Read base packet
|
|
60
|
+
packet = Packet.read_from(io)
|
|
61
|
+
return nil unless packet
|
|
62
|
+
|
|
63
|
+
# Look up packet class for this type
|
|
64
|
+
packet_class = get(packet.type)
|
|
65
|
+
|
|
66
|
+
# If unknown type, return base Packet
|
|
67
|
+
return packet unless packet_class
|
|
68
|
+
|
|
69
|
+
# Create specific packet type
|
|
70
|
+
specific_packet = packet_class.new(
|
|
71
|
+
magic: packet.magic,
|
|
72
|
+
length: packet.length,
|
|
73
|
+
packet_hash: packet.packet_hash,
|
|
74
|
+
set_id: packet.set_id,
|
|
75
|
+
type: packet.type,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
# Set body_data directly (not a lutaml attribute)
|
|
79
|
+
specific_packet.body_data = packet.body_data
|
|
80
|
+
|
|
81
|
+
# Parse body into structured fields
|
|
82
|
+
specific_packet.parse_body
|
|
83
|
+
|
|
84
|
+
specific_packet
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Clear all registrations (primarily for testing)
|
|
88
|
+
def clear!
|
|
89
|
+
@registry.clear
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Register all standard PAR2 packet types
|
|
94
|
+
register(MainPacket::PACKET_TYPE, MainPacket)
|
|
95
|
+
register(FileDescriptionPacket::PACKET_TYPE, FileDescriptionPacket)
|
|
96
|
+
register(IfscPacket::PACKET_TYPE, IfscPacket)
|
|
97
|
+
register(RecoverySlicePacket::PACKET_TYPE, RecoverySlicePacket)
|
|
98
|
+
register(CreatorPacket::PACKET_TYPE, CreatorPacket)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Parity
|
|
5
|
+
module Models
|
|
6
|
+
# PAR2 Recovery Slice packet
|
|
7
|
+
#
|
|
8
|
+
# Contains Reed-Solomon encoded recovery data for error correction.
|
|
9
|
+
#
|
|
10
|
+
# Body structure:
|
|
11
|
+
# - exponent (4 bytes, L<): Recovery block exponent/index
|
|
12
|
+
# - recovery_data (variable): Reed-Solomon encoded block data
|
|
13
|
+
class RecoverySlicePacket < Packet
|
|
14
|
+
# Packet type identifier
|
|
15
|
+
PACKET_TYPE = "PAR 2.0\x00RecvSlic"
|
|
16
|
+
|
|
17
|
+
# Recovery block exponent (4 bytes)
|
|
18
|
+
attribute :exponent, :integer
|
|
19
|
+
|
|
20
|
+
# Recovery data (variable length)
|
|
21
|
+
attribute :recovery_data, :string, default: -> { "" }
|
|
22
|
+
|
|
23
|
+
# Initialize recovery slice packet
|
|
24
|
+
#
|
|
25
|
+
# @param attributes [Hash] Packet attributes
|
|
26
|
+
def initialize(**attributes)
|
|
27
|
+
super
|
|
28
|
+
self.type = PACKET_TYPE
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Parse body data into attributes
|
|
32
|
+
#
|
|
33
|
+
# Body format:
|
|
34
|
+
# - exponent: 4 bytes (L<)
|
|
35
|
+
# - recovery_data: remainder
|
|
36
|
+
def parse_body
|
|
37
|
+
return if body_data.nil? || body_data.empty?
|
|
38
|
+
return if body_data.bytesize < 4
|
|
39
|
+
|
|
40
|
+
pos = 0
|
|
41
|
+
|
|
42
|
+
# Read exponent (4 bytes, little-endian unsigned 32-bit)
|
|
43
|
+
self.exponent = body_data[pos, 4].unpack1("L<")
|
|
44
|
+
pos += 4
|
|
45
|
+
|
|
46
|
+
# Read recovery data (remainder)
|
|
47
|
+
self.recovery_data = body_data[pos..] || ""
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Build body data from attributes
|
|
51
|
+
#
|
|
52
|
+
# Constructs binary body data
|
|
53
|
+
#
|
|
54
|
+
# @return [String] Binary body data
|
|
55
|
+
def build_body
|
|
56
|
+
data = +""
|
|
57
|
+
|
|
58
|
+
# Write exponent (4 bytes, little-endian)
|
|
59
|
+
data << [exponent].pack("L<")
|
|
60
|
+
|
|
61
|
+
# Write recovery data
|
|
62
|
+
data << recovery_data
|
|
63
|
+
|
|
64
|
+
self.body_data = data
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Get size of recovery data
|
|
68
|
+
#
|
|
69
|
+
# @return [Integer] Recovery data size in bytes
|
|
70
|
+
def data_size
|
|
71
|
+
recovery_data.bytesize
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Parity
|
|
5
|
+
# PAR2 packet models for serialization and parsing
|
|
6
|
+
#
|
|
7
|
+
# Contains model classes for all PAR2 packet types:
|
|
8
|
+
# - Packet: Base class for all packets
|
|
9
|
+
# - MainPacket: Recovery set metadata
|
|
10
|
+
# - FileDescriptionPacket: Protected file metadata
|
|
11
|
+
# - IfscPacket: Input File Slice Checksums
|
|
12
|
+
# - RecoverySlicePacket: Reed-Solomon recovery data
|
|
13
|
+
# - CreatorPacket: Creator identification
|
|
14
|
+
# - PacketRegistry: Registry for packet type dispatch
|
|
15
|
+
module Models
|
|
16
|
+
autoload :Packet, "omnizip/parity/models/packet"
|
|
17
|
+
autoload :CreatorPacket, "omnizip/parity/models/creator_packet"
|
|
18
|
+
autoload :FileDescriptionPacket,
|
|
19
|
+
"omnizip/parity/models/file_description_packet"
|
|
20
|
+
autoload :IfscPacket, "omnizip/parity/models/ifsc_packet"
|
|
21
|
+
autoload :MainPacket, "omnizip/parity/models/main_packet"
|
|
22
|
+
autoload :RecoverySlicePacket,
|
|
23
|
+
"omnizip/parity/models/recovery_slice_packet"
|
|
24
|
+
autoload :PacketRegistry, "omnizip/parity/models/packet_registry"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|