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,232 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
|
|
5
|
+
module Omnizip
|
|
6
|
+
module Formats
|
|
7
|
+
module Cpio
|
|
8
|
+
# CPIO archive writer
|
|
9
|
+
#
|
|
10
|
+
# Creates CPIO archives in newc, CRC, or ODC format.
|
|
11
|
+
# Ported from libarchive's archive_write_set_format_cpio_newc.c
|
|
12
|
+
#
|
|
13
|
+
# @example Create CPIO archive
|
|
14
|
+
# writer = Cpio::Writer.new('archive.cpio')
|
|
15
|
+
# writer.add_file('file.txt')
|
|
16
|
+
# writer.add_directory('dir/')
|
|
17
|
+
# writer.write
|
|
18
|
+
#
|
|
19
|
+
# @example With CRC format
|
|
20
|
+
# writer = Cpio::Writer.new('archive.cpio', format: :crc)
|
|
21
|
+
# writer.add_directory('initramfs/')
|
|
22
|
+
# writer.write
|
|
23
|
+
class Writer
|
|
24
|
+
include Omnizip::Formats::Cpio::Constants
|
|
25
|
+
|
|
26
|
+
# @return [String] Output archive path
|
|
27
|
+
attr_reader :output_path
|
|
28
|
+
|
|
29
|
+
# @return [Symbol] CPIO format (:newc, :crc, :odc)
|
|
30
|
+
attr_reader :format
|
|
31
|
+
|
|
32
|
+
# @return [Array<Entry>] Entries to write
|
|
33
|
+
attr_reader :entries
|
|
34
|
+
|
|
35
|
+
# Initialize CPIO writer
|
|
36
|
+
#
|
|
37
|
+
# @param output_path [String] Output CPIO file path
|
|
38
|
+
# @param format [Symbol] CPIO format (:newc, :crc, :odc)
|
|
39
|
+
def initialize(output_path, format: :newc)
|
|
40
|
+
@output_path = output_path
|
|
41
|
+
@format = validate_format(format)
|
|
42
|
+
@entries = []
|
|
43
|
+
@inode_counter = 1
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Add file to archive
|
|
47
|
+
#
|
|
48
|
+
# @param file_path [String] Source file path
|
|
49
|
+
# @param cpio_path [String, nil] Path in archive (defaults to file_path)
|
|
50
|
+
# @raise [ArgumentError] if file doesn't exist
|
|
51
|
+
def add_file(file_path, cpio_path = nil)
|
|
52
|
+
raise ArgumentError, "File not found: #{file_path}" unless
|
|
53
|
+
File.exist?(file_path) || File.symlink?(file_path)
|
|
54
|
+
|
|
55
|
+
# Default to basename if no cpio_path specified
|
|
56
|
+
cpio_path = File.basename(file_path) if cpio_path.nil?
|
|
57
|
+
# Use lstat to not follow symlinks
|
|
58
|
+
stat = File.lstat(file_path)
|
|
59
|
+
|
|
60
|
+
# Normalize path: remove leading slashes to make relative
|
|
61
|
+
cpio_path = cpio_path.sub(%r{^/+}, "")
|
|
62
|
+
|
|
63
|
+
# Read file data unless it's a symlink
|
|
64
|
+
data = if File.symlink?(file_path)
|
|
65
|
+
File.readlink(file_path)
|
|
66
|
+
elsif stat.file?
|
|
67
|
+
File.binread(file_path)
|
|
68
|
+
else
|
|
69
|
+
""
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
entry = create_entry_from_stat(cpio_path, stat, data)
|
|
73
|
+
@entries << entry
|
|
74
|
+
@inode_counter += 1
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Add directory to archive
|
|
78
|
+
#
|
|
79
|
+
# @param dir_path [String] Source directory path
|
|
80
|
+
# @param recursive [Boolean] Include subdirectories
|
|
81
|
+
# @param cpio_path [String, nil] Path in archive
|
|
82
|
+
# @raise [ArgumentError] if directory doesn't exist
|
|
83
|
+
def add_directory(dir_path, recursive: true, cpio_path: nil)
|
|
84
|
+
raise ArgumentError, "Directory not found: #{dir_path}" unless
|
|
85
|
+
Dir.exist?(dir_path)
|
|
86
|
+
|
|
87
|
+
# Default to basename if no cpio_path specified
|
|
88
|
+
cpio_path = File.basename(dir_path) if cpio_path.nil?
|
|
89
|
+
# Normalize path: remove leading slashes to make relative
|
|
90
|
+
cpio_path = cpio_path.sub(%r{^/+}, "")
|
|
91
|
+
stat = File.lstat(dir_path)
|
|
92
|
+
|
|
93
|
+
# Add directory entry
|
|
94
|
+
entry = create_entry_from_stat(cpio_path, stat, "")
|
|
95
|
+
@entries << entry
|
|
96
|
+
@inode_counter += 1
|
|
97
|
+
|
|
98
|
+
# Add contents if recursive
|
|
99
|
+
if recursive
|
|
100
|
+
Dir.foreach(dir_path) do |item|
|
|
101
|
+
next if [".", ".."].include?(item)
|
|
102
|
+
|
|
103
|
+
item_path = File.join(dir_path, item)
|
|
104
|
+
item_cpio_path = "#{cpio_path}/#{item}"
|
|
105
|
+
|
|
106
|
+
if File.directory?(item_path)
|
|
107
|
+
add_directory(item_path, recursive: true,
|
|
108
|
+
cpio_path: item_cpio_path)
|
|
109
|
+
else
|
|
110
|
+
add_file(item_path, item_cpio_path)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Write CPIO archive
|
|
117
|
+
#
|
|
118
|
+
# @raise [IOError] if write fails
|
|
119
|
+
def write
|
|
120
|
+
File.open(@output_path, "wb") do |io|
|
|
121
|
+
# Write all entries
|
|
122
|
+
@entries.each do |entry|
|
|
123
|
+
write_entry(io, entry)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Write trailer
|
|
127
|
+
write_trailer(io)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
@output_path
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
# Validate format
|
|
136
|
+
#
|
|
137
|
+
# @param format [Symbol] Format to validate
|
|
138
|
+
# @return [Symbol] Validated format
|
|
139
|
+
# @raise [ArgumentError] if format invalid
|
|
140
|
+
def validate_format(format)
|
|
141
|
+
unless %i[newc crc odc].include?(format)
|
|
142
|
+
raise ArgumentError, "Invalid CPIO format: #{format}. " \
|
|
143
|
+
"Must be :newc, :crc, or :odc"
|
|
144
|
+
end
|
|
145
|
+
format
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Create entry from file stat
|
|
149
|
+
#
|
|
150
|
+
# @param path [String] Entry path
|
|
151
|
+
# @param stat [File::Stat] File statistics
|
|
152
|
+
# @param data [String] File data
|
|
153
|
+
# @return [Entry] Created entry
|
|
154
|
+
def create_entry_from_stat(path, stat, data)
|
|
155
|
+
Entry.new(
|
|
156
|
+
magic: format_magic,
|
|
157
|
+
ino: @inode_counter,
|
|
158
|
+
mode: stat.mode,
|
|
159
|
+
uid: stat.uid,
|
|
160
|
+
gid: stat.gid,
|
|
161
|
+
nlink: stat.nlink,
|
|
162
|
+
mtime: stat.mtime.to_i,
|
|
163
|
+
filesize: data.bytesize,
|
|
164
|
+
dev_major: (stat.dev >> 8) & 0xFF,
|
|
165
|
+
dev_minor: stat.dev & 0xFF,
|
|
166
|
+
rdev_major: stat.rdev ? (stat.rdev >> 8) & 0xFF : 0,
|
|
167
|
+
rdev_minor: stat.rdev ? (stat.rdev & 0xFF) : 0,
|
|
168
|
+
namesize: path.bytesize + 1,
|
|
169
|
+
checksum: @format == :crc ? calculate_checksum(data) : 0,
|
|
170
|
+
name: path,
|
|
171
|
+
data: data,
|
|
172
|
+
)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Get magic number for current format
|
|
176
|
+
#
|
|
177
|
+
# @return [String] Magic number
|
|
178
|
+
def format_magic
|
|
179
|
+
case @format
|
|
180
|
+
when :newc then MAGIC_NEWC
|
|
181
|
+
when :crc then MAGIC_CRC
|
|
182
|
+
when :odc then MAGIC_ODC
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Write entry to archive
|
|
187
|
+
#
|
|
188
|
+
# @param io [IO] Output stream
|
|
189
|
+
# @param entry [Entry] Entry to write
|
|
190
|
+
def write_entry(io, entry)
|
|
191
|
+
binary_data = entry.to_binary(format: @format)
|
|
192
|
+
io.write(binary_data)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Write trailer entry
|
|
196
|
+
#
|
|
197
|
+
# @param io [IO] Output stream
|
|
198
|
+
def write_trailer(io)
|
|
199
|
+
trailer = Entry.new(
|
|
200
|
+
magic: format_magic,
|
|
201
|
+
ino: 0,
|
|
202
|
+
mode: 0,
|
|
203
|
+
uid: 0,
|
|
204
|
+
gid: 0,
|
|
205
|
+
nlink: 1,
|
|
206
|
+
mtime: 0,
|
|
207
|
+
filesize: 0,
|
|
208
|
+
dev_major: 0,
|
|
209
|
+
dev_minor: 0,
|
|
210
|
+
rdev_major: 0,
|
|
211
|
+
rdev_minor: 0,
|
|
212
|
+
namesize: TRAILER_NAME.bytesize + 1,
|
|
213
|
+
checksum: 0,
|
|
214
|
+
name: TRAILER_NAME,
|
|
215
|
+
data: "",
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
write_entry(io, trailer)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# Calculate checksum for CRC format
|
|
222
|
+
#
|
|
223
|
+
# @param data [String] Data to checksum
|
|
224
|
+
# @return [Integer] CRC32 checksum
|
|
225
|
+
def calculate_checksum(data)
|
|
226
|
+
require "zlib"
|
|
227
|
+
Zlib.crc32(data) & 0xFFFFFFFF
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Formats
|
|
5
|
+
# CPIO archive format support
|
|
6
|
+
#
|
|
7
|
+
# Provides read and write access to CPIO archives in multiple formats:
|
|
8
|
+
# - newc (SVR4 new ASCII format) - Most common, used in initramfs
|
|
9
|
+
# - CRC (newc with CRC checksums)
|
|
10
|
+
# - ODC (Old portable ASCII format)
|
|
11
|
+
#
|
|
12
|
+
# CPIO is commonly used for:
|
|
13
|
+
# - Linux initramfs/initrd
|
|
14
|
+
# - RPM package contents
|
|
15
|
+
# - Unix system backups
|
|
16
|
+
#
|
|
17
|
+
# @example Create CPIO archive
|
|
18
|
+
# Omnizip::Formats::Cpio.create('archive.cpio') do |cpio|
|
|
19
|
+
# cpio.add_directory('files/')
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# @example Extract CPIO archive
|
|
23
|
+
# Omnizip::Formats::Cpio.extract('archive.cpio', 'output/')
|
|
24
|
+
module Cpio
|
|
25
|
+
# Nested classes - autoloaded
|
|
26
|
+
autoload :Constants, "omnizip/formats/cpio/constants"
|
|
27
|
+
autoload :Entry, "omnizip/formats/cpio/entry"
|
|
28
|
+
autoload :Writer, "omnizip/formats/cpio/writer"
|
|
29
|
+
autoload :Reader, "omnizip/formats/cpio/reader"
|
|
30
|
+
|
|
31
|
+
class << self
|
|
32
|
+
# Create CPIO archive
|
|
33
|
+
#
|
|
34
|
+
# @param path [String] Output CPIO file path
|
|
35
|
+
# @param format [Symbol] CPIO format (:newc, :crc, :odc)
|
|
36
|
+
# @yield [writer] Block for adding files/directories
|
|
37
|
+
# @yieldparam writer [Writer] CPIO writer
|
|
38
|
+
# @return [String] Path to created archive
|
|
39
|
+
#
|
|
40
|
+
# @example Create newc format archive
|
|
41
|
+
# Omnizip::Formats::Cpio.create('archive.cpio') do |cpio|
|
|
42
|
+
# cpio.add_file('kernel.img')
|
|
43
|
+
# cpio.add_directory('modules/')
|
|
44
|
+
# end
|
|
45
|
+
#
|
|
46
|
+
# @example Create with CRC checksums
|
|
47
|
+
# Omnizip::Formats::Cpio.create('archive.cpio', format: :crc) do |cpio|
|
|
48
|
+
# cpio.add_directory('initramfs/')
|
|
49
|
+
# end
|
|
50
|
+
def create(path, format: :newc)
|
|
51
|
+
writer = Writer.new(path, format: format)
|
|
52
|
+
|
|
53
|
+
yield writer if block_given?
|
|
54
|
+
|
|
55
|
+
writer.write
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Open CPIO archive for reading
|
|
59
|
+
#
|
|
60
|
+
# @param path [String] Path to CPIO file
|
|
61
|
+
# @yield [reader] Block for reading archive
|
|
62
|
+
# @yieldparam reader [Reader] CPIO reader
|
|
63
|
+
# @return [Reader] CPIO reader
|
|
64
|
+
#
|
|
65
|
+
# @example Read CPIO archive
|
|
66
|
+
# Omnizip::Formats::Cpio.open('archive.cpio') do |cpio|
|
|
67
|
+
# cpio.entries.each { |entry| puts entry.name }
|
|
68
|
+
# end
|
|
69
|
+
def open(path)
|
|
70
|
+
reader = Reader.new(path)
|
|
71
|
+
reader.open
|
|
72
|
+
|
|
73
|
+
if block_given?
|
|
74
|
+
yield reader
|
|
75
|
+
else
|
|
76
|
+
reader
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# List CPIO archive contents
|
|
81
|
+
#
|
|
82
|
+
# @param path [String] Path to CPIO file
|
|
83
|
+
# @return [Array<Entry>] Archive entries
|
|
84
|
+
#
|
|
85
|
+
# @example List archive contents
|
|
86
|
+
# entries = Omnizip::Formats::Cpio.list('archive.cpio')
|
|
87
|
+
# entries.each { |e| puts "#{e.name} (#{e.filesize} bytes)" }
|
|
88
|
+
def list(path)
|
|
89
|
+
open(path, &:list)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Extract CPIO archive
|
|
93
|
+
#
|
|
94
|
+
# @param cpio_path [String] Path to CPIO file
|
|
95
|
+
# @param output_dir [String] Output directory
|
|
96
|
+
#
|
|
97
|
+
# @example Extract archive
|
|
98
|
+
# Omnizip::Formats::Cpio.extract('archive.cpio', 'output/')
|
|
99
|
+
def extract(cpio_path, output_dir)
|
|
100
|
+
open(cpio_path) do |cpio|
|
|
101
|
+
cpio.extract_all(output_dir)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Get archive information
|
|
106
|
+
#
|
|
107
|
+
# @param path [String] Path to CPIO file
|
|
108
|
+
# @return [Hash] Archive information
|
|
109
|
+
#
|
|
110
|
+
# @example Get archive info
|
|
111
|
+
# info = Omnizip::Formats::Cpio.info('archive.cpio')
|
|
112
|
+
# puts "Format: #{info[:format]}"
|
|
113
|
+
# puts "Files: #{info[:file_count]}"
|
|
114
|
+
def info(path)
|
|
115
|
+
open(path) do |cpio|
|
|
116
|
+
entries = cpio.list
|
|
117
|
+
|
|
118
|
+
{
|
|
119
|
+
format: cpio.format_name,
|
|
120
|
+
format_type: cpio.format,
|
|
121
|
+
entry_count: entries.size,
|
|
122
|
+
file_count: entries.count(&:file?),
|
|
123
|
+
directory_count: entries.count(&:directory?),
|
|
124
|
+
symlink_count: entries.count(&:symlink?),
|
|
125
|
+
total_size: entries.sum(&:filesize),
|
|
126
|
+
}
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "yaml"
|
|
4
|
+
begin
|
|
5
|
+
require "lutaml/model"
|
|
6
|
+
rescue LoadError, ArgumentError
|
|
7
|
+
# lutaml-model not available, using simple classes
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module Omnizip
|
|
11
|
+
module Formats
|
|
12
|
+
# Loads and manages format specifications from YAML configuration files
|
|
13
|
+
#
|
|
14
|
+
# This class provides a configuration-driven architecture for archive formats,
|
|
15
|
+
# allowing format specifications to be externalized in YAML files rather than
|
|
16
|
+
# hardcoded in the application.
|
|
17
|
+
#
|
|
18
|
+
# @example Loading a format specification
|
|
19
|
+
# spec = FormatSpecLoader.load("rar5")
|
|
20
|
+
# spec.format.name # => "RAR5"
|
|
21
|
+
# spec.format.magic_bytes # => [0x52, 0x61, 0x72, ...]
|
|
22
|
+
#
|
|
23
|
+
# @example Getting all loaded specifications
|
|
24
|
+
# specs = FormatSpecLoader.all_specs
|
|
25
|
+
# specs.keys # => ["rar3", "rar5", "zip", ...]
|
|
26
|
+
class FormatSpecLoader
|
|
27
|
+
class << self
|
|
28
|
+
# Load a format specification from a YAML file
|
|
29
|
+
#
|
|
30
|
+
# @param format_name [String] The name of the format (e.g., "rar5")
|
|
31
|
+
# @param config_dir [String] The directory containing format specs
|
|
32
|
+
# @return [FormatSpecification] The loaded format specification
|
|
33
|
+
# @raise [FormatError] If the specification file is not found
|
|
34
|
+
# or invalid
|
|
35
|
+
def load(format_name, config_dir: default_config_dir)
|
|
36
|
+
spec_file = File.join(config_dir, "#{format_name}_spec.yml")
|
|
37
|
+
|
|
38
|
+
unless File.exist?(spec_file)
|
|
39
|
+
raise FormatError,
|
|
40
|
+
"Format specification not found: #{spec_file}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
yaml_content = File.read(spec_file)
|
|
44
|
+
parsed_yaml = YAML.safe_load(
|
|
45
|
+
yaml_content,
|
|
46
|
+
permitted_classes: [Symbol],
|
|
47
|
+
symbolize_names: true,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
validate_spec(parsed_yaml, format_name)
|
|
51
|
+
|
|
52
|
+
spec = FormatSpecification.new(parsed_yaml)
|
|
53
|
+
register_spec(format_name, spec)
|
|
54
|
+
spec
|
|
55
|
+
rescue Psych::SyntaxError => e
|
|
56
|
+
raise FormatError,
|
|
57
|
+
"Invalid YAML in #{spec_file}: #{e.message}"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Get all loaded format specifications
|
|
61
|
+
#
|
|
62
|
+
# @return [Hash<String, FormatSpecification>] All loaded specs
|
|
63
|
+
def all_specs
|
|
64
|
+
@all_specs ||= {}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Clear all loaded specifications (primarily for testing)
|
|
68
|
+
#
|
|
69
|
+
# @return [void]
|
|
70
|
+
def clear_specs
|
|
71
|
+
@all_specs = {}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Check if a format specification is loaded
|
|
75
|
+
#
|
|
76
|
+
# @param format_name [String] The format name
|
|
77
|
+
# @return [Boolean] True if loaded, false otherwise
|
|
78
|
+
def loaded?(format_name)
|
|
79
|
+
all_specs.key?(format_name)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Get a loaded specification
|
|
83
|
+
#
|
|
84
|
+
# @param format_name [String] The format name
|
|
85
|
+
# @return [FormatSpecification, nil] The spec or nil if not loaded
|
|
86
|
+
def get(format_name)
|
|
87
|
+
all_specs[format_name]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Load all format specifications from a directory
|
|
91
|
+
#
|
|
92
|
+
# @param config_dir [String] The directory containing format specs
|
|
93
|
+
# @return [Hash<String, FormatSpecification>] All loaded specs
|
|
94
|
+
def load_all(config_dir: default_config_dir)
|
|
95
|
+
return all_specs unless Dir.exist?(config_dir)
|
|
96
|
+
|
|
97
|
+
Dir.glob(File.join(config_dir, "*_spec.yml")).each do |spec_file|
|
|
98
|
+
format_name = File.basename(spec_file, "_spec.yml")
|
|
99
|
+
unless loaded?(format_name)
|
|
100
|
+
load(format_name,
|
|
101
|
+
config_dir: config_dir)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
all_specs
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
# Default configuration directory for format specifications
|
|
111
|
+
#
|
|
112
|
+
# @return [String] The default config directory path
|
|
113
|
+
def default_config_dir
|
|
114
|
+
File.join(__dir__, "../../../config/formats")
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Register a loaded specification
|
|
118
|
+
#
|
|
119
|
+
# @param format_name [String] The format name
|
|
120
|
+
# @param spec [FormatSpecification] The specification to register
|
|
121
|
+
# @return [void]
|
|
122
|
+
def register_spec(format_name, spec)
|
|
123
|
+
all_specs[format_name] = spec
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Validate a parsed YAML specification
|
|
127
|
+
#
|
|
128
|
+
# @param parsed_yaml [Hash] The parsed YAML content
|
|
129
|
+
# @param format_name [String] The format name
|
|
130
|
+
# @return [void]
|
|
131
|
+
# @raise [FormatError] If the spec is invalid
|
|
132
|
+
def validate_spec(parsed_yaml, format_name)
|
|
133
|
+
unless parsed_yaml.is_a?(Hash) && parsed_yaml[:format]
|
|
134
|
+
raise FormatError,
|
|
135
|
+
"Invalid format specification for #{format_name}: " \
|
|
136
|
+
"missing 'format' key"
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
format_data = parsed_yaml[:format]
|
|
140
|
+
required_keys = %i[name version magic_bytes]
|
|
141
|
+
|
|
142
|
+
required_keys.each do |key|
|
|
143
|
+
next if format_data[key]
|
|
144
|
+
|
|
145
|
+
raise FormatError,
|
|
146
|
+
"Invalid format specification for #{format_name}: " \
|
|
147
|
+
"missing required key '#{key}'"
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Model class for encryption data
|
|
154
|
+
class EncryptionData < Lutaml::Model::Serializable
|
|
155
|
+
attribute :supported, :boolean
|
|
156
|
+
attribute :algorithms, :string, collection: true
|
|
157
|
+
attribute :key_derivation, :string
|
|
158
|
+
attribute :kdf_iterations, :integer
|
|
159
|
+
attribute :salt_size, :integer
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Model class for checksum data
|
|
163
|
+
class ChecksumData < Lutaml::Model::Serializable
|
|
164
|
+
attribute :algorithm, :string
|
|
165
|
+
attribute :size, :integer
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Model class for format data
|
|
169
|
+
class FormatData < Lutaml::Model::Serializable
|
|
170
|
+
attribute :name, :string
|
|
171
|
+
attribute :version, :string
|
|
172
|
+
attribute :extension, :string
|
|
173
|
+
attribute :magic_bytes, :integer, collection: true
|
|
174
|
+
attribute :block_types, :hash
|
|
175
|
+
attribute :archive_flags, :hash
|
|
176
|
+
attribute :main_header_flags, :hash
|
|
177
|
+
attribute :file_header_flags, :hash
|
|
178
|
+
attribute :file_flags, :hash
|
|
179
|
+
attribute :encryption_flags, :hash
|
|
180
|
+
attribute :compression_methods, :hash
|
|
181
|
+
attribute :host_os, :hash
|
|
182
|
+
attribute :dictionary_sizes, :hash
|
|
183
|
+
attribute :encryption, EncryptionData
|
|
184
|
+
attribute :checksum, ChecksumData
|
|
185
|
+
attribute :features, :hash
|
|
186
|
+
attribute :compression_features, :hash
|
|
187
|
+
attribute :advanced_features, :hash
|
|
188
|
+
attribute :extra_records, :hash
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Model class representing a format specification
|
|
192
|
+
#
|
|
193
|
+
# This class uses Lutaml::Model to provide a structured representation
|
|
194
|
+
# of format specifications loaded from YAML files.
|
|
195
|
+
class FormatSpecification < Lutaml::Model::Serializable
|
|
196
|
+
attribute :format, FormatData
|
|
197
|
+
|
|
198
|
+
# Get a value from the format specification
|
|
199
|
+
#
|
|
200
|
+
# @param key [Symbol, String] The key to retrieve
|
|
201
|
+
# @return [Object] The value for the key
|
|
202
|
+
def [](key)
|
|
203
|
+
format.public_send(key)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Get magic bytes as an array of integers
|
|
207
|
+
#
|
|
208
|
+
# @return [Array<Integer>] The magic bytes
|
|
209
|
+
def magic_bytes
|
|
210
|
+
format.magic_bytes
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Get the format name
|
|
214
|
+
#
|
|
215
|
+
# @return [String] The format name
|
|
216
|
+
def name
|
|
217
|
+
format.name
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Get the format version
|
|
221
|
+
#
|
|
222
|
+
# @return [String] The format version
|
|
223
|
+
def version
|
|
224
|
+
format.version
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|