omnizip 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +32 -0
- data/.rubocop_todo.yml +754 -0
- data/COPYING +502 -0
- data/Gemfile +17 -0
- data/LICENSE +12 -0
- data/README.adoc +1045 -0
- data/Rakefile +12 -0
- data/benchmark/README.md +260 -0
- data/benchmark/benchmark_suite.rb +125 -0
- data/benchmark/compression_bench.rb +181 -0
- data/benchmark/filter_bench.rb +180 -0
- data/benchmark/models/benchmark_result.rb +59 -0
- data/benchmark/models/comparison_result.rb +69 -0
- data/benchmark/profile_suite.rb +167 -0
- data/benchmark/reporter.rb +150 -0
- data/benchmark/run_benchmarks.rb +66 -0
- data/benchmark/test_data.rb +137 -0
- data/config/formats/rar3_spec.yml +91 -0
- data/config/formats/rar5_spec.yml +102 -0
- data/docs/.github/workflows/docs.yml +142 -0
- data/docs/.gitignore +21 -0
- data/docs/.lychee.toml +67 -0
- data/docs/Gemfile +13 -0
- data/docs/RAR_WRITE_SUPPORT.md +26 -0
- data/docs/README.md +101 -0
- data/docs/_config.yml +112 -0
- data/docs/assets/logo.svg +1 -0
- data/docs/assets/omnizip-logo.pdf +1540 -11
- data/docs/comparison/feature-matrix.adoc +694 -0
- data/docs/comparison/index.adoc +113 -0
- data/docs/comparison/vs-7zip.adoc +309 -0
- data/docs/comparison/vs-peazip.adoc +77 -0
- data/docs/comparison/vs-rubyzip.adoc +342 -0
- data/docs/comparison/vs-winrar.adoc +100 -0
- data/docs/compatibility.adoc +579 -0
- data/docs/concepts/index.adoc +129 -0
- data/docs/developer/architecture.adoc +256 -0
- data/docs/developer/contributing.adoc +158 -0
- data/docs/developer/index.adoc +25 -0
- data/docs/developer/testing.adoc +212 -0
- data/docs/getting-started/basic-usage.adoc +271 -0
- data/docs/getting-started/index.adoc +42 -0
- data/docs/getting-started/installation.adoc +138 -0
- data/docs/getting-started/quick-start.adoc +185 -0
- data/docs/getting-started/your-first-archive.adoc +218 -0
- data/docs/guides/advanced-features/encryption.adoc +300 -0
- data/docs/guides/advanced-features/index.adoc +49 -0
- data/docs/guides/advanced-features/parallel-processing.adoc +246 -0
- data/docs/guides/advanced-features/progress-tracking.adoc +320 -0
- data/docs/guides/advanced-features/streaming.adoc +212 -0
- data/docs/guides/archive-formats/gzip-format.adoc +107 -0
- data/docs/guides/archive-formats/index.adoc +130 -0
- data/docs/guides/archive-formats/rar-format.adoc +104 -0
- data/docs/guides/archive-formats/rar5.adoc +521 -0
- data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
- data/docs/guides/archive-formats/tar-format.adoc +106 -0
- data/docs/guides/archive-formats/xz-format.adoc +118 -0
- data/docs/guides/archive-formats/zip-format.adoc +35 -0
- data/docs/guides/compression-algorithms/bzip2.adoc +113 -0
- data/docs/guides/compression-algorithms/deflate.adoc +319 -0
- data/docs/guides/compression-algorithms/index.adoc +190 -0
- data/docs/guides/compression-algorithms/lzma.adoc +398 -0
- data/docs/guides/compression-algorithms/lzma2.adoc +327 -0
- data/docs/guides/compression-algorithms/ppmd.adoc +316 -0
- data/docs/guides/compression-algorithms/zstandard.adoc +361 -0
- data/docs/guides/creating-archives.adoc +354 -0
- data/docs/guides/extracting-archives.adoc +53 -0
- data/docs/guides/format-conversion.adoc +64 -0
- data/docs/guides/index.adoc +49 -0
- data/docs/guides/migration-rubyzip.adoc +217 -0
- data/docs/guides/parity-archives.adoc +605 -0
- data/docs/guides/performance-tuning.adoc +88 -0
- data/docs/index.adoc +218 -0
- data/docs/lychee.toml +67 -0
- data/docs/reference/api/overview.adoc +188 -0
- data/docs/reference/cli/compress-command.adoc +114 -0
- data/docs/reference/cli/overview.adoc +140 -0
- data/docs/reference/index.adoc +26 -0
- data/docs/resources/faq.adoc +185 -0
- data/docs/resources/quick-reference.adoc +222 -0
- data/docs/troubleshooting/index.adoc +208 -0
- data/examples/api_comparison.rb +205 -0
- data/examples/deflate64_example.rb +96 -0
- data/examples/par2_demo.rb +121 -0
- data/examples/quick_start_native.rb +150 -0
- data/examples/quick_start_rubyzip.rb +115 -0
- data/examples/rubyzip_compatibility_demo.rb +194 -0
- data/exe/omnizip +27 -0
- data/lib/omnizip/algorithm.rb +130 -0
- data/lib/omnizip/algorithm_registry.rb +86 -0
- data/lib/omnizip/algorithms/.keep +0 -0
- data/lib/omnizip/algorithms/bzip2/bwt.rb +225 -0
- data/lib/omnizip/algorithms/bzip2/decoder.rb +193 -0
- data/lib/omnizip/algorithms/bzip2/encoder.rb +237 -0
- data/lib/omnizip/algorithms/bzip2/huffman.rb +206 -0
- data/lib/omnizip/algorithms/bzip2/mtf.rb +101 -0
- data/lib/omnizip/algorithms/bzip2/rle.rb +151 -0
- data/lib/omnizip/algorithms/bzip2.rb +130 -0
- data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
- data/lib/omnizip/algorithms/deflate/decoder.rb +38 -0
- data/lib/omnizip/algorithms/deflate/encoder.rb +46 -0
- data/lib/omnizip/algorithms/deflate.rb +128 -0
- data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
- data/lib/omnizip/algorithms/deflate64/decoder.rb +153 -0
- data/lib/omnizip/algorithms/deflate64/encoder.rb +98 -0
- data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +354 -0
- data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +142 -0
- data/lib/omnizip/algorithms/deflate64.rb +109 -0
- data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
- data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
- data/lib/omnizip/algorithms/lzma/decoder.rb +148 -0
- data/lib/omnizip/algorithms/lzma/dictionary.rb +69 -0
- data/lib/omnizip/algorithms/lzma/distance_coder.rb +415 -0
- data/lib/omnizip/algorithms/lzma/encoder.rb +142 -0
- data/lib/omnizip/algorithms/lzma/length_coder.rb +260 -0
- data/lib/omnizip/algorithms/lzma/literal_decoder.rb +320 -0
- data/lib/omnizip/algorithms/lzma/literal_encoder.rb +210 -0
- data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +341 -0
- data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +192 -0
- data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
- data/lib/omnizip/algorithms/lzma/match.rb +32 -0
- data/lib/omnizip/algorithms/lzma/match_finder.rb +205 -0
- data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
- data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +88 -0
- data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +130 -0
- data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
- data/lib/omnizip/algorithms/lzma/range_coder.rb +85 -0
- data/lib/omnizip/algorithms/lzma/range_decoder.rb +434 -0
- data/lib/omnizip/algorithms/lzma/range_encoder.rb +194 -0
- data/lib/omnizip/algorithms/lzma/state.rb +127 -0
- data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +325 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder.rb +426 -0
- data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +645 -0
- data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +227 -0
- data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +169 -0
- data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +261 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
- data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +331 -0
- data/lib/omnizip/algorithms/lzma/xz_state.rb +116 -0
- data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +2055 -0
- data/lib/omnizip/algorithms/lzma.rb +238 -0
- data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +182 -0
- data/lib/omnizip/algorithms/lzma2/constants.rb +41 -0
- data/lib/omnizip/algorithms/lzma2/encoder.rb +147 -0
- data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +161 -0
- data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
- data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +127 -0
- data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
- data/lib/omnizip/algorithms/lzma2.rb +141 -0
- data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
- data/lib/omnizip/algorithms/ppmd7/context.rb +154 -0
- data/lib/omnizip/algorithms/ppmd7/decoder.rb +126 -0
- data/lib/omnizip/algorithms/ppmd7/encoder.rb +163 -0
- data/lib/omnizip/algorithms/ppmd7/model.rb +248 -0
- data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
- data/lib/omnizip/algorithms/ppmd7.rb +116 -0
- data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
- data/lib/omnizip/algorithms/ppmd8/context.rb +34 -0
- data/lib/omnizip/algorithms/ppmd8/decoder.rb +107 -0
- data/lib/omnizip/algorithms/ppmd8/encoder.rb +138 -0
- data/lib/omnizip/algorithms/ppmd8/model.rb +250 -0
- data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
- data/lib/omnizip/algorithms/ppmd8.rb +82 -0
- data/lib/omnizip/algorithms/ppmd_base.rb +138 -0
- data/lib/omnizip/algorithms/sevenzip_lzma2.rb +123 -0
- data/lib/omnizip/algorithms/xz_lzma2.rb +118 -0
- data/lib/omnizip/algorithms/zstandard/constants.rb +25 -0
- data/lib/omnizip/algorithms/zstandard/decoder.rb +46 -0
- data/lib/omnizip/algorithms/zstandard/encoder.rb +51 -0
- data/lib/omnizip/algorithms/zstandard.rb +138 -0
- data/lib/omnizip/buffer/memory_archive.rb +251 -0
- data/lib/omnizip/buffer/memory_extractor.rb +224 -0
- data/lib/omnizip/buffer.rb +176 -0
- data/lib/omnizip/checksum_registry.rb +114 -0
- data/lib/omnizip/checksums/crc32.rb +100 -0
- data/lib/omnizip/checksums/crc64.rb +101 -0
- data/lib/omnizip/checksums/crc_base.rb +158 -0
- data/lib/omnizip/checksums/verifier.rb +131 -0
- data/lib/omnizip/chunked/memory_manager.rb +194 -0
- data/lib/omnizip/chunked/reader.rb +78 -0
- data/lib/omnizip/chunked/writer.rb +120 -0
- data/lib/omnizip/chunked.rb +129 -0
- data/lib/omnizip/cli/output_formatter.rb +104 -0
- data/lib/omnizip/cli.rb +572 -0
- data/lib/omnizip/commands/.keep +0 -0
- data/lib/omnizip/commands/archive_create_command.rb +427 -0
- data/lib/omnizip/commands/archive_extract_command.rb +272 -0
- data/lib/omnizip/commands/archive_list_command.rb +218 -0
- data/lib/omnizip/commands/archive_repair_command.rb +131 -0
- data/lib/omnizip/commands/archive_verify_command.rb +117 -0
- data/lib/omnizip/commands/compress_command.rb +117 -0
- data/lib/omnizip/commands/decompress_command.rb +120 -0
- data/lib/omnizip/commands/list_command.rb +53 -0
- data/lib/omnizip/commands/metadata_command.rb +153 -0
- data/lib/omnizip/commands/parity_create_command.rb +122 -0
- data/lib/omnizip/commands/parity_repair_command.rb +122 -0
- data/lib/omnizip/commands/parity_verify_command.rb +124 -0
- data/lib/omnizip/commands/profile_list_command.rb +56 -0
- data/lib/omnizip/commands/profile_show_command.rb +44 -0
- data/lib/omnizip/convenience.rb +359 -0
- data/lib/omnizip/converter/conversion_registry.rb +49 -0
- data/lib/omnizip/converter/conversion_strategy.rb +121 -0
- data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +97 -0
- data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +112 -0
- data/lib/omnizip/converter.rb +105 -0
- data/lib/omnizip/crypto/aes256/cipher.rb +100 -0
- data/lib/omnizip/crypto/aes256/constants.rb +28 -0
- data/lib/omnizip/crypto/aes256/key_derivation.rb +101 -0
- data/lib/omnizip/crypto/aes256.rb +102 -0
- data/lib/omnizip/error.rb +106 -0
- data/lib/omnizip/eta/exponential_smoothing_estimator.rb +98 -0
- data/lib/omnizip/eta/moving_average_estimator.rb +99 -0
- data/lib/omnizip/eta/rate_calculator.rb +104 -0
- data/lib/omnizip/eta/sample_history.rb +143 -0
- data/lib/omnizip/eta/time_estimator.rb +106 -0
- data/lib/omnizip/eta.rb +63 -0
- data/lib/omnizip/extraction/filter_chain.rb +177 -0
- data/lib/omnizip/extraction/glob_pattern.rb +140 -0
- data/lib/omnizip/extraction/pattern_matcher.rb +70 -0
- data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
- data/lib/omnizip/extraction/regex_pattern.rb +50 -0
- data/lib/omnizip/extraction/selective_extractor.rb +240 -0
- data/lib/omnizip/extraction.rb +111 -0
- data/lib/omnizip/file_type/mime_classifier.rb +144 -0
- data/lib/omnizip/file_type.rb +113 -0
- data/lib/omnizip/filter.rb +139 -0
- data/lib/omnizip/filter_pipeline.rb +108 -0
- data/lib/omnizip/filter_registry.rb +166 -0
- data/lib/omnizip/filters/bcj.rb +279 -0
- data/lib/omnizip/filters/bcj2/constants.rb +53 -0
- data/lib/omnizip/filters/bcj2/decoder.rb +200 -0
- data/lib/omnizip/filters/bcj2/encoder.rb +61 -0
- data/lib/omnizip/filters/bcj2/stream_data.rb +93 -0
- data/lib/omnizip/filters/bcj2.rb +99 -0
- data/lib/omnizip/filters/bcj_arm.rb +176 -0
- data/lib/omnizip/filters/bcj_arm64.rb +244 -0
- data/lib/omnizip/filters/bcj_ia64.rb +196 -0
- data/lib/omnizip/filters/bcj_ppc.rb +190 -0
- data/lib/omnizip/filters/bcj_sparc.rb +176 -0
- data/lib/omnizip/filters/bcj_x86.rb +193 -0
- data/lib/omnizip/filters/delta.rb +196 -0
- data/lib/omnizip/filters/filter_base.rb +72 -0
- data/lib/omnizip/filters/registry.rb +123 -0
- data/lib/omnizip/filters/xz_delta.rb +258 -0
- data/lib/omnizip/format_detector.rb +162 -0
- data/lib/omnizip/format_registry.rb +59 -0
- data/lib/omnizip/formats/.keep +0 -0
- data/lib/omnizip/formats/bzip2_file.rb +172 -0
- data/lib/omnizip/formats/cpio/constants.rb +55 -0
- data/lib/omnizip/formats/cpio/entry.rb +385 -0
- data/lib/omnizip/formats/cpio/reader.rb +196 -0
- data/lib/omnizip/formats/cpio/writer.rb +234 -0
- data/lib/omnizip/formats/cpio.rb +140 -0
- data/lib/omnizip/formats/format_spec_loader.rb +230 -0
- data/lib/omnizip/formats/gzip.rb +238 -0
- data/lib/omnizip/formats/iso/directory_builder.rb +297 -0
- data/lib/omnizip/formats/iso/directory_record.rb +152 -0
- data/lib/omnizip/formats/iso/joliet.rb +204 -0
- data/lib/omnizip/formats/iso/path_table.rb +125 -0
- data/lib/omnizip/formats/iso/reader.rb +197 -0
- data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
- data/lib/omnizip/formats/iso/volume_builder.rb +320 -0
- data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
- data/lib/omnizip/formats/iso/writer.rb +530 -0
- data/lib/omnizip/formats/iso.rb +140 -0
- data/lib/omnizip/formats/lzip.rb +175 -0
- data/lib/omnizip/formats/lzma_alone.rb +171 -0
- data/lib/omnizip/formats/rar/archive_repairer.rb +243 -0
- data/lib/omnizip/formats/rar/archive_verifier.rb +195 -0
- data/lib/omnizip/formats/rar/block_parser.rb +243 -0
- data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
- data/lib/omnizip/formats/rar/compression/dispatcher.rb +217 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +216 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +158 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
- data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
- data/lib/omnizip/formats/rar/compression/ppmd/context.rb +105 -0
- data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +219 -0
- data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +262 -0
- data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
- data/lib/omnizip/formats/rar/constants.rb +82 -0
- data/lib/omnizip/formats/rar/decompressor.rb +238 -0
- data/lib/omnizip/formats/rar/external_writer.rb +312 -0
- data/lib/omnizip/formats/rar/header.rb +192 -0
- data/lib/omnizip/formats/rar/license_validator.rb +109 -0
- data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
- data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
- data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
- data/lib/omnizip/formats/rar/parity_handler.rb +292 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +202 -0
- data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +578 -0
- data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
- data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
- data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +97 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
- data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +166 -0
- data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
- data/lib/omnizip/formats/rar/rar5/header.rb +187 -0
- data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
- data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +264 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +194 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +109 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +142 -0
- data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
- data/lib/omnizip/formats/rar/rar5/vint.rb +65 -0
- data/lib/omnizip/formats/rar/rar5/writer.rb +466 -0
- data/lib/omnizip/formats/rar/rar_format_base.rb +241 -0
- data/lib/omnizip/formats/rar/reader.rb +366 -0
- data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
- data/lib/omnizip/formats/rar/volume_manager.rb +168 -0
- data/lib/omnizip/formats/rar/writer.rb +431 -0
- data/lib/omnizip/formats/rar.rb +205 -0
- data/lib/omnizip/formats/rar3/compressor.rb +73 -0
- data/lib/omnizip/formats/rar3/decompressor.rb +66 -0
- data/lib/omnizip/formats/rar3/reader.rb +386 -0
- data/lib/omnizip/formats/rar3/writer.rb +219 -0
- data/lib/omnizip/formats/rar5/compressor.rb +73 -0
- data/lib/omnizip/formats/rar5/decompressor.rb +66 -0
- data/lib/omnizip/formats/rar5/reader.rb +342 -0
- data/lib/omnizip/formats/rar5/writer.rb +214 -0
- data/lib/omnizip/formats/seven_zip/coder_chain.rb +150 -0
- data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
- data/lib/omnizip/formats/seven_zip/encoded_header.rb +114 -0
- data/lib/omnizip/formats/seven_zip/encrypted_header.rb +142 -0
- data/lib/omnizip/formats/seven_zip/file_collector.rb +144 -0
- data/lib/omnizip/formats/seven_zip/header.rb +106 -0
- data/lib/omnizip/formats/seven_zip/header_encryptor.rb +134 -0
- data/lib/omnizip/formats/seven_zip/header_writer.rb +466 -0
- data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
- data/lib/omnizip/formats/seven_zip/models/file_entry.rb +58 -0
- data/lib/omnizip/formats/seven_zip/models/folder.rb +69 -0
- data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
- data/lib/omnizip/formats/seven_zip/parser.rb +660 -0
- data/lib/omnizip/formats/seven_zip/reader.rb +458 -0
- data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +632 -0
- data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +315 -0
- data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
- data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +162 -0
- data/lib/omnizip/formats/seven_zip/writer.rb +740 -0
- data/lib/omnizip/formats/seven_zip.rb +93 -0
- data/lib/omnizip/formats/tar/constants.rb +73 -0
- data/lib/omnizip/formats/tar/entry.rb +94 -0
- data/lib/omnizip/formats/tar/header.rb +168 -0
- data/lib/omnizip/formats/tar/reader.rb +121 -0
- data/lib/omnizip/formats/tar/writer.rb +216 -0
- data/lib/omnizip/formats/tar.rb +84 -0
- data/lib/omnizip/formats/xz/reader.rb +116 -0
- data/lib/omnizip/formats/xz.rb +237 -0
- data/lib/omnizip/formats/xz_impl/block_decoder.rb +754 -0
- data/lib/omnizip/formats/xz_impl/block_encoder.rb +306 -0
- data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
- data/lib/omnizip/formats/xz_impl/block_header_parser.rb +186 -0
- data/lib/omnizip/formats/xz_impl/constants.rb +49 -0
- data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
- data/lib/omnizip/formats/xz_impl/index_encoder.rb +122 -0
- data/lib/omnizip/formats/xz_impl/stream_decoder.rb +468 -0
- data/lib/omnizip/formats/xz_impl/stream_encoder.rb +99 -0
- data/lib/omnizip/formats/xz_impl/stream_footer.rb +81 -0
- data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +117 -0
- data/lib/omnizip/formats/xz_impl/stream_header.rb +55 -0
- data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +108 -0
- data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
- data/lib/omnizip/formats/xz_impl/writer.rb +421 -0
- data/lib/omnizip/formats/zip/central_directory_header.rb +195 -0
- data/lib/omnizip/formats/zip/constants.rb +69 -0
- data/lib/omnizip/formats/zip/end_of_central_directory.rb +133 -0
- data/lib/omnizip/formats/zip/local_file_header.rb +138 -0
- data/lib/omnizip/formats/zip/reader.rb +250 -0
- data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
- data/lib/omnizip/formats/zip/writer.rb +375 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +104 -0
- data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +66 -0
- data/lib/omnizip/formats/zip/zip64_extra_field.rb +114 -0
- data/lib/omnizip/formats/zip.rb +50 -0
- data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
- data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
- data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
- data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
- data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
- data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +421 -0
- data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +465 -0
- data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +288 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +200 -0
- data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +197 -0
- data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +141 -0
- data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +519 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +723 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +750 -0
- data/lib/omnizip/io/buffered_input.rb +146 -0
- data/lib/omnizip/io/buffered_output.rb +105 -0
- data/lib/omnizip/io/stream_manager.rb +115 -0
- data/lib/omnizip/link_handler/hard_link.rb +79 -0
- data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
- data/lib/omnizip/link_handler.rb +124 -0
- data/lib/omnizip/metadata/archive_metadata.rb +114 -0
- data/lib/omnizip/metadata/entry_metadata.rb +146 -0
- data/lib/omnizip/metadata/metadata_editor.rb +171 -0
- data/lib/omnizip/metadata/metadata_registry.rb +64 -0
- data/lib/omnizip/metadata/metadata_validator.rb +99 -0
- data/lib/omnizip/metadata.rb +57 -0
- data/lib/omnizip/models/.keep +0 -0
- data/lib/omnizip/models/algorithm_metadata.rb +73 -0
- data/lib/omnizip/models/compression_options.rb +71 -0
- data/lib/omnizip/models/conversion_options.rb +87 -0
- data/lib/omnizip/models/conversion_result.rb +135 -0
- data/lib/omnizip/models/eta_result.rb +46 -0
- data/lib/omnizip/models/extraction_rule.rb +115 -0
- data/lib/omnizip/models/filter_chain.rb +144 -0
- data/lib/omnizip/models/filter_config.rb +183 -0
- data/lib/omnizip/models/match_result.rb +124 -0
- data/lib/omnizip/models/optimization_suggestion.rb +91 -0
- data/lib/omnizip/models/parallel_options.rb +104 -0
- data/lib/omnizip/models/performance_result.rb +79 -0
- data/lib/omnizip/models/profile_report.rb +82 -0
- data/lib/omnizip/models/progress_options.rb +38 -0
- data/lib/omnizip/models/split_options.rb +116 -0
- data/lib/omnizip/optimization_registry.rb +81 -0
- data/lib/omnizip/parallel/job_queue.rb +209 -0
- data/lib/omnizip/parallel/job_scheduler.rb +203 -0
- data/lib/omnizip/parallel/parallel_compressor.rb +347 -0
- data/lib/omnizip/parallel/parallel_extractor.rb +329 -0
- data/lib/omnizip/parallel/worker_pool.rb +223 -0
- data/lib/omnizip/parallel.rb +149 -0
- data/lib/omnizip/parity/chunked_block_processor.rb +196 -0
- data/lib/omnizip/parity/galois16.rb +145 -0
- data/lib/omnizip/parity/models/creator_packet.rb +73 -0
- data/lib/omnizip/parity/models/file_description_packet.rb +133 -0
- data/lib/omnizip/parity/models/ifsc_packet.rb +123 -0
- data/lib/omnizip/parity/models/main_packet.rb +128 -0
- data/lib/omnizip/parity/models/packet.rb +156 -0
- data/lib/omnizip/parity/models/packet_registry.rb +109 -0
- data/lib/omnizip/parity/models/recovery_slice_packet.rb +78 -0
- data/lib/omnizip/parity/par2_creator.rb +531 -0
- data/lib/omnizip/parity/par2_repairer.rb +407 -0
- data/lib/omnizip/parity/par2_verifier.rb +364 -0
- data/lib/omnizip/parity/par2cmdline_algorithm.rb +110 -0
- data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
- data/lib/omnizip/parity/reed_solomon_decoder.rb +266 -0
- data/lib/omnizip/parity/reed_solomon_encoder.rb +111 -0
- data/lib/omnizip/parity/reed_solomon_matrix.rb +342 -0
- data/lib/omnizip/parity.rb +186 -0
- data/lib/omnizip/password/encryption_registry.rb +65 -0
- data/lib/omnizip/password/encryption_strategy.rb +96 -0
- data/lib/omnizip/password/password_validator.rb +129 -0
- data/lib/omnizip/password/winzip_aes_strategy.rb +192 -0
- data/lib/omnizip/password/zip_crypto_strategy.rb +141 -0
- data/lib/omnizip/password.rb +87 -0
- data/lib/omnizip/pipe/stream_compressor.rb +124 -0
- data/lib/omnizip/pipe/stream_decompressor.rb +174 -0
- data/lib/omnizip/pipe.rb +121 -0
- data/lib/omnizip/platform/ntfs_streams.rb +201 -0
- data/lib/omnizip/platform.rb +189 -0
- data/lib/omnizip/profile/archive_profile.rb +39 -0
- data/lib/omnizip/profile/balanced_profile.rb +33 -0
- data/lib/omnizip/profile/binary_profile.rb +36 -0
- data/lib/omnizip/profile/compression_profile.rb +158 -0
- data/lib/omnizip/profile/custom_profile.rb +157 -0
- data/lib/omnizip/profile/fast_profile.rb +33 -0
- data/lib/omnizip/profile/maximum_profile.rb +33 -0
- data/lib/omnizip/profile/profile_detector.rb +110 -0
- data/lib/omnizip/profile/profile_registry.rb +161 -0
- data/lib/omnizip/profile/text_profile.rb +36 -0
- data/lib/omnizip/profile.rb +190 -0
- data/lib/omnizip/profiler/memory_profiler.rb +66 -0
- data/lib/omnizip/profiler/method_profiler.rb +49 -0
- data/lib/omnizip/profiler/report_generator.rb +169 -0
- data/lib/omnizip/profiler.rb +204 -0
- data/lib/omnizip/progress/callback_reporter.rb +36 -0
- data/lib/omnizip/progress/console_reporter.rb +62 -0
- data/lib/omnizip/progress/log_reporter.rb +91 -0
- data/lib/omnizip/progress/operation_progress.rb +118 -0
- data/lib/omnizip/progress/progress_bar.rb +156 -0
- data/lib/omnizip/progress/progress_reporter.rb +40 -0
- data/lib/omnizip/progress/progress_tracker.rb +190 -0
- data/lib/omnizip/progress/silent_reporter.rb +24 -0
- data/lib/omnizip/progress.rb +127 -0
- data/lib/omnizip/rubyzip_compat.rb +63 -0
- data/lib/omnizip/temp/safe_extract.rb +168 -0
- data/lib/omnizip/temp/temp_file.rb +124 -0
- data/lib/omnizip/temp/temp_file_pool.rb +109 -0
- data/lib/omnizip/temp.rb +181 -0
- data/lib/omnizip/version.rb +5 -0
- data/lib/omnizip/zip/entry.rb +156 -0
- data/lib/omnizip/zip/file.rb +485 -0
- data/lib/omnizip/zip/input_stream.rb +273 -0
- data/lib/omnizip/zip/output_stream.rb +324 -0
- data/lib/omnizip.rb +156 -0
- data/readme-docs/advanced-features.adoc +515 -0
- data/readme-docs/api-usage.adoc +444 -0
- data/readme-docs/architecture.adoc +449 -0
- data/readme-docs/archive-formats.adoc +479 -0
- data/readme-docs/cli-usage.adoc +222 -0
- data/readme-docs/compression-algorithms.adoc +442 -0
- data/readme-docs/compression-profiles.adoc +247 -0
- data/readme-docs/encryption-checksums.adoc +328 -0
- data/readme-docs/format-converter.adoc +325 -0
- data/readme-docs/installation.adoc +228 -0
- data/readme-docs/par2-archives.adoc +608 -0
- data/readme-docs/performance-profiler.adoc +389 -0
- data/readme-docs/preprocessing-filters.adoc +280 -0
- data/xz-file-format-1.2.1.txt +1174 -0
- metadata +617 -0
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
= PAR2 Parity Archives
|
|
2
|
+
:toc:
|
|
3
|
+
:toclevels: 3
|
|
4
|
+
|
|
5
|
+
== Purpose
|
|
6
|
+
|
|
7
|
+
PAR2 (Parity Archive 2) provides error correction and repair capabilities for archives using Reed-Solomon error correction codes. Protect your data against corruption during transfer or storage.
|
|
8
|
+
|
|
9
|
+
== Features
|
|
10
|
+
|
|
11
|
+
* **Error Detection** - Verify file integrity with MD5 checksums
|
|
12
|
+
* **Error Correction** - Recover corrupted or missing blocks
|
|
13
|
+
* **Configurable Redundancy** - Choose protection level (0-100%)
|
|
14
|
+
* **Multi-file Support** - Protect multiple files with single PAR2 set
|
|
15
|
+
* **Block-level Recovery** - Efficient partial repairs
|
|
16
|
+
* **Progress Tracking** - Real-time feedback during operations
|
|
17
|
+
|
|
18
|
+
== Quick Start
|
|
19
|
+
|
|
20
|
+
=== Protect a File
|
|
21
|
+
|
|
22
|
+
[source,ruby]
|
|
23
|
+
----
|
|
24
|
+
# Create PAR2 protection with 5% redundancy
|
|
25
|
+
Omnizip::Parity.create('important.zip', redundancy: 5)
|
|
26
|
+
# Creates: important.par2, important.vol00+01.par2, etc.
|
|
27
|
+
----
|
|
28
|
+
|
|
29
|
+
=== Verify Integrity
|
|
30
|
+
|
|
31
|
+
[source,ruby]
|
|
32
|
+
----
|
|
33
|
+
# Check if files are intact
|
|
34
|
+
result = Omnizip::Parity.verify('important.par2')
|
|
35
|
+
|
|
36
|
+
if result.all_ok?
|
|
37
|
+
puts "All files intact"
|
|
38
|
+
elsif result.repairable?
|
|
39
|
+
puts "Damage detected but can be repaired"
|
|
40
|
+
else
|
|
41
|
+
puts "Damage exceeds recovery capacity"
|
|
42
|
+
end
|
|
43
|
+
----
|
|
44
|
+
|
|
45
|
+
=== Repair Damage
|
|
46
|
+
|
|
47
|
+
[source,ruby]
|
|
48
|
+
----
|
|
49
|
+
# Automatically repair damaged files
|
|
50
|
+
result = Omnizip::Parity.repair('important.par2')
|
|
51
|
+
|
|
52
|
+
if result.success?
|
|
53
|
+
puts "Recovered: #{result.recovered_files.join(', ')}"
|
|
54
|
+
else
|
|
55
|
+
puts "Repair failed: #{result.error_message}"
|
|
56
|
+
end
|
|
57
|
+
----
|
|
58
|
+
|
|
59
|
+
== Creating PAR2 Protection
|
|
60
|
+
|
|
61
|
+
=== Basic Creation
|
|
62
|
+
|
|
63
|
+
[source,ruby]
|
|
64
|
+
----
|
|
65
|
+
# Protect single file
|
|
66
|
+
Omnizip::Parity.create('backup.7z', redundancy: 10)
|
|
67
|
+
|
|
68
|
+
# Protect multiple files with pattern
|
|
69
|
+
Omnizip::Parity.create('data/*.dat', redundancy: 15)
|
|
70
|
+
|
|
71
|
+
# Custom block size
|
|
72
|
+
Omnizip::Parity.create('large.zip',
|
|
73
|
+
redundancy: 10,
|
|
74
|
+
block_size: 32768 # 32KB blocks
|
|
75
|
+
)
|
|
76
|
+
----
|
|
77
|
+
|
|
78
|
+
=== With Progress Tracking
|
|
79
|
+
|
|
80
|
+
[source,ruby]
|
|
81
|
+
----
|
|
82
|
+
# Track PAR2 creation progress
|
|
83
|
+
Omnizip::Parity.create('archive.7z',
|
|
84
|
+
redundancy: 10,
|
|
85
|
+
progress: ->(pct, msg) do
|
|
86
|
+
puts "[#{pct}%] #{msg}"
|
|
87
|
+
end
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# Output:
|
|
91
|
+
# [0%] Initializing PAR2 creation
|
|
92
|
+
# [10%] Generating recovery blocks (this may take a while)
|
|
93
|
+
# [60%] Writing recovery volume files
|
|
94
|
+
# [90%] Finalizing recovery volumes
|
|
95
|
+
# [100%] PAR2 creation complete
|
|
96
|
+
----
|
|
97
|
+
|
|
98
|
+
=== Custom Output Location
|
|
99
|
+
|
|
100
|
+
[source,ruby]
|
|
101
|
+
----
|
|
102
|
+
# Save PAR2 files to different directory
|
|
103
|
+
Omnizip::Parity.create('data/backup.zip',
|
|
104
|
+
redundancy: 10,
|
|
105
|
+
output_dir: 'recovery/'
|
|
106
|
+
)
|
|
107
|
+
# Creates: recovery/backup.par2, recovery/backup.vol*.par2
|
|
108
|
+
----
|
|
109
|
+
|
|
110
|
+
== Verifying Files
|
|
111
|
+
|
|
112
|
+
=== Basic Verification
|
|
113
|
+
|
|
114
|
+
[source,ruby]
|
|
115
|
+
----
|
|
116
|
+
result = Omnizip::Parity.verify('backup.par2')
|
|
117
|
+
|
|
118
|
+
# Check overall status
|
|
119
|
+
result.all_ok? # => true if no damage
|
|
120
|
+
result.repairable? # => true if can be repaired
|
|
121
|
+
|
|
122
|
+
# Detailed information
|
|
123
|
+
result.damaged_files # => ['file1.txt']
|
|
124
|
+
result.damaged_blocks # => [5, 12, 18]
|
|
125
|
+
result.missing_files # => []
|
|
126
|
+
result.total_blocks # => 100
|
|
127
|
+
result.recovery_blocks # => 10
|
|
128
|
+
result.damage_count # => 3
|
|
129
|
+
----
|
|
130
|
+
|
|
131
|
+
=== Verification Details
|
|
132
|
+
|
|
133
|
+
[source,ruby]
|
|
134
|
+
----
|
|
135
|
+
result = Omnizip::Parity.verify('backup.par2')
|
|
136
|
+
|
|
137
|
+
if result.damaged_files.any?
|
|
138
|
+
puts "Damaged files:"
|
|
139
|
+
result.damaged_files.each { |f| puts " - #{f}" }
|
|
140
|
+
puts "\nDamaged blocks: #{result.damaged_blocks.size}"
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
if result.missing_files.any?
|
|
144
|
+
puts "Missing files:"
|
|
145
|
+
result.missing_files.each { |f| puts " - #{f}" }
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
if result.repairable?
|
|
149
|
+
puts "\n✓ Can repair with #{result.recovery_blocks} recovery blocks"
|
|
150
|
+
else
|
|
151
|
+
puts "\n✗ Cannot repair: need #{result.damage_count} blocks, " \
|
|
152
|
+
"have #{result.recovery_blocks}"
|
|
153
|
+
end
|
|
154
|
+
----
|
|
155
|
+
|
|
156
|
+
== Repairing Files
|
|
157
|
+
|
|
158
|
+
=== Basic Repair
|
|
159
|
+
|
|
160
|
+
[source,ruby]
|
|
161
|
+
----
|
|
162
|
+
# Repair damaged files in place
|
|
163
|
+
result = Omnizip::Parity.repair('backup.par2')
|
|
164
|
+
|
|
165
|
+
if result.success?
|
|
166
|
+
puts "Successfully recovered:"
|
|
167
|
+
result.recovered_files.each { |f| puts " - #{f}" }
|
|
168
|
+
puts "Recovered #{result.recovered_blocks} blocks"
|
|
169
|
+
else
|
|
170
|
+
puts "Repair failed: #{result.error_message}"
|
|
171
|
+
|
|
172
|
+
if result.has_unrecoverable?
|
|
173
|
+
puts "Unrecoverable files:"
|
|
174
|
+
result.unrecoverable.each { |f| puts " - #{f}" }
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
----
|
|
178
|
+
|
|
179
|
+
=== Repair with Progress
|
|
180
|
+
|
|
181
|
+
[source,ruby]
|
|
182
|
+
----
|
|
183
|
+
# Track repair progress
|
|
184
|
+
result = Omnizip::Parity.repair('large.par2',
|
|
185
|
+
progress: ->(pct, msg) do
|
|
186
|
+
puts "[#{pct}%] #{msg}"
|
|
187
|
+
end
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
# Output:
|
|
191
|
+
# [0%] Verifying files
|
|
192
|
+
# [10%] Loading recovery blocks
|
|
193
|
+
# [30%] Calculating repairs
|
|
194
|
+
# [50%] Recovering damaged blocks
|
|
195
|
+
# [80%] Writing repaired files
|
|
196
|
+
# [100%] Repair complete
|
|
197
|
+
----
|
|
198
|
+
|
|
199
|
+
=== Repair to Different Location
|
|
200
|
+
|
|
201
|
+
[source,ruby]
|
|
202
|
+
----
|
|
203
|
+
# Repair files to separate directory
|
|
204
|
+
result = Omnizip::Parity.repair('backup.par2',
|
|
205
|
+
output_dir: 'repaired/'
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
# Original damaged files remain untouched
|
|
209
|
+
# Repaired files written to repaired/
|
|
210
|
+
----
|
|
211
|
+
|
|
212
|
+
== Checking Protection Status
|
|
213
|
+
|
|
214
|
+
=== Quick Check
|
|
215
|
+
|
|
216
|
+
[source,ruby]
|
|
217
|
+
----
|
|
218
|
+
# Check if file has PAR2 protection
|
|
219
|
+
if Omnizip::Parity.protected?('backup.zip')
|
|
220
|
+
puts "File is protected by PAR2"
|
|
221
|
+
else
|
|
222
|
+
puts "No PAR2 protection found"
|
|
223
|
+
end
|
|
224
|
+
----
|
|
225
|
+
|
|
226
|
+
=== Detailed Information
|
|
227
|
+
|
|
228
|
+
[source,ruby]
|
|
229
|
+
----
|
|
230
|
+
# Get PAR2 protection details
|
|
231
|
+
info = Omnizip::Parity.info('backup.zip')
|
|
232
|
+
|
|
233
|
+
if info
|
|
234
|
+
puts "PAR2 Protection Information:"
|
|
235
|
+
puts " PAR2 file: #{info[:par2_file]}"
|
|
236
|
+
puts " Block size: #{info[:block_size]} bytes"
|
|
237
|
+
puts " Total blocks: #{info[:total_blocks]}"
|
|
238
|
+
puts " Recovery blocks: #{info[:recovery_blocks]}"
|
|
239
|
+
puts " Redundancy: #{info[:redundancy]}%"
|
|
240
|
+
puts " Protected files: #{info[:file_count]}"
|
|
241
|
+
else
|
|
242
|
+
puts "No PAR2 protection found"
|
|
243
|
+
end
|
|
244
|
+
----
|
|
245
|
+
|
|
246
|
+
== Best Practices
|
|
247
|
+
|
|
248
|
+
=== Redundancy Guidelines
|
|
249
|
+
|
|
250
|
+
[cols="20,30,50",options="header"]
|
|
251
|
+
|===
|
|
252
|
+
|Redundancy |Speed |Use Case
|
|
253
|
+
|
|
254
|
+
|**5%**
|
|
255
|
+
|Fast
|
|
256
|
+
|Minimal protection, quick creation
|
|
257
|
+
|
|
258
|
+
|**10%**
|
|
259
|
+
|Good
|
|
260
|
+
|Balanced protection (recommended)
|
|
261
|
+
|
|
262
|
+
|**15-20%**
|
|
263
|
+
|Slower
|
|
264
|
+
|High redundancy for critical data
|
|
265
|
+
|
|
266
|
+
|**25%+**
|
|
267
|
+
|Slowest
|
|
268
|
+
|Maximum protection, important archives
|
|
269
|
+
|===
|
|
270
|
+
|
|
271
|
+
=== Block Size Guidelines
|
|
272
|
+
|
|
273
|
+
[cols="20,30,50",options="header"]
|
|
274
|
+
|===
|
|
275
|
+
|Block Size |File Size |Notes
|
|
276
|
+
|
|
277
|
+
|**16KB**
|
|
278
|
+
|< 100MB
|
|
279
|
+
|Default, good for most files
|
|
280
|
+
|
|
281
|
+
|**32KB**
|
|
282
|
+
|100MB - 1GB
|
|
283
|
+
|Better for medium files
|
|
284
|
+
|
|
285
|
+
|**64KB**
|
|
286
|
+
|> 1GB
|
|
287
|
+
|Optimal for very large files
|
|
288
|
+
|===
|
|
289
|
+
|
|
290
|
+
=== Recommended Workflows
|
|
291
|
+
|
|
292
|
+
==== Workflow 1: Backup with Protection
|
|
293
|
+
|
|
294
|
+
[source,ruby]
|
|
295
|
+
----
|
|
296
|
+
def protected_backup(files, archive_path)
|
|
297
|
+
# Step 1: Create compressed archive
|
|
298
|
+
Omnizip::Formats::SevenZip::Writer.new(archive_path,
|
|
299
|
+
algorithm: :lzma2,
|
|
300
|
+
level: 9
|
|
301
|
+
) do |zip|
|
|
302
|
+
files.each { |f| zip.add_file(f) }
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# Step 2: Add PAR2 protection
|
|
306
|
+
Omnizip::Parity.create(archive_path,
|
|
307
|
+
redundancy: 10,
|
|
308
|
+
progress: ->(pct, msg) { puts "#{pct}%: #{msg}" }
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
puts "✓ Backup created with 10% PAR2 protection"
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
files = Dir.glob('important_data/**/*').select { |f| File.file?(f) }
|
|
315
|
+
protected_backup(files, 'backup.7z')
|
|
316
|
+
----
|
|
317
|
+
|
|
318
|
+
==== Workflow 2: Verify Before Extract
|
|
319
|
+
|
|
320
|
+
[source,ruby]
|
|
321
|
+
----
|
|
322
|
+
def safe_extract(archive_path, output_dir)
|
|
323
|
+
par2_file = archive_path.sub(/\.\w+$/, '.par2')
|
|
324
|
+
|
|
325
|
+
# Check if PAR2 protection exists
|
|
326
|
+
if File.exist?(par2_file)
|
|
327
|
+
puts "Verifying archive integrity..."
|
|
328
|
+
result = Omnizip::Parity.verify(par2_file)
|
|
329
|
+
|
|
330
|
+
unless result.all_ok?
|
|
331
|
+
if result.repairable?
|
|
332
|
+
puts "Archive damaged, attempting repair..."
|
|
333
|
+
repair_result = Omnizip::Parity.repair(par2_file)
|
|
334
|
+
|
|
335
|
+
unless repair_result.success?
|
|
336
|
+
raise "Repair failed: #{repair_result.error_message}"
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
puts "✓ Archive repaired successfully"
|
|
340
|
+
else
|
|
341
|
+
raise "Archive is corrupted beyond repair"
|
|
342
|
+
end
|
|
343
|
+
else
|
|
344
|
+
puts "✓ Archive integrity verified"
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# Extract archive
|
|
349
|
+
Omnizip::Formats::SevenZip::Reader.new(archive_path) do |zip|
|
|
350
|
+
zip.extract_all(output_dir)
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
puts "✓ Extraction complete"
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
safe_extract('backup.7z', 'restored/')
|
|
357
|
+
----
|
|
358
|
+
|
|
359
|
+
==== Workflow 3: Incremental Backups
|
|
360
|
+
|
|
361
|
+
[source,ruby]
|
|
362
|
+
----
|
|
363
|
+
def incremental_backup_with_parity(source_dir, backup_dir)
|
|
364
|
+
timestamp = Time.now.strftime('%Y%m%d_%H%M%S')
|
|
365
|
+
archive_name = "backup_#{timestamp}.7z"
|
|
366
|
+
archive_path = File.join(backup_dir, archive_name)
|
|
367
|
+
|
|
368
|
+
FileUtils.mkdir_p(backup_dir)
|
|
369
|
+
|
|
370
|
+
# Create archive
|
|
371
|
+
puts "Creating archive: #{archive_name}"
|
|
372
|
+
Omnizip::Formats::SevenZip::Writer.new(archive_path,
|
|
373
|
+
algorithm: :lzma2,
|
|
374
|
+
level: 7
|
|
375
|
+
) do |zip|
|
|
376
|
+
Dir.glob("#{source_dir}/**/*").each do |file|
|
|
377
|
+
next if File.directory?(file)
|
|
378
|
+
relative_path = file.sub("#{source_dir}/", '')
|
|
379
|
+
zip.add_file(file, archive_path: relative_path)
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
# Add PAR2 protection
|
|
384
|
+
puts "Adding PAR2 protection..."
|
|
385
|
+
Omnizip::Parity.create(archive_path,
|
|
386
|
+
redundancy: 10,
|
|
387
|
+
output_dir: backup_dir
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
# Verify immediately
|
|
391
|
+
par2_file = File.join(backup_dir, "#{archive_name.sub('.7z', '')}.par2")
|
|
392
|
+
verify_result = Omnizip::Parity.verify(par2_file)
|
|
393
|
+
|
|
394
|
+
if verify_result.all_ok?
|
|
395
|
+
puts "✓ Backup complete and verified"
|
|
396
|
+
else
|
|
397
|
+
puts "⚠️ Warning: Verification failed immediately after creation!"
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
incremental_backup_with_parity('my_project/', 'backups/')
|
|
402
|
+
----
|
|
403
|
+
|
|
404
|
+
== Error Recovery Examples
|
|
405
|
+
|
|
406
|
+
=== Example 1: Automatic Corruption Detection
|
|
407
|
+
|
|
408
|
+
[source,ruby]
|
|
409
|
+
----
|
|
410
|
+
def monitor_archive_health(archive_path)
|
|
411
|
+
return unless Omnizip::Parity.protected?(archive_path)
|
|
412
|
+
|
|
413
|
+
par2_file = archive_path.sub(/\.\w+$/, '.par2')
|
|
414
|
+
result = Omnizip::Parity.verify(par2_file)
|
|
415
|
+
|
|
416
|
+
status = if result.all_ok?
|
|
417
|
+
"✓ HEALTHY"
|
|
418
|
+
elsif result.repairable?
|
|
419
|
+
"⚠️ DAMAGED (repairable)"
|
|
420
|
+
else
|
|
421
|
+
"✗ CORRUPTED (unrecoverable)"
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
puts "#{File.basename(archive_path)}: #{status}"
|
|
425
|
+
|
|
426
|
+
if result.damaged_blocks.any?
|
|
427
|
+
puts " Damaged blocks: #{result.damaged_blocks.size}"
|
|
428
|
+
puts " Recovery blocks: #{result.recovery_blocks}"
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
# Monitor all archives in backup directory
|
|
433
|
+
Dir.glob('backups/*.{7z,zip}').each do |archive|
|
|
434
|
+
monitor_archive_health(archive)
|
|
435
|
+
end
|
|
436
|
+
----
|
|
437
|
+
|
|
438
|
+
=== Example 2: Batch Repair
|
|
439
|
+
|
|
440
|
+
[source,ruby]
|
|
441
|
+
----
|
|
442
|
+
def batch_repair_archives(backup_dir)
|
|
443
|
+
par2_files = Dir.glob("#{backup_dir}/*.par2")
|
|
444
|
+
|
|
445
|
+
results = {
|
|
446
|
+
verified: [],
|
|
447
|
+
repaired: [],
|
|
448
|
+
failed: []
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
par2_files.each do |par2_file|
|
|
452
|
+
archive_name = File.basename(par2_file, '.par2')
|
|
453
|
+
|
|
454
|
+
result = Omnizip::Parity.verify(par2_file)
|
|
455
|
+
|
|
456
|
+
if result.all_ok?
|
|
457
|
+
results[:verified] << archive_name
|
|
458
|
+
elsif result.repairable?
|
|
459
|
+
repair_result = Omnizip::Parity.repair(par2_file)
|
|
460
|
+
|
|
461
|
+
if repair_result.success?
|
|
462
|
+
results[:repaired] << archive_name
|
|
463
|
+
else
|
|
464
|
+
results[:failed] << archive_name
|
|
465
|
+
end
|
|
466
|
+
else
|
|
467
|
+
results[:failed] << archive_name
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
# Print summary
|
|
472
|
+
puts "\n=== Repair Summary ==="
|
|
473
|
+
puts "Verified OK: #{results[:verified].size}"
|
|
474
|
+
puts "Repaired: #{results[:repaired].size}"
|
|
475
|
+
puts "Failed: #{results[:failed].size}"
|
|
476
|
+
|
|
477
|
+
results[:repaired].each { |name| puts " ✓ #{name}" }
|
|
478
|
+
results[:failed].each { |name| puts " ✗ #{name}" }
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
batch_repair_archives('backups/')
|
|
482
|
+
----
|
|
483
|
+
|
|
484
|
+
== Technical Details
|
|
485
|
+
|
|
486
|
+
=== PAR2 File Structure
|
|
487
|
+
|
|
488
|
+
PAR2 creates multiple files:
|
|
489
|
+
|
|
490
|
+
[source]
|
|
491
|
+
----
|
|
492
|
+
backup.par2 # Index file with file descriptions
|
|
493
|
+
backup.vol00+01.par2 # 1 recovery block
|
|
494
|
+
backup.vol01+02.par2 # 2 recovery blocks
|
|
495
|
+
backup.vol03+04.par2 # 4 recovery blocks
|
|
496
|
+
backup.vol07+08.par2 # 8 recovery blocks
|
|
497
|
+
----
|
|
498
|
+
|
|
499
|
+
Volume distribution follows powers of 2 for efficient recovery.
|
|
500
|
+
|
|
501
|
+
=== Reed-Solomon Error Correction
|
|
502
|
+
|
|
503
|
+
PAR2 uses Reed-Solomon codes over GF(2^16):
|
|
504
|
+
|
|
505
|
+
* **Systematic Codes** - Data blocks stored unchanged
|
|
506
|
+
* **Parity Blocks** - Generated using Galois field mathematics
|
|
507
|
+
* **Erasure Decoding** - Recover up to N missing blocks with N parity blocks
|
|
508
|
+
* **Error Detection** - Identify corrupted blocks via MD5 checksums
|
|
509
|
+
|
|
510
|
+
=== Block-level Processing
|
|
511
|
+
|
|
512
|
+
Files are divided into fixed-size blocks:
|
|
513
|
+
|
|
514
|
+
[source]
|
|
515
|
+
----
|
|
516
|
+
File (160KB) with 16KB blocks:
|
|
517
|
+
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
|
|
518
|
+
│ B0 │ B1 │ B2 │ B3 │ B4 │ B5 │ B6 │ B7 │ B8 │ B9 │
|
|
519
|
+
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
|
|
520
|
+
↓ Reed-Solomon Encoding
|
|
521
|
+
┌─────┬─────┐
|
|
522
|
+
│ P0 │ P1 │ ← Parity blocks (10% redundancy = 1 block)
|
|
523
|
+
└─────┴─────┘
|
|
524
|
+
|
|
525
|
+
Can recover any 1 missing or corrupted block
|
|
526
|
+
----
|
|
527
|
+
|
|
528
|
+
=== Performance Characteristics
|
|
529
|
+
|
|
530
|
+
[cols="30,30,40",options="header"]
|
|
531
|
+
|===
|
|
532
|
+
|Operation |Speed |Notes
|
|
533
|
+
|
|
534
|
+
|**Create 5%**
|
|
535
|
+
|Moderate
|
|
536
|
+
|~2-3 minutes per GB
|
|
537
|
+
|
|
538
|
+
|**Create 10%**
|
|
539
|
+
|Slow
|
|
540
|
+
|~4-6 minutes per GB
|
|
541
|
+
|
|
542
|
+
|**Create 20%**
|
|
543
|
+
|Very Slow
|
|
544
|
+
|~10-15 minutes per GB
|
|
545
|
+
|
|
546
|
+
|**Verify**
|
|
547
|
+
|Fast
|
|
548
|
+
|~30 seconds per GB
|
|
549
|
+
|
|
550
|
+
|**Repair**
|
|
551
|
+
|Moderate
|
|
552
|
+
|Depends on damage extent
|
|
553
|
+
|===
|
|
554
|
+
|
|
555
|
+
## Command-Line Usage
|
|
556
|
+
|
|
557
|
+
=== Create PAR2
|
|
558
|
+
|
|
559
|
+
[source,bash]
|
|
560
|
+
----
|
|
561
|
+
# Create with default 5% redundancy
|
|
562
|
+
$ omnizip parity create backup.7z
|
|
563
|
+
|
|
564
|
+
# Custom redundancy
|
|
565
|
+
$ omnizip parity create --redundancy 10 backup.7z
|
|
566
|
+
|
|
567
|
+
# Multiple files
|
|
568
|
+
$ omnizip parity create --redundancy 5 data/*.dat
|
|
569
|
+
|
|
570
|
+
# With custom block size
|
|
571
|
+
$ omnizip parity create --block-size 32768 large.zip
|
|
572
|
+
----
|
|
573
|
+
|
|
574
|
+
=== Verify PAR2
|
|
575
|
+
|
|
576
|
+
[source,bash]
|
|
577
|
+
----
|
|
578
|
+
# Verify archive integrity
|
|
579
|
+
$ omnizip parity verify backup.par2
|
|
580
|
+
|
|
581
|
+
# Output:
|
|
582
|
+
# Verifying backup.par2...
|
|
583
|
+
# ✓ All files intact
|
|
584
|
+
# Total blocks: 100
|
|
585
|
+
# Recovery blocks available: 10
|
|
586
|
+
----
|
|
587
|
+
|
|
588
|
+
=== Repair with PAR2
|
|
589
|
+
|
|
590
|
+
[source,bash]
|
|
591
|
+
----
|
|
592
|
+
# Repair damaged files
|
|
593
|
+
$ omnizip parity repair backup.par2
|
|
594
|
+
|
|
595
|
+
# Output:
|
|
596
|
+
# Repairing backup.par2...
|
|
597
|
+
# Loading recovery blocks...
|
|
598
|
+
# Recovering damaged blocks...
|
|
599
|
+
# ✓ Repair successful
|
|
600
|
+
# Recovered files: backup.7z
|
|
601
|
+
# Recovered blocks: 3
|
|
602
|
+
----
|
|
603
|
+
|
|
604
|
+
== See Also
|
|
605
|
+
|
|
606
|
+
* link:archive-formats.adoc[Archive Formats]
|
|
607
|
+
* link:advanced-features.adoc[Advanced Features]
|
|
608
|
+
* link:../README.adoc[Main README]
|