omnizip 0.4.7-arm-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,160 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Zip
|
|
5
|
+
# Rubyzip-compatible Entry class
|
|
6
|
+
# Wraps CentralDirectoryHeader with rubyzip API
|
|
7
|
+
class Entry
|
|
8
|
+
include Omnizip::Entry
|
|
9
|
+
|
|
10
|
+
attr_reader :header, :ftype, :filepath
|
|
11
|
+
|
|
12
|
+
def entry_name = name
|
|
13
|
+
def entry_directory? = directory?
|
|
14
|
+
def entry_size = size
|
|
15
|
+
def entry_mtime = time
|
|
16
|
+
|
|
17
|
+
# Create entry from CentralDirectoryHeader
|
|
18
|
+
def initialize(header, filepath: nil)
|
|
19
|
+
@header = header
|
|
20
|
+
@filepath = filepath
|
|
21
|
+
@ftype = header.directory? ? :directory : :file
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Entry name (path within archive)
|
|
25
|
+
def name
|
|
26
|
+
header.filename
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Uncompressed size
|
|
30
|
+
def size
|
|
31
|
+
header.uncompressed_size
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Compressed size
|
|
35
|
+
def compressed_size
|
|
36
|
+
header.compressed_size
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# CRC32 checksum
|
|
40
|
+
def crc
|
|
41
|
+
header.crc32
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Compression method ID
|
|
45
|
+
def compression_method
|
|
46
|
+
header.compression_method
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Modification time
|
|
50
|
+
def time
|
|
51
|
+
dos_time_to_time(header.last_mod_date, header.last_mod_time)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Is this a directory?
|
|
55
|
+
def directory?
|
|
56
|
+
@ftype == :directory
|
|
57
|
+
end
|
|
58
|
+
alias_method :is_directory, :directory?
|
|
59
|
+
|
|
60
|
+
# Is this a file?
|
|
61
|
+
def file?
|
|
62
|
+
@ftype == :file
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Is this a symbolic link?
|
|
66
|
+
def symlink?
|
|
67
|
+
false # Not supported yet
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Get comment
|
|
71
|
+
def comment
|
|
72
|
+
header.comment || ""
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Set comment
|
|
76
|
+
def comment=(value)
|
|
77
|
+
header.comment = value
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Get extra field
|
|
81
|
+
def extra
|
|
82
|
+
header.extra_field || ""
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Set extra field
|
|
86
|
+
def extra=(value)
|
|
87
|
+
header.extra_field = value
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Unix permissions
|
|
91
|
+
def unix_perms
|
|
92
|
+
header.unix_permissions
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Set Unix permissions
|
|
96
|
+
def unix_perms=(perms)
|
|
97
|
+
header.unix_permissions = perms
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Get metadata for this entry
|
|
101
|
+
# @return [Omnizip::Metadata::EntryMetadata] Entry metadata
|
|
102
|
+
def metadata
|
|
103
|
+
@metadata ||= Omnizip::Metadata::EntryMetadata.new(self)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Save metadata changes
|
|
107
|
+
# Marks the entry as modified so changes are written on archive close
|
|
108
|
+
def save_metadata
|
|
109
|
+
# Changes are already applied to the header
|
|
110
|
+
# This is a convenience method for the API
|
|
111
|
+
metadata.reset_modified
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Extract this entry to a destination path
|
|
115
|
+
# Note: This requires access to the archive file
|
|
116
|
+
def extract(dest_path)
|
|
117
|
+
raise NotImplementedError,
|
|
118
|
+
"Entry#extract requires File context. Use Omnizip::Zip::File#extract instead"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Get input stream for this entry
|
|
122
|
+
# Note: This requires access to the archive file
|
|
123
|
+
def get_input_stream
|
|
124
|
+
raise NotImplementedError,
|
|
125
|
+
"Entry#get_input_stream requires File context"
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# String representation
|
|
129
|
+
def to_s
|
|
130
|
+
name
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Equality comparison
|
|
134
|
+
def ==(other)
|
|
135
|
+
return false unless other.is_a?(Entry)
|
|
136
|
+
|
|
137
|
+
name == other.name
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
private
|
|
141
|
+
|
|
142
|
+
# Convert DOS date/time to Ruby Time
|
|
143
|
+
def dos_time_to_time(dos_date, dos_time)
|
|
144
|
+
return Time.now if dos_date.zero? && dos_time.zero?
|
|
145
|
+
|
|
146
|
+
year = ((dos_date >> 9) & 0x7F) + 1980
|
|
147
|
+
month = (dos_date >> 5) & 0x0F
|
|
148
|
+
day = dos_date & 0x1F
|
|
149
|
+
|
|
150
|
+
hour = (dos_time >> 11) & 0x1F
|
|
151
|
+
min = (dos_time >> 5) & 0x3F
|
|
152
|
+
sec = (dos_time & 0x1F) * 2
|
|
153
|
+
|
|
154
|
+
Time.new(year, month, day, hour, min, sec)
|
|
155
|
+
rescue ArgumentError
|
|
156
|
+
Time.now
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "stringio"
|
|
5
|
+
|
|
6
|
+
module Omnizip
|
|
7
|
+
module Zip
|
|
8
|
+
# Rubyzip-compatible File class
|
|
9
|
+
# Provides drop-in replacement for Zip::File from rubyzip
|
|
10
|
+
class File
|
|
11
|
+
include Enumerable
|
|
12
|
+
|
|
13
|
+
attr_reader :name, :entries, :comment
|
|
14
|
+
|
|
15
|
+
# Open a ZIP archive
|
|
16
|
+
# @param file_path [String] Path to ZIP file
|
|
17
|
+
# @param create [Boolean] Create file if it doesn't exist
|
|
18
|
+
# @param options [Hash] Additional options
|
|
19
|
+
# @yield [file] Block to execute with the opened archive
|
|
20
|
+
# @return [File] The opened archive (if no block given)
|
|
21
|
+
def self.open(file_path, create: false, **options)
|
|
22
|
+
file = new(file_path, create: create, **options)
|
|
23
|
+
|
|
24
|
+
if block_given?
|
|
25
|
+
begin
|
|
26
|
+
yield(file)
|
|
27
|
+
ensure
|
|
28
|
+
file.close
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
file
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Create a new archive from scratch
|
|
36
|
+
# @param file_path [String] Path to ZIP file
|
|
37
|
+
# @yield [file] Block to execute with the new archive
|
|
38
|
+
def self.create(file_path, &block)
|
|
39
|
+
open(file_path, create: true, &block)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Initialize a ZIP file
|
|
43
|
+
# @param file_path [String] Path to ZIP file
|
|
44
|
+
# @param create [Boolean] Create file if it doesn't exist
|
|
45
|
+
def initialize(file_path, create: false, **options)
|
|
46
|
+
@name = file_path
|
|
47
|
+
@entries = []
|
|
48
|
+
@comment = ""
|
|
49
|
+
@create = create
|
|
50
|
+
@options = options
|
|
51
|
+
@modified = false
|
|
52
|
+
@reader = nil
|
|
53
|
+
@writer = nil
|
|
54
|
+
# Load existing archive if it exists
|
|
55
|
+
if ::File.exist?(file_path) && !create
|
|
56
|
+
load_archive
|
|
57
|
+
elsif create
|
|
58
|
+
# Will create on write/close
|
|
59
|
+
@modified = true
|
|
60
|
+
elsif !::File.exist?(file_path)
|
|
61
|
+
raise Errno::ENOENT, "No such file or directory - #{file_path}"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Add a file to the archive
|
|
66
|
+
# @param entry_name [String] Name in the archive
|
|
67
|
+
# @param src_path [String, nil] Source file path (optional if block given)
|
|
68
|
+
# @yield Block that returns content to add
|
|
69
|
+
def add(entry_name, src_path = nil)
|
|
70
|
+
# Handle directory entries (ending with /)
|
|
71
|
+
if entry_name.end_with?("/") && !src_path && !block_given?
|
|
72
|
+
add_directory(entry_name)
|
|
73
|
+
elsif block_given?
|
|
74
|
+
data = yield
|
|
75
|
+
add_data(entry_name, data)
|
|
76
|
+
elsif src_path
|
|
77
|
+
add_file_from_path(entry_name, src_path)
|
|
78
|
+
else
|
|
79
|
+
raise ArgumentError, "Either src_path or block must be provided"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
@modified = true
|
|
83
|
+
self
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Get entry by name
|
|
87
|
+
# @param entry_name [String] Name of the entry
|
|
88
|
+
# @return [Entry, nil] The entry or nil if not found
|
|
89
|
+
def get_entry(entry_name)
|
|
90
|
+
entries.find { |e| e.name == entry_name }
|
|
91
|
+
end
|
|
92
|
+
alias_method :find_entry, :get_entry
|
|
93
|
+
|
|
94
|
+
# Get input stream for an entry
|
|
95
|
+
# @param entry [Entry, String] Entry object or name
|
|
96
|
+
# @yield [stream] Block to read from the stream
|
|
97
|
+
# @return [String] Entry content (if no block given)
|
|
98
|
+
# rubocop:disable-next Naming/BlockForwarding, Style/ArgumentsForwarding, Style/BlockDelimiters -- Ruby 3.0 compatibility
|
|
99
|
+
def get_input_stream(entry, &block)
|
|
100
|
+
entry = get_entry(entry) if entry.is_a?(String)
|
|
101
|
+
raise Errno::ENOENT, "Entry not found: #{entry}" unless entry
|
|
102
|
+
|
|
103
|
+
content = read_entry_data(entry)
|
|
104
|
+
|
|
105
|
+
if block
|
|
106
|
+
StringIO.open(content, "rb", &block)
|
|
107
|
+
else
|
|
108
|
+
content
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
alias_method :read, :get_input_stream
|
|
112
|
+
|
|
113
|
+
# Iterate over all entries
|
|
114
|
+
# @yield [entry] Block to execute for each entry
|
|
115
|
+
# rubocop:disable-next Naming/BlockForwarding, Style/ArgumentsForwarding -- Ruby 3.0 compatibility
|
|
116
|
+
def each(&block)
|
|
117
|
+
entries.each(&block)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Extract an entry to a destination path
|
|
121
|
+
# @param entry [Entry, String] Entry object or name
|
|
122
|
+
# @param dest_path [String] Destination file path
|
|
123
|
+
def extract(entry, dest_path, &on_exists_proc)
|
|
124
|
+
entry = get_entry(entry) if entry.is_a?(String)
|
|
125
|
+
raise Errno::ENOENT, "Entry not found: #{entry}" unless entry
|
|
126
|
+
|
|
127
|
+
# Handle existing file
|
|
128
|
+
if ::File.exist?(dest_path)
|
|
129
|
+
if on_exists_proc
|
|
130
|
+
action = yield(entry, dest_path)
|
|
131
|
+
return if action == false
|
|
132
|
+
else
|
|
133
|
+
raise Errno::EEXIST, "Destination file already exists: #{dest_path}"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
extract_entry_to_path(entry, dest_path)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Remove an entry from the archive
|
|
141
|
+
# @param entry_name [String] Name of the entry to remove
|
|
142
|
+
def remove(entry_name)
|
|
143
|
+
entry = get_entry(entry_name)
|
|
144
|
+
@entries.delete(entry) if entry
|
|
145
|
+
@modified = true
|
|
146
|
+
@reader = nil
|
|
147
|
+
self
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Rename an entry
|
|
151
|
+
# @param entry_name [String] Current entry name
|
|
152
|
+
# @param new_name [String] New entry name
|
|
153
|
+
def rename(entry_name, new_name)
|
|
154
|
+
entry = get_entry(entry_name)
|
|
155
|
+
return unless entry
|
|
156
|
+
|
|
157
|
+
entry.header.filename = new_name
|
|
158
|
+
@modified = true
|
|
159
|
+
self
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Replace entry content
|
|
163
|
+
# @param entry_name [String] Entry name
|
|
164
|
+
# @param src_path [String, nil] Source file path
|
|
165
|
+
# rubocop:disable-next Naming/BlockForwarding, Style/ArgumentsForwarding -- Ruby 3.0 compatibility
|
|
166
|
+
def replace(entry_name, src_path = nil, &block)
|
|
167
|
+
remove(entry_name)
|
|
168
|
+
add(entry_name, src_path, &block)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Get archive comment
|
|
172
|
+
def comment
|
|
173
|
+
@comment
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Set archive comment
|
|
177
|
+
def comment=(value)
|
|
178
|
+
@comment = value.to_s
|
|
179
|
+
@modified = true
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Get number of entries
|
|
183
|
+
def size
|
|
184
|
+
entries.size
|
|
185
|
+
end
|
|
186
|
+
alias_method :length, :size
|
|
187
|
+
|
|
188
|
+
# Mark this archive as having unsaved changes. The next +#commit+
|
|
189
|
+
# or +#close+ will write the archive to disk.
|
|
190
|
+
def modified!
|
|
191
|
+
@modified = true
|
|
192
|
+
self
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# True if there are unsaved changes.
|
|
196
|
+
def modified?
|
|
197
|
+
@modified
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Check if archive contains an entry
|
|
201
|
+
# @param entry_name [String] Entry name to check
|
|
202
|
+
# @return [Boolean] True if entry exists
|
|
203
|
+
def include?(entry_name)
|
|
204
|
+
!get_entry(entry_name).nil?
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Get names of all entries
|
|
208
|
+
# @return [Array<String>] Array of entry names
|
|
209
|
+
def names
|
|
210
|
+
entries.map(&:name)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Glob entries by pattern
|
|
214
|
+
# @param pattern [String] Glob pattern
|
|
215
|
+
# @return [Array<Entry>] Matching entries
|
|
216
|
+
# rubocop:disable-next Naming/BlockForwarding, Style/ArgumentsForwarding, Style/BlockDelimiters -- Ruby 3.0 compatibility
|
|
217
|
+
def glob(pattern, &block)
|
|
218
|
+
matching = entries.select { |e| ::File.fnmatch(pattern, e.name) }
|
|
219
|
+
|
|
220
|
+
if block
|
|
221
|
+
matching.each(&block)
|
|
222
|
+
else
|
|
223
|
+
matching
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Extract files matching a pattern
|
|
228
|
+
# @param pattern [String, Regexp, Array] Pattern(s) to match
|
|
229
|
+
# @param dest [String] Destination directory
|
|
230
|
+
# @param options [Hash] Extraction options
|
|
231
|
+
# @option options [Boolean] :preserve_paths Keep directory structure
|
|
232
|
+
# @option options [Boolean] :flatten Extract all to destination root
|
|
233
|
+
# @option options [Boolean] :overwrite Overwrite existing files
|
|
234
|
+
# @return [Array<String>] Paths of extracted files
|
|
235
|
+
def extract_matching(pattern, dest, options = {})
|
|
236
|
+
Omnizip::Extraction.extract_matching(self, pattern, dest, options)
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Extract files matching a pattern to memory
|
|
240
|
+
# @param pattern [String, Regexp, Array] Pattern(s) to match
|
|
241
|
+
# @return [Hash<String, String>] Hash of filename => content
|
|
242
|
+
def extract_matching_to_memory(pattern)
|
|
243
|
+
Omnizip::Extraction.extract_to_memory_matching(self, pattern)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# List files matching a pattern
|
|
247
|
+
# @param pattern [String, Regexp, Array] Pattern(s) to match
|
|
248
|
+
# @return [Array<Entry>] Matching entries
|
|
249
|
+
def list_matching(pattern)
|
|
250
|
+
Omnizip::Extraction.list_matching(self, pattern)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Count files matching a pattern
|
|
254
|
+
# @param pattern [String, Regexp, Array] Pattern(s) to match
|
|
255
|
+
# @return [Integer] Number of matches
|
|
256
|
+
def count_matching(pattern)
|
|
257
|
+
Omnizip::Extraction.count_matching(self, pattern)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# Extract with a filter chain
|
|
261
|
+
# @param filter [Omnizip::Extraction::FilterChain] Filter chain
|
|
262
|
+
# @param dest [String] Destination directory
|
|
263
|
+
# @param options [Hash] Extraction options
|
|
264
|
+
# @return [Array<String>] Paths of extracted files
|
|
265
|
+
def extract_with_filter(filter, dest, options = {})
|
|
266
|
+
Omnizip::Extraction.extract_with_filter(self, filter, dest, options)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# Get archive metadata
|
|
270
|
+
# @return [Omnizip::Metadata::ArchiveMetadata] Archive metadata
|
|
271
|
+
def metadata
|
|
272
|
+
@metadata ||= Omnizip::Metadata::ArchiveMetadata.new(self)
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# Save metadata changes
|
|
276
|
+
# Marks the archive as modified so changes are written on close
|
|
277
|
+
def save_metadata
|
|
278
|
+
@modified = true
|
|
279
|
+
metadata.reset_modified
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# Commit changes to disk
|
|
283
|
+
def commit
|
|
284
|
+
write_archive if @modified
|
|
285
|
+
@modified = false
|
|
286
|
+
@reader = nil # Invalidate reader after writing
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# Close the archive
|
|
290
|
+
def close
|
|
291
|
+
commit if @modified
|
|
292
|
+
@reader = nil
|
|
293
|
+
@writer = nil
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
private
|
|
297
|
+
|
|
298
|
+
# Load existing archive
|
|
299
|
+
def load_archive
|
|
300
|
+
@reader = Omnizip::Formats::Zip::Reader.new(@name)
|
|
301
|
+
@reader.read
|
|
302
|
+
|
|
303
|
+
@entries = @reader.entries.map do |header|
|
|
304
|
+
Entry.new(header, filepath: @name)
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# Add file from filesystem path
|
|
309
|
+
def add_file_from_path(entry_name, src_path)
|
|
310
|
+
unless ::File.exist?(src_path)
|
|
311
|
+
raise Errno::ENOENT, "Source file not found: #{src_path}"
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
if ::File.directory?(src_path)
|
|
315
|
+
add_directory(entry_name)
|
|
316
|
+
else
|
|
317
|
+
data = ::File.binread(src_path)
|
|
318
|
+
stat = ::File.stat(src_path)
|
|
319
|
+
add_data(entry_name, data, stat: stat)
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
# Add data directly
|
|
324
|
+
def add_data(entry_name, data, stat: nil)
|
|
325
|
+
# Remove existing entry with same name
|
|
326
|
+
remove(entry_name)
|
|
327
|
+
|
|
328
|
+
# Create new header
|
|
329
|
+
header = create_header(entry_name, data, stat: stat)
|
|
330
|
+
entry = Entry.new(header, filepath: @name)
|
|
331
|
+
@entries << entry
|
|
332
|
+
|
|
333
|
+
# Invalidate reader cache since we modified entries
|
|
334
|
+
@reader = nil
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
# Add directory entry
|
|
338
|
+
def add_directory(entry_name)
|
|
339
|
+
entry_name = "#{entry_name}/" unless entry_name.end_with?("/")
|
|
340
|
+
header = create_header(entry_name, "", directory: true)
|
|
341
|
+
entry = Entry.new(header, filepath: @name)
|
|
342
|
+
@entries << entry
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
# Create a central directory header
|
|
346
|
+
def create_header(filename, data, stat: nil, directory: false)
|
|
347
|
+
now = Time.now
|
|
348
|
+
crc32 = if directory
|
|
349
|
+
0
|
|
350
|
+
else
|
|
351
|
+
Omnizip::Checksums::Crc32.new.tap do |c|
|
|
352
|
+
c.update(data)
|
|
353
|
+
end.value
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
external_attrs = if directory
|
|
357
|
+
Omnizip::Formats::Zip::Constants::UNIX_DIR_PERMISSIONS |
|
|
358
|
+
Omnizip::Formats::Zip::Constants::ATTR_DIRECTORY
|
|
359
|
+
elsif stat
|
|
360
|
+
(stat.mode & 0o777) << 16
|
|
361
|
+
else
|
|
362
|
+
Omnizip::Formats::Zip::Constants::UNIX_FILE_PERMISSIONS
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
Omnizip::Formats::Zip::CentralDirectoryHeader.new(
|
|
366
|
+
version_made_by: Omnizip::Formats::Zip::Constants::VERSION_MADE_BY_UNIX |
|
|
367
|
+
Omnizip::Formats::Zip::Constants::VERSION_DEFAULT,
|
|
368
|
+
version_needed: Omnizip::Formats::Zip::Constants::VERSION_DEFAULT,
|
|
369
|
+
flags: Omnizip::Formats::Zip::Constants::FLAG_UTF8,
|
|
370
|
+
compression_method: directory ? 0 : 8, # Store or Deflate
|
|
371
|
+
last_mod_time: dos_time(now),
|
|
372
|
+
last_mod_date: dos_date(now),
|
|
373
|
+
crc32: crc32,
|
|
374
|
+
compressed_size: 0, # Will be set during write
|
|
375
|
+
uncompressed_size: data.bytesize,
|
|
376
|
+
disk_number_start: 0,
|
|
377
|
+
internal_attributes: 0,
|
|
378
|
+
external_attributes: external_attrs,
|
|
379
|
+
local_header_offset: 0, # Will be set during write
|
|
380
|
+
filename: filename,
|
|
381
|
+
extra_field: "",
|
|
382
|
+
comment: "",
|
|
383
|
+
).tap do |header|
|
|
384
|
+
header.cached_original_data = data
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
# Read entry data from archive
|
|
389
|
+
def read_entry_data(entry)
|
|
390
|
+
return "" if entry.directory?
|
|
391
|
+
|
|
392
|
+
# Check if we have cached data (for new entries not yet written)
|
|
393
|
+
cached_data = entry.header.cached_original_data
|
|
394
|
+
return cached_data if cached_data
|
|
395
|
+
|
|
396
|
+
# Otherwise read from file
|
|
397
|
+
unless @reader
|
|
398
|
+
@reader = Omnizip::Formats::Zip::Reader.new(@name)
|
|
399
|
+
@reader.read
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
::File.open(@name, "rb") do |io|
|
|
403
|
+
# Find the entry in reader
|
|
404
|
+
reader_entry = @reader.entries.find { |e| e.filename == entry.name }
|
|
405
|
+
raise Errno::ENOENT, "Entry not found in archive: #{entry.name}" unless reader_entry
|
|
406
|
+
|
|
407
|
+
# Extract just the data
|
|
408
|
+
io.seek(reader_entry.local_header_offset, ::IO::SEEK_SET)
|
|
409
|
+
|
|
410
|
+
# Read and parse local file header
|
|
411
|
+
fixed_header = io.read(30)
|
|
412
|
+
return "" unless fixed_header && fixed_header.size == 30
|
|
413
|
+
|
|
414
|
+
_signature, _version, _flags, _method, _time, _date, _crc32,
|
|
415
|
+
_comp_size, _uncomp_size, filename_length, extra_length = fixed_header.unpack("VvvvvvVVVvv")
|
|
416
|
+
|
|
417
|
+
# Skip filename and extra field
|
|
418
|
+
io.read(filename_length + extra_length)
|
|
419
|
+
|
|
420
|
+
# Read compressed data
|
|
421
|
+
compressed_data = io.read(reader_entry.compressed_size)
|
|
422
|
+
return "" unless compressed_data
|
|
423
|
+
|
|
424
|
+
# Decompress
|
|
425
|
+
@reader.decompress(
|
|
426
|
+
compressed_data,
|
|
427
|
+
reader_entry.compression_method,
|
|
428
|
+
reader_entry.uncompressed_size,
|
|
429
|
+
)
|
|
430
|
+
end
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
# Extract entry to filesystem
|
|
434
|
+
def extract_entry_to_path(entry, dest_path)
|
|
435
|
+
if entry.directory?
|
|
436
|
+
FileUtils.mkdir_p(dest_path)
|
|
437
|
+
else
|
|
438
|
+
FileUtils.mkdir_p(::File.dirname(dest_path))
|
|
439
|
+
content = read_entry_data(entry)
|
|
440
|
+
::File.binwrite(dest_path, content)
|
|
441
|
+
|
|
442
|
+
# Set permissions if Unix
|
|
443
|
+
if entry.unix_perms.positive?
|
|
444
|
+
::File.chmod(entry.unix_perms & 0o777, dest_path)
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
# Write archive to disk
|
|
450
|
+
def write_archive
|
|
451
|
+
# Cache all entry data before writing (to avoid reading while writing)
|
|
452
|
+
entry_data = {}
|
|
453
|
+
entries.each do |entry|
|
|
454
|
+
next if entry.directory?
|
|
455
|
+
|
|
456
|
+
header = entry.header
|
|
457
|
+
cached = header.cached_original_data
|
|
458
|
+
entry_data[entry.name] = cached || read_entry_data(entry)
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
writer = Omnizip::Formats::Zip::Writer.new(@name)
|
|
462
|
+
|
|
463
|
+
entries.each do |entry|
|
|
464
|
+
if entry.directory?
|
|
465
|
+
writer.add_directory(entry.name)
|
|
466
|
+
else
|
|
467
|
+
writer.add_data(entry.name, entry_data[entry.name])
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
writer.write
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
# Convert Time to DOS time format
|
|
475
|
+
def dos_time(time)
|
|
476
|
+
((time.hour << 11) | (time.min << 5) | (time.sec / 2)) & 0xFFFF
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
# Convert Time to DOS date format
|
|
480
|
+
def dos_date(time)
|
|
481
|
+
(((time.year - 1980) << 9) | (time.month << 5) | time.day) & 0xFFFF
|
|
482
|
+
end
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
end
|