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,244 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Formats
|
|
5
|
+
module Msi
|
|
6
|
+
# MSI Table Parser
|
|
7
|
+
#
|
|
8
|
+
# Parses MSI database tables from OLE streams. MSI uses a column-major
|
|
9
|
+
# storage format where each column's data is stored contiguously.
|
|
10
|
+
#
|
|
11
|
+
# Key tables for file extraction:
|
|
12
|
+
# - File: File entries with name, size, component, sequence
|
|
13
|
+
# - Component: Links files to directories
|
|
14
|
+
# - Directory: Directory hierarchy
|
|
15
|
+
# - Media: Cabinet file references
|
|
16
|
+
class TableParser
|
|
17
|
+
include Omnizip::Formats::Msi::Constants
|
|
18
|
+
|
|
19
|
+
# @return [StringPool] String pool for string lookups
|
|
20
|
+
attr_reader :string_pool
|
|
21
|
+
|
|
22
|
+
# @return [Hash] Parsed tables (table_name => rows)
|
|
23
|
+
attr_reader :tables
|
|
24
|
+
|
|
25
|
+
# @return [Hash] Column definitions (table_name => columns)
|
|
26
|
+
attr_reader :columns
|
|
27
|
+
|
|
28
|
+
# @return [Array<String>] Table names
|
|
29
|
+
attr_reader :table_names
|
|
30
|
+
|
|
31
|
+
# @return [Proc] Stream reader method
|
|
32
|
+
attr_reader :read_stream
|
|
33
|
+
|
|
34
|
+
# Initialize table parser
|
|
35
|
+
#
|
|
36
|
+
# @param string_pool [StringPool] String pool for lookups
|
|
37
|
+
# @param stream_reader [Proc] Method to read streams
|
|
38
|
+
def initialize(string_pool, stream_reader)
|
|
39
|
+
@string_pool = string_pool
|
|
40
|
+
@read_stream = stream_reader
|
|
41
|
+
@tables = {}
|
|
42
|
+
@columns = {}
|
|
43
|
+
@table_names = []
|
|
44
|
+
load_table_list
|
|
45
|
+
load_column_defs
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Get table rows
|
|
49
|
+
#
|
|
50
|
+
# @param table_name [String] Table name
|
|
51
|
+
# @return [Array<Hash>] Table rows (each row is a hash of column => value)
|
|
52
|
+
def table(table_name)
|
|
53
|
+
return @tables[table_name] if @tables.key?(table_name)
|
|
54
|
+
|
|
55
|
+
@tables[table_name] = parse_table(table_name)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Get column definitions for table
|
|
59
|
+
#
|
|
60
|
+
# @param table_name [String] Table name
|
|
61
|
+
# @return [Array<Hash>] Column definitions
|
|
62
|
+
def column_defs(table_name)
|
|
63
|
+
@columns[table_name] || []
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Check if table exists
|
|
67
|
+
#
|
|
68
|
+
# @param table_name [String] Table name
|
|
69
|
+
# @return [Boolean]
|
|
70
|
+
def table_exists?(table_name)
|
|
71
|
+
@table_names.include?(table_name)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
# Load list of table names from _Tables stream
|
|
77
|
+
def load_table_list
|
|
78
|
+
data = @read_stream.call(TABLES_STREAM)
|
|
79
|
+
return if data.nil? || data.empty?
|
|
80
|
+
|
|
81
|
+
# _Tables format: column-major with one column (Table string index)
|
|
82
|
+
# First 2 bytes appear to be header (skip)
|
|
83
|
+
# Then 2-byte string indices for each table name
|
|
84
|
+
return if data.bytesize < 4
|
|
85
|
+
|
|
86
|
+
# Skip first 2 bytes (header), read string indices
|
|
87
|
+
offset = 2
|
|
88
|
+
while offset + 2 <= data.bytesize
|
|
89
|
+
str_idx = data[offset, 2].unpack1("v")
|
|
90
|
+
name = @string_pool[str_idx]
|
|
91
|
+
@table_names << name if name
|
|
92
|
+
offset += 2
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Load column definitions from _Columns stream
|
|
97
|
+
def load_column_defs
|
|
98
|
+
data = @read_stream.call(COLUMNS_STREAM)
|
|
99
|
+
return if data.nil? || data.empty?
|
|
100
|
+
|
|
101
|
+
# _Columns format: column-major with 4 columns
|
|
102
|
+
# Column 1: Table (string index, 2 bytes)
|
|
103
|
+
# Column 2: Number (signed short, 2 bytes)
|
|
104
|
+
# Column 3: Name (string index, 2 bytes)
|
|
105
|
+
# Column 4: Type (unsigned short, 2 bytes)
|
|
106
|
+
|
|
107
|
+
# Determine number of rows
|
|
108
|
+
num_rows = data.bytesize / 8 # 4 columns * 2 bytes each
|
|
109
|
+
|
|
110
|
+
# Extract each column (column-major order)
|
|
111
|
+
col_size = num_rows * 2
|
|
112
|
+
|
|
113
|
+
table_col = data[0, col_size].unpack("v*")
|
|
114
|
+
number_col = data[col_size, col_size].unpack("v*")
|
|
115
|
+
name_col = data[col_size * 2, col_size].unpack("v*")
|
|
116
|
+
type_col = data[col_size * 3, col_size].unpack("v*")
|
|
117
|
+
|
|
118
|
+
# Build column definitions per table
|
|
119
|
+
num_rows.times do |i|
|
|
120
|
+
table_name = @string_pool[table_col[i]]
|
|
121
|
+
next unless table_name
|
|
122
|
+
|
|
123
|
+
col_name = @string_pool[name_col[i]]
|
|
124
|
+
next unless col_name
|
|
125
|
+
|
|
126
|
+
# Number column: signed short with nullable bit
|
|
127
|
+
raw_num = number_col[i]
|
|
128
|
+
col_num = raw_num & 0x7FFF
|
|
129
|
+
is_primary_key = raw_num.anybits?(0x8000)
|
|
130
|
+
|
|
131
|
+
# Type column: determine storage width
|
|
132
|
+
type_val = type_col[i]
|
|
133
|
+
col_type = parse_column_type(type_val)
|
|
134
|
+
|
|
135
|
+
@columns[table_name] ||= []
|
|
136
|
+
@columns[table_name] << {
|
|
137
|
+
name: col_name,
|
|
138
|
+
number: col_num,
|
|
139
|
+
type: col_type[:type],
|
|
140
|
+
width: col_type[:width],
|
|
141
|
+
nullable: col_type[:nullable],
|
|
142
|
+
primary_key: is_primary_key,
|
|
143
|
+
}
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Sort columns by number for each table
|
|
147
|
+
@columns.each_value do |cols|
|
|
148
|
+
cols.sort_by! { |c| c[:number] }
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Parse column type from raw type value
|
|
153
|
+
#
|
|
154
|
+
# Type encoding:
|
|
155
|
+
# - Low byte: length or type code
|
|
156
|
+
# - High byte: type category with nullable bit
|
|
157
|
+
#
|
|
158
|
+
# @param raw [Integer] Raw type value
|
|
159
|
+
# @return [Hash] Parsed type info
|
|
160
|
+
def parse_column_type(raw)
|
|
161
|
+
low_byte = raw & 0xFF
|
|
162
|
+
high_byte = (raw >> 8) & 0xFF
|
|
163
|
+
nullable = high_byte.anybits?(0x80)
|
|
164
|
+
type_id = high_byte & 0x7F
|
|
165
|
+
|
|
166
|
+
# Determine type and width based on type_id
|
|
167
|
+
# Type 1 = int, Type >= 0x10 = string
|
|
168
|
+
if type_id == 1
|
|
169
|
+
# Integer type
|
|
170
|
+
if low_byte == 2
|
|
171
|
+
{ type: :i2, width: 2, nullable: nullable }
|
|
172
|
+
else
|
|
173
|
+
{ type: :i4, width: 4, nullable: nullable }
|
|
174
|
+
end
|
|
175
|
+
elsif type_id == 2
|
|
176
|
+
# Long integer
|
|
177
|
+
{ type: :i4, width: 4, nullable: nullable }
|
|
178
|
+
elsif type_id >= 0x10
|
|
179
|
+
# String type - width is always 2 (string pool index)
|
|
180
|
+
{ type: :string, width: 2, nullable: nullable }
|
|
181
|
+
else
|
|
182
|
+
# Default to string
|
|
183
|
+
{ type: :string, width: 2, nullable: nullable }
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Parse a table stream into rows
|
|
188
|
+
#
|
|
189
|
+
# @param table_name [String] Table name
|
|
190
|
+
# @return [Array<Hash>] Parsed rows
|
|
191
|
+
def parse_table(table_name)
|
|
192
|
+
rows = []
|
|
193
|
+
data = @read_stream.call(table_name)
|
|
194
|
+
return rows if data.nil? || data.empty?
|
|
195
|
+
|
|
196
|
+
column_defs = @columns[table_name]
|
|
197
|
+
return rows if column_defs.nil? || column_defs.empty?
|
|
198
|
+
|
|
199
|
+
# Calculate row count from data size and column widths
|
|
200
|
+
total_width = column_defs.sum { |c| c[:width] }
|
|
201
|
+
return rows if total_width.zero?
|
|
202
|
+
|
|
203
|
+
num_rows = data.bytesize / total_width
|
|
204
|
+
|
|
205
|
+
# Parse column by column (column-major order)
|
|
206
|
+
offset = 0
|
|
207
|
+
rows = Array.new(num_rows) { {} }
|
|
208
|
+
|
|
209
|
+
column_defs.each do |col|
|
|
210
|
+
num_rows.times do |row_idx|
|
|
211
|
+
value = read_column_value(data, offset, col)
|
|
212
|
+
rows[row_idx][col[:name]] = value
|
|
213
|
+
offset += col[:width]
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
rows
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Read a single column value from data
|
|
221
|
+
#
|
|
222
|
+
# @param data [String] Raw table data
|
|
223
|
+
# @param offset [Integer] Current offset
|
|
224
|
+
# @param col [Hash] Column definition
|
|
225
|
+
# @return [Object] Parsed value
|
|
226
|
+
def read_column_value(data, offset, col)
|
|
227
|
+
case col[:type]
|
|
228
|
+
when :string
|
|
229
|
+
str_idx = data[offset, 2]&.unpack1("v") || 0
|
|
230
|
+
@string_pool[str_idx]
|
|
231
|
+
when :i2
|
|
232
|
+
val = data[offset, 2]&.unpack1("v") || 0
|
|
233
|
+
# Handle nullable marker
|
|
234
|
+
col[:nullable] ? (val & 0x7FFF) : val
|
|
235
|
+
when :i4
|
|
236
|
+
val = data[offset, 4]&.unpack1("V") || 0
|
|
237
|
+
# Handle nullable marker (high bit)
|
|
238
|
+
col[:nullable] ? (val & 0x7FFFFFFF) : val
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Formats
|
|
5
|
+
# MSI (Microsoft Installer) format support
|
|
6
|
+
#
|
|
7
|
+
# Provides read access to MSI packages, extracting files from
|
|
8
|
+
# embedded or external cabinet archives.
|
|
9
|
+
#
|
|
10
|
+
# MSI files are OLE compound documents containing:
|
|
11
|
+
# - Database tables (File, Component, Directory, Media, etc.)
|
|
12
|
+
# - String pool for interned strings
|
|
13
|
+
# - Embedded cabinets (in _Streams or direct OLE streams)
|
|
14
|
+
module Msi
|
|
15
|
+
autoload :Constants, "omnizip/formats/msi/constants"
|
|
16
|
+
autoload :Entry, "omnizip/formats/msi/entry"
|
|
17
|
+
autoload :StringPool, "omnizip/formats/msi/string_pool"
|
|
18
|
+
autoload :TableParser, "omnizip/formats/msi/table_parser"
|
|
19
|
+
autoload :DirectoryResolver, "omnizip/formats/msi/directory_resolver"
|
|
20
|
+
autoload :CabExtractor, "omnizip/formats/msi/cab_extractor"
|
|
21
|
+
autoload :Reader, "omnizip/formats/msi/reader"
|
|
22
|
+
|
|
23
|
+
class << self
|
|
24
|
+
# Open MSI file and return reader
|
|
25
|
+
#
|
|
26
|
+
# @param path [String] Path to MSI file
|
|
27
|
+
# @yield [Reader] Reader instance
|
|
28
|
+
# @return [Reader]
|
|
29
|
+
def open(path)
|
|
30
|
+
reader = Reader.new(path)
|
|
31
|
+
reader.open
|
|
32
|
+
if block_given?
|
|
33
|
+
begin
|
|
34
|
+
yield reader
|
|
35
|
+
ensure
|
|
36
|
+
reader.close
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
reader
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# List files in MSI package
|
|
44
|
+
#
|
|
45
|
+
# @param path [String] Path to MSI file
|
|
46
|
+
# @return [Array<String>] File paths
|
|
47
|
+
def list(path)
|
|
48
|
+
open(path) { |r| r.files.map(&:path) }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Extract all files from MSI package
|
|
52
|
+
#
|
|
53
|
+
# @param path [String] Path to MSI file
|
|
54
|
+
# @param output_dir [String] Output directory
|
|
55
|
+
# @return [Array<String>] Extracted file paths
|
|
56
|
+
def extract(path, output_dir)
|
|
57
|
+
open(path) do |reader|
|
|
58
|
+
reader.extract(output_dir)
|
|
59
|
+
reader.files.map { |f| File.join(output_dir, f.path) }
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Get information about MSI package
|
|
64
|
+
#
|
|
65
|
+
# @param path [String] Path to MSI file
|
|
66
|
+
# @return [Hash] Package information
|
|
67
|
+
def info(path)
|
|
68
|
+
open(path, &:info)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "set"
|
|
4
|
+
|
|
5
|
+
module Omnizip
|
|
6
|
+
module Formats
|
|
7
|
+
module Ole
|
|
8
|
+
# OLE allocation table
|
|
9
|
+
#
|
|
10
|
+
# Manages block chains for files stored in OLE containers.
|
|
11
|
+
# There are two types: Big (BBAT) and Small (SBAT).
|
|
12
|
+
class AllocationTable
|
|
13
|
+
include Omnizip::Formats::Ole::Constants
|
|
14
|
+
|
|
15
|
+
# @return [Array<Integer>] Table entries
|
|
16
|
+
attr_reader :entries
|
|
17
|
+
|
|
18
|
+
# @return [Object] Parent OLE storage
|
|
19
|
+
attr_reader :ole
|
|
20
|
+
|
|
21
|
+
# @return [IO] Underlying IO
|
|
22
|
+
attr_reader :io
|
|
23
|
+
|
|
24
|
+
# @return [Integer] Block size in bytes
|
|
25
|
+
attr_reader :block_size
|
|
26
|
+
|
|
27
|
+
# Initialize allocation table
|
|
28
|
+
#
|
|
29
|
+
# @param ole [Object] Parent OLE storage
|
|
30
|
+
def initialize(ole)
|
|
31
|
+
@ole = ole
|
|
32
|
+
@entries = []
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Load allocation table from binary data
|
|
36
|
+
#
|
|
37
|
+
# @param data [String] Binary data containing table entries
|
|
38
|
+
def load(data)
|
|
39
|
+
@entries = data.unpack("V*")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Get entry at index
|
|
43
|
+
#
|
|
44
|
+
# @param idx [Integer] Entry index
|
|
45
|
+
# @return [Integer] Entry value
|
|
46
|
+
def [](idx)
|
|
47
|
+
@entries[idx]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Set entry at index
|
|
51
|
+
#
|
|
52
|
+
# @param idx [Integer] Entry index
|
|
53
|
+
# @param val [Integer] Entry value
|
|
54
|
+
def []=(idx, val)
|
|
55
|
+
@entries[idx] = val
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Get number of entries
|
|
59
|
+
#
|
|
60
|
+
# @return [Integer] Entry count
|
|
61
|
+
def length
|
|
62
|
+
@entries.length
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Free resources to prevent memory leaks
|
|
66
|
+
#
|
|
67
|
+
# Call this when done with the allocation table to release memory.
|
|
68
|
+
# @return [void]
|
|
69
|
+
def free
|
|
70
|
+
@entries = nil
|
|
71
|
+
@ole = nil
|
|
72
|
+
@io = nil
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Follow chain from starting index
|
|
76
|
+
#
|
|
77
|
+
# @param idx [Integer] Starting block index
|
|
78
|
+
# @return [Array<Integer>] Chain of block indices
|
|
79
|
+
# @raise [ArgumentError] If chain is broken
|
|
80
|
+
def chain(idx)
|
|
81
|
+
result = []
|
|
82
|
+
visited = Set.new
|
|
83
|
+
|
|
84
|
+
until idx >= META_BAT
|
|
85
|
+
if idx.negative? || idx > length
|
|
86
|
+
raise ArgumentError, "Broken allocation chain at index #{idx}"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
if visited.include?(idx)
|
|
90
|
+
raise ArgumentError, "Circular chain detected at index #{idx}"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
visited << idx
|
|
94
|
+
result << idx
|
|
95
|
+
idx = @entries[idx]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
result
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Convert block chain to byte ranges
|
|
102
|
+
#
|
|
103
|
+
# @param blocks [Array<Integer>] Block indices
|
|
104
|
+
# @param size [Integer, nil] Optional size to truncate to
|
|
105
|
+
# @return [Array<Array<Integer, Integer>>] Array of [offset, length] pairs
|
|
106
|
+
def blocks_to_ranges(blocks, size = nil)
|
|
107
|
+
return [] if blocks.empty?
|
|
108
|
+
|
|
109
|
+
# Truncate chain if size specified
|
|
110
|
+
blocks = blocks[0, (size.to_f / block_size).ceil] if size
|
|
111
|
+
|
|
112
|
+
# Convert to ranges
|
|
113
|
+
ranges = blocks.map { |i| [block_size * i, block_size] }
|
|
114
|
+
|
|
115
|
+
# Truncate final range if needed
|
|
116
|
+
if ranges.last && size
|
|
117
|
+
ranges.last[1] -= ((ranges.length * block_size) - size)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
ranges
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Get ranges for a chain
|
|
124
|
+
#
|
|
125
|
+
# @param chain_or_idx [Array<Integer>, Integer] Block chain or head index
|
|
126
|
+
# @param size [Integer, nil] Optional size
|
|
127
|
+
# @return [Array<Array<Integer, Integer>>] Byte ranges
|
|
128
|
+
def ranges(chain_or_idx, size = nil)
|
|
129
|
+
blocks = chain_or_idx.is_a?(Array) ? chain_or_idx : chain(chain_or_idx)
|
|
130
|
+
blocks_to_ranges(blocks, size)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Read data from block chain
|
|
134
|
+
#
|
|
135
|
+
# @param chain_or_idx [Array<Integer>, Integer] Block chain or head index
|
|
136
|
+
# @param size [Integer, nil] Optional size
|
|
137
|
+
# @return [String] Data from chain
|
|
138
|
+
def read(chain_or_idx, size = nil)
|
|
139
|
+
ranges = self.ranges(chain_or_idx, size)
|
|
140
|
+
data = "".b
|
|
141
|
+
|
|
142
|
+
ranges.each do |offset, len|
|
|
143
|
+
@io.seek(offset)
|
|
144
|
+
data << @io.read(len).to_s
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
data
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Find a free block
|
|
151
|
+
#
|
|
152
|
+
# @return [Integer] Free block index
|
|
153
|
+
def free_block
|
|
154
|
+
idx = @entries.index(AVAIL)
|
|
155
|
+
return idx if idx
|
|
156
|
+
|
|
157
|
+
@entries << AVAIL
|
|
158
|
+
@entries.length - 1
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Resize a block chain
|
|
162
|
+
#
|
|
163
|
+
# @param blocks [Array<Integer>] Current blocks (modified in place)
|
|
164
|
+
# @param size [Integer] New size in bytes
|
|
165
|
+
# @return [Array<Integer>] Updated blocks
|
|
166
|
+
def resize_chain(blocks, size)
|
|
167
|
+
new_num_blocks = (size / block_size.to_f).ceil
|
|
168
|
+
old_num_blocks = blocks.length
|
|
169
|
+
|
|
170
|
+
if new_num_blocks < old_num_blocks
|
|
171
|
+
# De-allocate excess blocks
|
|
172
|
+
(new_num_blocks...old_num_blocks).each do |i|
|
|
173
|
+
@entries[blocks[i]] = AVAIL
|
|
174
|
+
end
|
|
175
|
+
if new_num_blocks.positive?
|
|
176
|
+
@entries[blocks[new_num_blocks - 1]] =
|
|
177
|
+
EOC
|
|
178
|
+
end
|
|
179
|
+
blocks.slice!(new_num_blocks..-1)
|
|
180
|
+
elsif new_num_blocks > old_num_blocks
|
|
181
|
+
# Allocate more blocks
|
|
182
|
+
last_block = blocks.last
|
|
183
|
+
(new_num_blocks - old_num_blocks).times do
|
|
184
|
+
block = free_block
|
|
185
|
+
@entries[last_block] = block if last_block
|
|
186
|
+
blocks << block
|
|
187
|
+
last_block = block
|
|
188
|
+
@entries[last_block] = EOC
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
blocks
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Truncate table to remove trailing AVAIL entries
|
|
196
|
+
#
|
|
197
|
+
# @return [Array<Integer>] Truncated entries
|
|
198
|
+
def truncate
|
|
199
|
+
temp = @entries.reverse
|
|
200
|
+
first_non_avail = temp.find { |b| b != AVAIL }
|
|
201
|
+
temp = temp[temp.index(first_non_avail)..] if first_non_avail
|
|
202
|
+
temp.reverse
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Truncate entries in place
|
|
206
|
+
def truncate_entries
|
|
207
|
+
@entries.replace(truncate)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Pack table to binary data
|
|
211
|
+
#
|
|
212
|
+
# @return [String] Binary data
|
|
213
|
+
def pack
|
|
214
|
+
table = truncate
|
|
215
|
+
|
|
216
|
+
# Pad to block boundary
|
|
217
|
+
num = @ole.bbat.block_size / 4
|
|
218
|
+
if (table.length % num) != 0
|
|
219
|
+
table += [AVAIL] * (num - (table.length % num))
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
table.pack("V*")
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Big allocation table (BBAT)
|
|
226
|
+
#
|
|
227
|
+
# Manages large blocks (typically 512 bytes) for files >= 4096 bytes.
|
|
228
|
+
class Big < AllocationTable
|
|
229
|
+
def initialize(ole)
|
|
230
|
+
super
|
|
231
|
+
@block_size = 1 << @ole.header.b_shift
|
|
232
|
+
@io = @ole.io
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# Big blocks are -1 based to avoid clashing with header
|
|
236
|
+
#
|
|
237
|
+
# @param blocks [Array<Integer>] Block indices
|
|
238
|
+
# @param size [Integer, nil] Optional size
|
|
239
|
+
# @return [Array<Array<Integer, Integer>>] Byte ranges
|
|
240
|
+
def blocks_to_ranges(blocks, size = nil)
|
|
241
|
+
return [] if blocks.empty?
|
|
242
|
+
|
|
243
|
+
blocks = blocks[0, (size.to_f / block_size).ceil] if size
|
|
244
|
+
ranges = blocks.map { |i| [block_size * (i + 1), block_size] }
|
|
245
|
+
ranges.last[1] -= ((ranges.length * block_size) - size) if ranges.last && size
|
|
246
|
+
ranges
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Small allocation table (SBAT)
|
|
251
|
+
#
|
|
252
|
+
# Manages small blocks (typically 64 bytes) for files < 4096 bytes.
|
|
253
|
+
class Small < AllocationTable
|
|
254
|
+
def initialize(ole)
|
|
255
|
+
super
|
|
256
|
+
@block_size = 1 << @ole.header.s_shift
|
|
257
|
+
@io = @ole.sb_file
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module Formats
|
|
5
|
+
module Ole
|
|
6
|
+
# OLE format constants
|
|
7
|
+
#
|
|
8
|
+
# Constants for the OLE compound document format including
|
|
9
|
+
# magic bytes, special markers, and format-related values.
|
|
10
|
+
module Constants
|
|
11
|
+
# OLE magic signature (D0CF11E0A1B11AE1)
|
|
12
|
+
MAGIC = "\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1".b
|
|
13
|
+
|
|
14
|
+
# Header size in bytes
|
|
15
|
+
HEADER_SIZE = 76
|
|
16
|
+
|
|
17
|
+
# Header block size (always 512)
|
|
18
|
+
HEADER_BLOCK_SIZE = 512
|
|
19
|
+
|
|
20
|
+
# Allocation table special markers
|
|
21
|
+
AVAIL = 0xffffffff # Free block
|
|
22
|
+
EOC = 0xfffffffe # End of chain
|
|
23
|
+
BAT = 0xfffffffd # Block stores BAT data
|
|
24
|
+
META_BAT = 0xfffffffc # Block stores Meta BAT
|
|
25
|
+
|
|
26
|
+
# End of tree marker for dirents
|
|
27
|
+
EOT = 0xffffffff
|
|
28
|
+
|
|
29
|
+
# Default threshold for small block vs big block (4096 bytes)
|
|
30
|
+
DEFAULT_THRESHOLD = 4096
|
|
31
|
+
|
|
32
|
+
# Byte order marker for little-endian
|
|
33
|
+
BYTE_ORDER_LE = "\xfe\xff".b
|
|
34
|
+
|
|
35
|
+
# Default block sizes
|
|
36
|
+
DEFAULT_BIG_BLOCK_SHIFT = 9 # 512 bytes
|
|
37
|
+
DEFAULT_SMALL_BLOCK_SHIFT = 6 # 64 bytes
|
|
38
|
+
|
|
39
|
+
# Dirent types
|
|
40
|
+
DIRENT_TYPES = {
|
|
41
|
+
0 => :empty,
|
|
42
|
+
1 => :dir,
|
|
43
|
+
2 => :file,
|
|
44
|
+
5 => :root,
|
|
45
|
+
}.freeze
|
|
46
|
+
|
|
47
|
+
# Dirent colors for red-black tree
|
|
48
|
+
DIRENT_COLORS = {
|
|
49
|
+
0 => :red,
|
|
50
|
+
1 => :black,
|
|
51
|
+
}.freeze
|
|
52
|
+
|
|
53
|
+
# Dirent size in bytes
|
|
54
|
+
DIRENT_SIZE = 128
|
|
55
|
+
|
|
56
|
+
# Maximum name length in UTF-16 characters (including null terminator)
|
|
57
|
+
MAX_NAME_LENGTH = 32
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|