omnizip 0.4.7-aarch64-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.
Files changed (632) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +32 -0
  4. data/.rubocop_todo.yml +293 -0
  5. data/CHANGELOG.md +1647 -0
  6. data/CONTEXT.md +68 -0
  7. data/COPYING +502 -0
  8. data/Gemfile +19 -0
  9. data/LICENSE +12 -0
  10. data/README.adoc +1327 -0
  11. data/Rakefile +15 -0
  12. data/TODO.refactor/00-overview.md +67 -0
  13. data/TODO.refactor/01-registry-base-class.md +81 -0
  14. data/TODO.refactor/02-error-hierarchy.md +57 -0
  15. data/TODO.refactor/03-autoload-entry-point.md +69 -0
  16. data/TODO.refactor/04-filter-base-consolidation.md +49 -0
  17. data/TODO.refactor/05-send-private-methods.md +64 -0
  18. data/TODO.refactor/06-instance-variable-access.md +69 -0
  19. data/TODO.refactor/07-respond-to-replacement.md +237 -0
  20. data/TODO.refactor/08-spec-doubles.md +27 -0
  21. data/TODO.refactor/09-cli-shared-module.md +35 -0
  22. data/TODO.refactor/10-format-detector-ocp.md +34 -0
  23. data/TODO.refactor/11-convenience-decoupling.md +38 -0
  24. data/TODO.refactor/12-thread-safety.md +8 -0
  25. data/TODO.refactor/13-lutaml-model-migration.md +158 -0
  26. data/TODO.refactor/14-add-missing-specs.md +25 -0
  27. data/benchmark/README.md +260 -0
  28. data/benchmark/benchmark_suite.rb +125 -0
  29. data/benchmark/compression_bench.rb +181 -0
  30. data/benchmark/filter_bench.rb +180 -0
  31. data/benchmark/models/benchmark_result.rb +59 -0
  32. data/benchmark/models/comparison_result.rb +69 -0
  33. data/benchmark/profile_suite.rb +167 -0
  34. data/benchmark/reporter.rb +150 -0
  35. data/benchmark/run_benchmarks.rb +66 -0
  36. data/benchmark/test_data.rb +137 -0
  37. data/config/formats/rar3_spec.yml +92 -0
  38. data/config/formats/rar5_spec.yml +102 -0
  39. data/docs/.github/workflows/docs.yml +142 -0
  40. data/docs/.gitignore +21 -0
  41. data/docs/.lychee.toml +67 -0
  42. data/docs/Gemfile +13 -0
  43. data/docs/RAR_WRITE_SUPPORT.md +26 -0
  44. data/docs/README.md +101 -0
  45. data/docs/_config.yml +112 -0
  46. data/docs/assets/logo.svg +1 -0
  47. data/docs/assets/omnizip-logo.pdf +1540 -11
  48. data/docs/comparison/feature-matrix.adoc +694 -0
  49. data/docs/comparison/index.adoc +113 -0
  50. data/docs/comparison/vs-7zip.adoc +309 -0
  51. data/docs/comparison/vs-peazip.adoc +77 -0
  52. data/docs/comparison/vs-rubyzip.adoc +342 -0
  53. data/docs/comparison/vs-winrar.adoc +100 -0
  54. data/docs/compatibility.adoc +579 -0
  55. data/docs/concepts/index.adoc +129 -0
  56. data/docs/developer/architecture.adoc +256 -0
  57. data/docs/developer/contributing.adoc +158 -0
  58. data/docs/developer/index.adoc +25 -0
  59. data/docs/developer/testing.adoc +212 -0
  60. data/docs/getting-started/basic-usage.adoc +263 -0
  61. data/docs/getting-started/index.adoc +42 -0
  62. data/docs/getting-started/installation.adoc +138 -0
  63. data/docs/getting-started/quick-start.adoc +183 -0
  64. data/docs/getting-started/your-first-archive.adoc +219 -0
  65. data/docs/guides/advanced-features/encryption.adoc +277 -0
  66. data/docs/guides/advanced-features/index.adoc +59 -0
  67. data/docs/guides/advanced-features/parallel-processing.adoc +144 -0
  68. data/docs/guides/advanced-features/progress-tracking.adoc +124 -0
  69. data/docs/guides/advanced-features/streaming.adoc +142 -0
  70. data/docs/guides/archive-formats/gzip-format.adoc +105 -0
  71. data/docs/guides/archive-formats/index.adoc +160 -0
  72. data/docs/guides/archive-formats/ole-format.adoc +151 -0
  73. data/docs/guides/archive-formats/rar-format.adoc +104 -0
  74. data/docs/guides/archive-formats/rar5.adoc +521 -0
  75. data/docs/guides/archive-formats/rpm-format.adoc +108 -0
  76. data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
  77. data/docs/guides/archive-formats/tar-format.adoc +106 -0
  78. data/docs/guides/archive-formats/xz-format.adoc +118 -0
  79. data/docs/guides/archive-formats/zip-format.adoc +35 -0
  80. data/docs/guides/compression-algorithms/bzip2.adoc +114 -0
  81. data/docs/guides/compression-algorithms/deflate.adoc +313 -0
  82. data/docs/guides/compression-algorithms/index.adoc +190 -0
  83. data/docs/guides/compression-algorithms/lzma.adoc +394 -0
  84. data/docs/guides/compression-algorithms/lzma2.adoc +244 -0
  85. data/docs/guides/compression-algorithms/ppmd.adoc +313 -0
  86. data/docs/guides/compression-algorithms/zstandard.adoc +296 -0
  87. data/docs/guides/creating-archives.adoc +348 -0
  88. data/docs/guides/extracting-archives.adoc +53 -0
  89. data/docs/guides/format-conversion.adoc +64 -0
  90. data/docs/guides/index.adoc +49 -0
  91. data/docs/guides/migration-rubyzip.adoc +217 -0
  92. data/docs/guides/parity-archives.adoc +605 -0
  93. data/docs/guides/performance-tuning.adoc +88 -0
  94. data/docs/index.adoc +228 -0
  95. data/docs/lychee.toml +67 -0
  96. data/docs/reference/api/overview.adoc +187 -0
  97. data/docs/reference/cli/compress-command.adoc +114 -0
  98. data/docs/reference/cli/overview.adoc +140 -0
  99. data/docs/reference/index.adoc +26 -0
  100. data/docs/resources/faq.adoc +185 -0
  101. data/docs/resources/quick-reference.adoc +222 -0
  102. data/docs/rust-backend.md +0 -0
  103. data/docs/troubleshooting/index.adoc +207 -0
  104. data/docs/xar_format.md +216 -0
  105. data/examples/api_comparison.rb +205 -0
  106. data/examples/deflate64_example.rb +96 -0
  107. data/examples/par2_demo.rb +121 -0
  108. data/examples/quick_start_native.rb +150 -0
  109. data/examples/quick_start_rubyzip.rb +115 -0
  110. data/examples/rubyzip_compatibility_demo.rb +194 -0
  111. data/exe/omnizip +27 -0
  112. data/lib/omnizip/algorithm.rb +176 -0
  113. data/lib/omnizip/algorithm_registry.rb +65 -0
  114. data/lib/omnizip/algorithms/.keep +0 -0
  115. data/lib/omnizip/algorithms/bzip2/bwt.rb +236 -0
  116. data/lib/omnizip/algorithms/bzip2/bz2.rb +687 -0
  117. data/lib/omnizip/algorithms/bzip2/rle.rb +146 -0
  118. data/lib/omnizip/algorithms/bzip2.rb +108 -0
  119. data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
  120. data/lib/omnizip/algorithms/deflate/decoder.rb +37 -0
  121. data/lib/omnizip/algorithms/deflate/encoder.rb +45 -0
  122. data/lib/omnizip/algorithms/deflate.rb +135 -0
  123. data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
  124. data/lib/omnizip/algorithms/deflate64/decoder.rb +151 -0
  125. data/lib/omnizip/algorithms/deflate64/encoder.rb +95 -0
  126. data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +352 -0
  127. data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +140 -0
  128. data/lib/omnizip/algorithms/deflate64.rb +118 -0
  129. data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
  130. data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
  131. data/lib/omnizip/algorithms/lzma/decoder.rb +146 -0
  132. data/lib/omnizip/algorithms/lzma/dictionary.rb +70 -0
  133. data/lib/omnizip/algorithms/lzma/distance_coder.rb +326 -0
  134. data/lib/omnizip/algorithms/lzma/encoder.rb +139 -0
  135. data/lib/omnizip/algorithms/lzma/length_coder.rb +172 -0
  136. data/lib/omnizip/algorithms/lzma/literal_decoder.rb +204 -0
  137. data/lib/omnizip/algorithms/lzma/literal_encoder.rb +208 -0
  138. data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +368 -0
  139. data/lib/omnizip/algorithms/lzma/lzma1_encoder.rb +105 -0
  140. data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +194 -0
  141. data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
  142. data/lib/omnizip/algorithms/lzma/match.rb +32 -0
  143. data/lib/omnizip/algorithms/lzma/match_finder.rb +233 -0
  144. data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
  145. data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +84 -0
  146. data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +159 -0
  147. data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
  148. data/lib/omnizip/algorithms/lzma/range_coder.rb +82 -0
  149. data/lib/omnizip/algorithms/lzma/range_decoder.rb +274 -0
  150. data/lib/omnizip/algorithms/lzma/range_encoder.rb +202 -0
  151. data/lib/omnizip/algorithms/lzma/state.rb +127 -0
  152. data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +323 -0
  153. data/lib/omnizip/algorithms/lzma/xz_encoder.rb +420 -0
  154. data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +640 -0
  155. data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +224 -0
  156. data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +167 -0
  157. data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +258 -0
  158. data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
  159. data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +314 -0
  160. data/lib/omnizip/algorithms/lzma/xz_state.rb +108 -0
  161. data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +1311 -0
  162. data/lib/omnizip/algorithms/lzma.rb +266 -0
  163. data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +180 -0
  164. data/lib/omnizip/algorithms/lzma2/constants.rb +38 -0
  165. data/lib/omnizip/algorithms/lzma2/encoder.rb +145 -0
  166. data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +165 -0
  167. data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
  168. data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +122 -0
  169. data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
  170. data/lib/omnizip/algorithms/lzma2.rb +133 -0
  171. data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
  172. data/lib/omnizip/algorithms/ppmd7/context.rb +151 -0
  173. data/lib/omnizip/algorithms/ppmd7/decoder.rb +127 -0
  174. data/lib/omnizip/algorithms/ppmd7/encoder.rb +153 -0
  175. data/lib/omnizip/algorithms/ppmd7/model.rb +245 -0
  176. data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
  177. data/lib/omnizip/algorithms/ppmd7.rb +146 -0
  178. data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
  179. data/lib/omnizip/algorithms/ppmd8/context.rb +32 -0
  180. data/lib/omnizip/algorithms/ppmd8/decoder.rb +104 -0
  181. data/lib/omnizip/algorithms/ppmd8/encoder.rb +135 -0
  182. data/lib/omnizip/algorithms/ppmd8/model.rb +246 -0
  183. data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
  184. data/lib/omnizip/algorithms/ppmd8.rb +122 -0
  185. data/lib/omnizip/algorithms/ppmd_base.rb +142 -0
  186. data/lib/omnizip/algorithms/registration.rb +28 -0
  187. data/lib/omnizip/algorithms/zstandard/constants.rb +158 -0
  188. data/lib/omnizip/algorithms/zstandard/decoder.rb +249 -0
  189. data/lib/omnizip/algorithms/zstandard/dictionary.rb +73 -0
  190. data/lib/omnizip/algorithms/zstandard/encoder.rb +294 -0
  191. data/lib/omnizip/algorithms/zstandard/frame/block.rb +143 -0
  192. data/lib/omnizip/algorithms/zstandard/frame/header.rb +233 -0
  193. data/lib/omnizip/algorithms/zstandard/frame.rb +33 -0
  194. data/lib/omnizip/algorithms/zstandard/fse/bitstream.rb +183 -0
  195. data/lib/omnizip/algorithms/zstandard/fse/encoder.rb +534 -0
  196. data/lib/omnizip/algorithms/zstandard/fse/interleaved.rb +92 -0
  197. data/lib/omnizip/algorithms/zstandard/fse/table.rb +188 -0
  198. data/lib/omnizip/algorithms/zstandard/fse/table_description.rb +203 -0
  199. data/lib/omnizip/algorithms/zstandard/fse.rb +53 -0
  200. data/lib/omnizip/algorithms/zstandard/huffman.rb +276 -0
  201. data/lib/omnizip/algorithms/zstandard/huffman_encoder.rb +327 -0
  202. data/lib/omnizip/algorithms/zstandard/ldm.rb +121 -0
  203. data/lib/omnizip/algorithms/zstandard/literals.rb +241 -0
  204. data/lib/omnizip/algorithms/zstandard/literals_encoder.rb +96 -0
  205. data/lib/omnizip/algorithms/zstandard/match_finder.rb +483 -0
  206. data/lib/omnizip/algorithms/zstandard/sequences.rb +350 -0
  207. data/lib/omnizip/algorithms/zstandard/sequences_encoder.rb +333 -0
  208. data/lib/omnizip/algorithms/zstandard/xxhash.rb +159 -0
  209. data/lib/omnizip/algorithms/zstandard.rb +210 -0
  210. data/lib/omnizip/algorithms.rb +35 -0
  211. data/lib/omnizip/archive/builder.rb +48 -0
  212. data/lib/omnizip/archive/reader_session.rb +67 -0
  213. data/lib/omnizip/archive.rb +86 -0
  214. data/lib/omnizip/archive_handler.rb +82 -0
  215. data/lib/omnizip/archive_handlers/cpio_handler.rb +47 -0
  216. data/lib/omnizip/archive_handlers/iso_handler.rb +54 -0
  217. data/lib/omnizip/archive_handlers/ole_handler.rb +37 -0
  218. data/lib/omnizip/archive_handlers/rar_handler.rb +96 -0
  219. data/lib/omnizip/archive_handlers/rpm_handler.rb +45 -0
  220. data/lib/omnizip/archive_handlers/seven_zip_handler.rb +89 -0
  221. data/lib/omnizip/archive_handlers/tar_handler.rb +75 -0
  222. data/lib/omnizip/archive_handlers/xar_handler.rb +49 -0
  223. data/lib/omnizip/archive_handlers/zip_handler.rb +115 -0
  224. data/lib/omnizip/archive_handlers.rb +18 -0
  225. data/lib/omnizip/backends.rb +160 -0
  226. data/lib/omnizip/buffer/memory_archive.rb +246 -0
  227. data/lib/omnizip/buffer/memory_extractor.rb +234 -0
  228. data/lib/omnizip/buffer/seven_zip_bridge.rb +171 -0
  229. data/lib/omnizip/buffer.rb +187 -0
  230. data/lib/omnizip/checksum_registry.rb +41 -0
  231. data/lib/omnizip/checksums/crc32.rb +101 -0
  232. data/lib/omnizip/checksums/crc64.rb +102 -0
  233. data/lib/omnizip/checksums/crc_base.rb +158 -0
  234. data/lib/omnizip/checksums/registration.rb +16 -0
  235. data/lib/omnizip/checksums/verifier.rb +130 -0
  236. data/lib/omnizip/checksums.rb +11 -0
  237. data/lib/omnizip/chunked/memory_manager.rb +194 -0
  238. data/lib/omnizip/chunked/reader.rb +78 -0
  239. data/lib/omnizip/chunked/writer.rb +123 -0
  240. data/lib/omnizip/chunked.rb +123 -0
  241. data/lib/omnizip/cli/output_formatter.rb +112 -0
  242. data/lib/omnizip/cli.rb +604 -0
  243. data/lib/omnizip/commands/.keep +0 -0
  244. data/lib/omnizip/commands/archive_create_command.rb +245 -0
  245. data/lib/omnizip/commands/archive_extract_command.rb +231 -0
  246. data/lib/omnizip/commands/archive_list_command.rb +204 -0
  247. data/lib/omnizip/commands/archive_repair_command.rb +129 -0
  248. data/lib/omnizip/commands/archive_verify_command.rb +115 -0
  249. data/lib/omnizip/commands/compress_command.rb +115 -0
  250. data/lib/omnizip/commands/decompress_command.rb +149 -0
  251. data/lib/omnizip/commands/list_command.rb +51 -0
  252. data/lib/omnizip/commands/metadata_command.rb +215 -0
  253. data/lib/omnizip/commands/parity_create_command.rb +114 -0
  254. data/lib/omnizip/commands/parity_repair_command.rb +120 -0
  255. data/lib/omnizip/commands/parity_verify_command.rb +122 -0
  256. data/lib/omnizip/commands/profile_list_command.rb +54 -0
  257. data/lib/omnizip/commands/profile_show_command.rb +44 -0
  258. data/lib/omnizip/commands.rb +21 -0
  259. data/lib/omnizip/convenience.rb +389 -0
  260. data/lib/omnizip/converter/conversion_registry.rb +50 -0
  261. data/lib/omnizip/converter/conversion_strategy.rb +108 -0
  262. data/lib/omnizip/converter/extract_repack_strategy.rb +51 -0
  263. data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +43 -0
  264. data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +54 -0
  265. data/lib/omnizip/converter.rb +124 -0
  266. data/lib/omnizip/crypto/aes256/cipher.rb +104 -0
  267. data/lib/omnizip/crypto/aes256/constants.rb +28 -0
  268. data/lib/omnizip/crypto/aes256/key_derivation.rb +100 -0
  269. data/lib/omnizip/crypto/aes256.rb +102 -0
  270. data/lib/omnizip/crypto.rb +11 -0
  271. data/lib/omnizip/entry.rb +44 -0
  272. data/lib/omnizip/error.rb +110 -0
  273. data/lib/omnizip/eta/exponential_smoothing_estimator.rb +95 -0
  274. data/lib/omnizip/eta/moving_average_estimator.rb +96 -0
  275. data/lib/omnizip/eta/rate_calculator.rb +104 -0
  276. data/lib/omnizip/eta/sample_history.rb +143 -0
  277. data/lib/omnizip/eta/time_estimator.rb +106 -0
  278. data/lib/omnizip/eta.rb +68 -0
  279. data/lib/omnizip/extraction/filter_chain.rb +179 -0
  280. data/lib/omnizip/extraction/glob_pattern.rb +140 -0
  281. data/lib/omnizip/extraction/pattern_matcher.rb +66 -0
  282. data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
  283. data/lib/omnizip/extraction/regex_pattern.rb +50 -0
  284. data/lib/omnizip/extraction/selective_extractor.rb +247 -0
  285. data/lib/omnizip/extraction.rb +115 -0
  286. data/lib/omnizip/file_type/mime_classifier.rb +144 -0
  287. data/lib/omnizip/file_type.rb +117 -0
  288. data/lib/omnizip/filter.rb +141 -0
  289. data/lib/omnizip/filter_pipeline.rb +108 -0
  290. data/lib/omnizip/filter_registry.rb +113 -0
  291. data/lib/omnizip/filters/bcj.rb +277 -0
  292. data/lib/omnizip/filters/bcj2/constants.rb +53 -0
  293. data/lib/omnizip/filters/bcj2/decoder.rb +263 -0
  294. data/lib/omnizip/filters/bcj2/encoder.rb +58 -0
  295. data/lib/omnizip/filters/bcj2/stream_data.rb +91 -0
  296. data/lib/omnizip/filters/bcj2.rb +93 -0
  297. data/lib/omnizip/filters/bcj_arm.rb +174 -0
  298. data/lib/omnizip/filters/bcj_arm64.rb +242 -0
  299. data/lib/omnizip/filters/bcj_ia64.rb +194 -0
  300. data/lib/omnizip/filters/bcj_ppc.rb +188 -0
  301. data/lib/omnizip/filters/bcj_sparc.rb +174 -0
  302. data/lib/omnizip/filters/bcj_x86.rb +191 -0
  303. data/lib/omnizip/filters/delta.rb +195 -0
  304. data/lib/omnizip/filters/xz_delta.rb +258 -0
  305. data/lib/omnizip/filters.rb +20 -0
  306. data/lib/omnizip/format_detector.rb +166 -0
  307. data/lib/omnizip/formats/.keep +0 -0
  308. data/lib/omnizip/formats/bzip2_file.rb +159 -0
  309. data/lib/omnizip/formats/cpio/bounded_io.rb +66 -0
  310. data/lib/omnizip/formats/cpio/constants.rb +55 -0
  311. data/lib/omnizip/formats/cpio/entry.rb +389 -0
  312. data/lib/omnizip/formats/cpio/reader.rb +194 -0
  313. data/lib/omnizip/formats/cpio/writer.rb +232 -0
  314. data/lib/omnizip/formats/cpio.rb +132 -0
  315. data/lib/omnizip/formats/format_spec_loader.rb +228 -0
  316. data/lib/omnizip/formats/gzip.rb +236 -0
  317. data/lib/omnizip/formats/iso/directory_builder.rb +321 -0
  318. data/lib/omnizip/formats/iso/directory_record.rb +162 -0
  319. data/lib/omnizip/formats/iso/joliet.rb +204 -0
  320. data/lib/omnizip/formats/iso/path_table.rb +125 -0
  321. data/lib/omnizip/formats/iso/reader.rb +194 -0
  322. data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
  323. data/lib/omnizip/formats/iso/volume_builder.rb +319 -0
  324. data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
  325. data/lib/omnizip/formats/iso/writer.rb +543 -0
  326. data/lib/omnizip/formats/iso.rb +133 -0
  327. data/lib/omnizip/formats/lzip.rb +161 -0
  328. data/lib/omnizip/formats/lzma_alone.rb +149 -0
  329. data/lib/omnizip/formats/msi/cab_extractor.rb +181 -0
  330. data/lib/omnizip/formats/msi/constants.rb +157 -0
  331. data/lib/omnizip/formats/msi/directory_resolver.rb +188 -0
  332. data/lib/omnizip/formats/msi/entry.rb +134 -0
  333. data/lib/omnizip/formats/msi/reader.rb +301 -0
  334. data/lib/omnizip/formats/msi/string_pool.rb +246 -0
  335. data/lib/omnizip/formats/msi/table_parser.rb +244 -0
  336. data/lib/omnizip/formats/msi.rb +73 -0
  337. data/lib/omnizip/formats/ole/allocation_table.rb +263 -0
  338. data/lib/omnizip/formats/ole/constants.rb +61 -0
  339. data/lib/omnizip/formats/ole/dirent.rb +439 -0
  340. data/lib/omnizip/formats/ole/header.rb +199 -0
  341. data/lib/omnizip/formats/ole/ranges_io.rb +347 -0
  342. data/lib/omnizip/formats/ole/storage.rb +482 -0
  343. data/lib/omnizip/formats/ole/types/variant.rb +338 -0
  344. data/lib/omnizip/formats/ole.rb +143 -0
  345. data/lib/omnizip/formats/rar/archive_repairer.rb +240 -0
  346. data/lib/omnizip/formats/rar/archive_verifier.rb +192 -0
  347. data/lib/omnizip/formats/rar/block_parser.rb +282 -0
  348. data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
  349. data/lib/omnizip/formats/rar/compression/dispatcher.rb +210 -0
  350. data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +212 -0
  351. data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +154 -0
  352. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
  353. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
  354. data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
  355. data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
  356. data/lib/omnizip/formats/rar/compression/lz77_huffman.rb +25 -0
  357. data/lib/omnizip/formats/rar/compression/ppmd/context.rb +103 -0
  358. data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +238 -0
  359. data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +250 -0
  360. data/lib/omnizip/formats/rar/compression/ppmd.rb +16 -0
  361. data/lib/omnizip/formats/rar/compression.rb +17 -0
  362. data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
  363. data/lib/omnizip/formats/rar/constants.rb +88 -0
  364. data/lib/omnizip/formats/rar/decompressor.rb +316 -0
  365. data/lib/omnizip/formats/rar/external_writer.rb +311 -0
  366. data/lib/omnizip/formats/rar/header.rb +209 -0
  367. data/lib/omnizip/formats/rar/license_validator.rb +111 -0
  368. data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
  369. data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
  370. data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
  371. data/lib/omnizip/formats/rar/models.rb +14 -0
  372. data/lib/omnizip/formats/rar/parity_handler.rb +299 -0
  373. data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +200 -0
  374. data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +584 -0
  375. data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
  376. data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
  377. data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +96 -0
  378. data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
  379. data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +162 -0
  380. data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
  381. data/lib/omnizip/formats/rar/rar5/header.rb +208 -0
  382. data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
  383. data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
  384. data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
  385. data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
  386. data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
  387. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +260 -0
  388. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
  389. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +176 -0
  390. data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +108 -0
  391. data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +139 -0
  392. data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
  393. data/lib/omnizip/formats/rar/rar5/vint.rb +53 -0
  394. data/lib/omnizip/formats/rar/rar5/writer.rb +540 -0
  395. data/lib/omnizip/formats/rar/rar_format_base.rb +239 -0
  396. data/lib/omnizip/formats/rar/reader.rb +377 -0
  397. data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
  398. data/lib/omnizip/formats/rar/volume_manager.rb +166 -0
  399. data/lib/omnizip/formats/rar/writer.rb +437 -0
  400. data/lib/omnizip/formats/rar.rb +193 -0
  401. data/lib/omnizip/formats/rar3/compressor.rb +71 -0
  402. data/lib/omnizip/formats/rar3/decompressor.rb +64 -0
  403. data/lib/omnizip/formats/rar3/reader.rb +107 -0
  404. data/lib/omnizip/formats/rar3/writer.rb +220 -0
  405. data/lib/omnizip/formats/rar3.rb +15 -0
  406. data/lib/omnizip/formats/rar5/compressor.rb +71 -0
  407. data/lib/omnizip/formats/rar5/decompressor.rb +64 -0
  408. data/lib/omnizip/formats/rar5/reader.rb +130 -0
  409. data/lib/omnizip/formats/rar5/writer.rb +65 -0
  410. data/lib/omnizip/formats/rar5.rb +15 -0
  411. data/lib/omnizip/formats/rpm/constants.rb +58 -0
  412. data/lib/omnizip/formats/rpm/entry.rb +106 -0
  413. data/lib/omnizip/formats/rpm/header.rb +106 -0
  414. data/lib/omnizip/formats/rpm/lead.rb +132 -0
  415. data/lib/omnizip/formats/rpm/tag.rb +228 -0
  416. data/lib/omnizip/formats/rpm/writer.rb +652 -0
  417. data/lib/omnizip/formats/rpm.rb +458 -0
  418. data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +274 -0
  419. data/lib/omnizip/formats/seven_zip/coder_chain.rb +169 -0
  420. data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
  421. data/lib/omnizip/formats/seven_zip/encoded_header.rb +110 -0
  422. data/lib/omnizip/formats/seven_zip/encrypted_header.rb +139 -0
  423. data/lib/omnizip/formats/seven_zip/file_collector.rb +143 -0
  424. data/lib/omnizip/formats/seven_zip/header.rb +102 -0
  425. data/lib/omnizip/formats/seven_zip/header_encryptor.rb +132 -0
  426. data/lib/omnizip/formats/seven_zip/header_writer.rb +425 -0
  427. data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
  428. data/lib/omnizip/formats/seven_zip/models/file_entry.rb +65 -0
  429. data/lib/omnizip/formats/seven_zip/models/folder.rb +67 -0
  430. data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
  431. data/lib/omnizip/formats/seven_zip/models.rb +20 -0
  432. data/lib/omnizip/formats/seven_zip/parser.rb +671 -0
  433. data/lib/omnizip/formats/seven_zip/reader.rb +626 -0
  434. data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +611 -0
  435. data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +308 -0
  436. data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
  437. data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +166 -0
  438. data/lib/omnizip/formats/seven_zip/writer.rb +801 -0
  439. data/lib/omnizip/formats/seven_zip.rb +179 -0
  440. data/lib/omnizip/formats/tar/constants.rb +73 -0
  441. data/lib/omnizip/formats/tar/entry.rb +98 -0
  442. data/lib/omnizip/formats/tar/header.rb +206 -0
  443. data/lib/omnizip/formats/tar/reader.rb +119 -0
  444. data/lib/omnizip/formats/tar/writer.rb +212 -0
  445. data/lib/omnizip/formats/tar.rb +74 -0
  446. data/lib/omnizip/formats/xar/constants.rb +119 -0
  447. data/lib/omnizip/formats/xar/entry.rb +268 -0
  448. data/lib/omnizip/formats/xar/header.rb +223 -0
  449. data/lib/omnizip/formats/xar/reader.rb +400 -0
  450. data/lib/omnizip/formats/xar/toc.rb +570 -0
  451. data/lib/omnizip/formats/xar/writer.rb +461 -0
  452. data/lib/omnizip/formats/xar.rb +145 -0
  453. data/lib/omnizip/formats/xz/reader.rb +121 -0
  454. data/lib/omnizip/formats/xz/writer.rb +416 -0
  455. data/lib/omnizip/formats/xz.rb +210 -0
  456. data/lib/omnizip/formats/xz_const.rb +49 -0
  457. data/lib/omnizip/formats/xz_impl/block_decoder.rb +761 -0
  458. data/lib/omnizip/formats/xz_impl/block_encoder.rb +304 -0
  459. data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
  460. data/lib/omnizip/formats/xz_impl/block_header_parser.rb +182 -0
  461. data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
  462. data/lib/omnizip/formats/xz_impl/index_encoder.rb +120 -0
  463. data/lib/omnizip/formats/xz_impl/stream_decoder.rb +470 -0
  464. data/lib/omnizip/formats/xz_impl/stream_encoder.rb +95 -0
  465. data/lib/omnizip/formats/xz_impl/stream_footer.rb +79 -0
  466. data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +115 -0
  467. data/lib/omnizip/formats/xz_impl/stream_header.rb +53 -0
  468. data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +106 -0
  469. data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
  470. data/lib/omnizip/formats/xz_impl.rb +52 -0
  471. data/lib/omnizip/formats/zip/central_directory_header.rb +223 -0
  472. data/lib/omnizip/formats/zip/constants.rb +69 -0
  473. data/lib/omnizip/formats/zip/end_of_central_directory.rb +132 -0
  474. data/lib/omnizip/formats/zip/local_file_header.rb +136 -0
  475. data/lib/omnizip/formats/zip/reader.rb +376 -0
  476. data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
  477. data/lib/omnizip/formats/zip/writer.rb +489 -0
  478. data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +102 -0
  479. data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +64 -0
  480. data/lib/omnizip/formats/zip/zip64_extra_field.rb +112 -0
  481. data/lib/omnizip/formats/zip.rb +50 -0
  482. data/lib/omnizip/formats.rb +29 -0
  483. data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
  484. data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
  485. data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
  486. data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
  487. data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
  488. data/lib/omnizip/implementations/base.rb +19 -0
  489. data/lib/omnizip/implementations/rust/archive.rb +93 -0
  490. data/lib/omnizip/implementations/rust/library.rb +221 -0
  491. data/lib/omnizip/implementations/rust.rb +26 -0
  492. data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +428 -0
  493. data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +456 -0
  494. data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +285 -0
  495. data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +197 -0
  496. data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +194 -0
  497. data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +139 -0
  498. data/lib/omnizip/implementations/seven_zip/lzma.rb +21 -0
  499. data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +56 -0
  500. data/lib/omnizip/implementations/seven_zip/lzma2.rb +12 -0
  501. data/lib/omnizip/implementations/seven_zip.rb +11 -0
  502. data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +547 -0
  503. data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +748 -0
  504. data/lib/omnizip/implementations/xz_utils/lzma2.rb +13 -0
  505. data/lib/omnizip/implementations/xz_utils.rb +10 -0
  506. data/lib/omnizip/implementations.rb +25 -0
  507. data/lib/omnizip/io/buffered_input.rb +147 -0
  508. data/lib/omnizip/io/buffered_output.rb +106 -0
  509. data/lib/omnizip/io/source.rb +143 -0
  510. data/lib/omnizip/io/stream_manager.rb +117 -0
  511. data/lib/omnizip/io.rb +15 -0
  512. data/lib/omnizip/link_handler/hard_link.rb +79 -0
  513. data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
  514. data/lib/omnizip/link_handler.rb +129 -0
  515. data/lib/omnizip/metadata/archive_metadata.rb +114 -0
  516. data/lib/omnizip/metadata/entry_metadata.rb +153 -0
  517. data/lib/omnizip/metadata/metadata_editor.rb +169 -0
  518. data/lib/omnizip/metadata/metadata_registry.rb +71 -0
  519. data/lib/omnizip/metadata/metadata_validator.rb +101 -0
  520. data/lib/omnizip/metadata.rb +58 -0
  521. data/lib/omnizip/models/.keep +0 -0
  522. data/lib/omnizip/models/algorithm_metadata.rb +41 -0
  523. data/lib/omnizip/models/attribute_apply.rb +40 -0
  524. data/lib/omnizip/models/compression_options.rb +53 -0
  525. data/lib/omnizip/models/conversion_options.rb +79 -0
  526. data/lib/omnizip/models/conversion_result.rb +141 -0
  527. data/lib/omnizip/models/eta_result.rb +45 -0
  528. data/lib/omnizip/models/extraction_rule.rb +115 -0
  529. data/lib/omnizip/models/filter_chain.rb +142 -0
  530. data/lib/omnizip/models/filter_config.rb +148 -0
  531. data/lib/omnizip/models/match_result.rb +141 -0
  532. data/lib/omnizip/models/optimization_suggestion.rb +95 -0
  533. data/lib/omnizip/models/parallel_options.rb +116 -0
  534. data/lib/omnizip/models/performance_result.rb +85 -0
  535. data/lib/omnizip/models/profile_report.rb +116 -0
  536. data/lib/omnizip/models/progress_options.rb +39 -0
  537. data/lib/omnizip/models/split_options.rb +116 -0
  538. data/lib/omnizip/optimization_registry.rb +45 -0
  539. data/lib/omnizip/parallel/engine.rb +52 -0
  540. data/lib/omnizip/parallel/job_queue.rb +209 -0
  541. data/lib/omnizip/parallel/job_scheduler.rb +225 -0
  542. data/lib/omnizip/parallel/parallel_compressor.rb +326 -0
  543. data/lib/omnizip/parallel/parallel_extractor.rb +238 -0
  544. data/lib/omnizip/parallel/thread_pool.rb +60 -0
  545. data/lib/omnizip/parallel/worker_pool.rb +227 -0
  546. data/lib/omnizip/parallel.rb +156 -0
  547. data/lib/omnizip/parity/chunked_block_processor.rb +194 -0
  548. data/lib/omnizip/parity/galois16.rb +145 -0
  549. data/lib/omnizip/parity/models/creator_packet.rb +71 -0
  550. data/lib/omnizip/parity/models/file_description_packet.rb +131 -0
  551. data/lib/omnizip/parity/models/ifsc_packet.rb +111 -0
  552. data/lib/omnizip/parity/models/main_packet.rb +126 -0
  553. data/lib/omnizip/parity/models/packet.rb +156 -0
  554. data/lib/omnizip/parity/models/packet_registry.rb +102 -0
  555. data/lib/omnizip/parity/models/recovery_slice_packet.rb +76 -0
  556. data/lib/omnizip/parity/models.rb +27 -0
  557. data/lib/omnizip/parity/par2_creator.rb +496 -0
  558. data/lib/omnizip/parity/par2_repairer.rb +409 -0
  559. data/lib/omnizip/parity/par2_verifier.rb +373 -0
  560. data/lib/omnizip/parity/par2cmdline_algorithm.rb +108 -0
  561. data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
  562. data/lib/omnizip/parity/reed_solomon_decoder.rb +263 -0
  563. data/lib/omnizip/parity/reed_solomon_encoder.rb +108 -0
  564. data/lib/omnizip/parity/reed_solomon_matrix.rb +339 -0
  565. data/lib/omnizip/parity.rb +207 -0
  566. data/lib/omnizip/password/encryption_registry.rb +26 -0
  567. data/lib/omnizip/password/encryption_strategy.rb +96 -0
  568. data/lib/omnizip/password/password_validator.rb +129 -0
  569. data/lib/omnizip/password/winzip_aes_strategy.rb +190 -0
  570. data/lib/omnizip/password/zip_crypto_strategy.rb +135 -0
  571. data/lib/omnizip/password.rb +88 -0
  572. data/lib/omnizip/pipe/stream_compressor.rb +124 -0
  573. data/lib/omnizip/pipe/stream_decompressor.rb +173 -0
  574. data/lib/omnizip/pipe.rb +120 -0
  575. data/lib/omnizip/platform/ntfs_streams.rb +200 -0
  576. data/lib/omnizip/platform.rb +189 -0
  577. data/lib/omnizip/profile/archive_profile.rb +36 -0
  578. data/lib/omnizip/profile/balanced_profile.rb +31 -0
  579. data/lib/omnizip/profile/binary_profile.rb +33 -0
  580. data/lib/omnizip/profile/compression_profile.rb +157 -0
  581. data/lib/omnizip/profile/custom_profile.rb +155 -0
  582. data/lib/omnizip/profile/fast_profile.rb +31 -0
  583. data/lib/omnizip/profile/maximum_profile.rb +31 -0
  584. data/lib/omnizip/profile/profile_detector.rb +108 -0
  585. data/lib/omnizip/profile/profile_registry.rb +160 -0
  586. data/lib/omnizip/profile/text_profile.rb +33 -0
  587. data/lib/omnizip/profile.rb +261 -0
  588. data/lib/omnizip/profiler/memory_profiler.rb +66 -0
  589. data/lib/omnizip/profiler/method_profiler.rb +49 -0
  590. data/lib/omnizip/profiler/report_generator.rb +158 -0
  591. data/lib/omnizip/profiler.rb +192 -0
  592. data/lib/omnizip/progress/callback_reporter.rb +34 -0
  593. data/lib/omnizip/progress/console_reporter.rb +59 -0
  594. data/lib/omnizip/progress/log_reporter.rb +89 -0
  595. data/lib/omnizip/progress/operation_progress.rb +118 -0
  596. data/lib/omnizip/progress/progress_bar.rb +156 -0
  597. data/lib/omnizip/progress/progress_reporter.rb +40 -0
  598. data/lib/omnizip/progress/progress_tracker.rb +215 -0
  599. data/lib/omnizip/progress/silent_reporter.rb +22 -0
  600. data/lib/omnizip/progress.rb +131 -0
  601. data/lib/omnizip/registry.rb +111 -0
  602. data/lib/omnizip/rubyzip_compat.rb +61 -0
  603. data/lib/omnizip/temp/safe_extract.rb +124 -0
  604. data/lib/omnizip/temp/temp_file.rb +123 -0
  605. data/lib/omnizip/temp/temp_file_pool.rb +109 -0
  606. data/lib/omnizip/temp.rb +184 -0
  607. data/lib/omnizip/version.rb +5 -0
  608. data/lib/omnizip/zip/entry.rb +160 -0
  609. data/lib/omnizip/zip/file.rb +485 -0
  610. data/lib/omnizip/zip/input_stream.rb +270 -0
  611. data/lib/omnizip/zip/output_stream.rb +320 -0
  612. data/lib/omnizip/zip.rb +23 -0
  613. data/lib/omnizip.rb +157 -0
  614. data/lib/tasks/msi_test_files.rake +66 -0
  615. data/lib/tasks/platform_gems.rake +147 -0
  616. data/lib/tasks/rust_backend.rake +48 -0
  617. data/readme-docs/advanced-features.adoc +514 -0
  618. data/readme-docs/api-usage.adoc +445 -0
  619. data/readme-docs/architecture.adoc +450 -0
  620. data/readme-docs/archive-formats.adoc +479 -0
  621. data/readme-docs/cli-usage.adoc +222 -0
  622. data/readme-docs/compression-algorithms.adoc +446 -0
  623. data/readme-docs/compression-profiles.adoc +247 -0
  624. data/readme-docs/encryption-checksums.adoc +328 -0
  625. data/readme-docs/format-converter.adoc +316 -0
  626. data/readme-docs/installation.adoc +228 -0
  627. data/readme-docs/par2-archives.adoc +608 -0
  628. data/readme-docs/performance-profiler.adoc +389 -0
  629. data/readme-docs/preprocessing-filters.adoc +280 -0
  630. data/vendor/libomnizip_ffi.so +0 -0
  631. data/xz-file-format-1.2.1.txt +1174 -0
  632. metadata +768 -0
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Formats
5
+ # ISO 9660 CD-ROM filesystem format support
6
+ #
7
+ # Reads and writes ISO 9660 images: Primary Volume Descriptor
8
+ # parsing, directory traversal, file extraction, and image
9
+ # creation whose directory records point at allocated extents
10
+ # (verified against 7-Zip). Rock Ridge and Joliet are NOT
11
+ # implemented — the writer's options stay false rather than
12
+ # advertising extensions readers would misparse.
13
+ module Iso
14
+ # Nested classes - autoloaded
15
+ autoload :Reader, "omnizip/formats/iso/reader"
16
+ autoload :Writer, "omnizip/formats/iso/writer"
17
+ autoload :VolumeDescriptor, "omnizip/formats/iso/volume_descriptor"
18
+ autoload :VolumeBuilder, "omnizip/formats/iso/volume_builder"
19
+ autoload :DirectoryRecord, "omnizip/formats/iso/directory_record"
20
+ autoload :DirectoryBuilder, "omnizip/formats/iso/directory_builder"
21
+ autoload :PathTable, "omnizip/formats/iso/path_table"
22
+ autoload :RockRidge, "omnizip/formats/iso/rock_ridge"
23
+ autoload :Joliet, "omnizip/formats/iso/joliet"
24
+
25
+ # ISO 9660 constants
26
+ SECTOR_SIZE = 2048
27
+ SYSTEM_AREA_SECTORS = 16
28
+ VOLUME_DESCRIPTOR_START = SYSTEM_AREA_SECTORS
29
+
30
+ # Volume descriptor types
31
+ VD_BOOT_RECORD = 0
32
+ VD_PRIMARY = 1
33
+ VD_SUPPLEMENTARY = 2
34
+ VD_PARTITION = 3
35
+ VD_TERMINATOR = 255
36
+
37
+ # File flags
38
+ FLAG_HIDDEN = 0x01
39
+ FLAG_DIRECTORY = 0x02
40
+ FLAG_ASSOCIATED = 0x04
41
+ FLAG_EXTENDED = 0x08
42
+ FLAG_PERMISSIONS = 0x10
43
+ FLAG_NOT_FINAL = 0x80
44
+
45
+ # Open existing ISO image
46
+ #
47
+ # @param path [String] Path to ISO file
48
+ # @yield [reader] Block for reading archive
49
+ # @yieldparam reader [Reader] ISO reader
50
+ # @return [Reader] ISO reader
51
+ def self.open(path)
52
+ reader = Reader.new(path)
53
+ reader.open
54
+
55
+ if block_given?
56
+ begin
57
+ yield reader
58
+ ensure
59
+ reader.close
60
+ end
61
+ end
62
+
63
+ reader
64
+ end
65
+
66
+ # List contents of ISO image
67
+ #
68
+ # @param path [String] Path to ISO file
69
+ # @return [Array<DirectoryRecord>] Directory entries
70
+ def self.list(path)
71
+ entries = nil
72
+ open(path) { |iso| entries = iso.entries }
73
+ entries
74
+ end
75
+
76
+ # Extract ISO contents
77
+ #
78
+ # @param iso_path [String] Path to ISO file
79
+ # @param output_dir [String] Output directory
80
+ def self.extract(iso_path, output_dir)
81
+ open(iso_path) do |iso|
82
+ iso.extract_all(output_dir)
83
+ end
84
+ end
85
+
86
+ # Get ISO volume information
87
+ #
88
+ # @param path [String] Path to ISO file
89
+ # @return [Hash] Volume information
90
+ def self.info(path)
91
+ open(path) do |iso|
92
+ {
93
+ format: "ISO 9660",
94
+ volume_id: iso.volume_identifier,
95
+ system_id: iso.system_identifier,
96
+ size: iso.volume_size,
97
+ files: iso.entries.count { |e| !e.directory? },
98
+ directories: iso.entries.count(&:directory?),
99
+ }
100
+ end
101
+ end
102
+
103
+ # Create ISO 9660 image
104
+ #
105
+ # @param path [String] Output ISO file path
106
+ # @param options [Hash] Creation options
107
+ # @yield [writer] Block for adding files/directories
108
+ # @yieldparam writer [Writer] ISO writer
109
+ # @return [String] Path to created ISO
110
+ #
111
+ # @example Create ISO image
112
+ # Omnizip::Formats::Iso.create('backup.iso') do |iso|
113
+ # iso.volume_id = 'BACKUP_2024'
114
+ # iso.add_directory('documents/')
115
+ # end
116
+ #
117
+ # @example With Rock Ridge and Joliet
118
+ # Omnizip::Formats::Iso.create('cdrom.iso',
119
+ # rock_ridge: true,
120
+ # joliet: true
121
+ # ) do |iso|
122
+ # iso.add_directory('files/')
123
+ # end
124
+ def self.create(path, options = {})
125
+ writer = Writer.new(path, options)
126
+
127
+ yield writer if block_given?
128
+
129
+ writer.write
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
4
+
5
+ module Omnizip
6
+ module Formats
7
+ #
8
+ # LZIP (.lz) compression format
9
+ #
10
+ # Lzip is a file compression format that uses LZMA compression with a
11
+ # simple container format. It was created as an alternative to the
12
+ # legacy .lzma format with better integrity checking.
13
+ #
14
+ # This is DIFFERENT from both XZ and .lzma (LZMA_Alone) formats:
15
+ # - XZ (.xz): Container format with stream header/footer/index, LZMA2 compression
16
+ # - LZIP (.lz): Standalone format with "LZIP" magic and CRC32 footer, LZMA1 compression
17
+ # - LZMA_Alone (.lzma): Legacy standalone format with properties byte, LZMA1 compression
18
+ #
19
+ # Format structure:
20
+ # - Header (6 bytes):
21
+ # - Magic bytes: "LZIP" (0x4C 0x5A 0x49 0x50)
22
+ # - Version (1 byte): 0 or 1
23
+ # - Dictionary size (1 byte): encoded format
24
+ # - LZMA1 compressed stream (with fixed LC=3, LP=0, PB=2)
25
+ # - Footer:
26
+ # - Version 0 (12 bytes): CRC32 (4) + Uncompressed size (8)
27
+ # - Version 1 (20 bytes): CRC32 (4) + Uncompressed size (8) + Member size (8)
28
+ #
29
+ # Reference: /Users/mulgogi/src/external/xz/src/liblzma/common/lzip_decoder.c
30
+ #
31
+ module Lzip
32
+ # Lzip magic bytes: "LZIP" in ASCII
33
+ # Reference: lzip_decoder.c:106
34
+ MAGIC = [0x4C, 0x5A, 0x49, 0x50].pack("C*")
35
+
36
+ # Fixed LC/LP/PB values for lzip format
37
+ # Reference: lzip_decoder.c:23-26
38
+ LZIP_LC = 3
39
+ LZIP_LP = 0
40
+ LZIP_PB = 2
41
+
42
+ # Minimum and maximum dictionary sizes (in bytes)
43
+ # Reference: lzip_decoder.c:197-198
44
+ MIN_DICT_SIZE = 4096 # 4 KiB
45
+ MAX_DICT_SIZE = (512 << 20) # 512 MiB
46
+
47
+ class << self
48
+ # Compress a file with LZIP
49
+ #
50
+ # @param input_path [String] Input file path
51
+ # @param output_path [String] Output LZIP file path
52
+ # @param options [Hash] Compression options
53
+ # @option options [Integer] :level Compression level (0-9, default: 6)
54
+ # @option options [Integer] :dict_size Dictionary size (default: auto from level)
55
+ # @option options [Integer] :version LZIP version (0 or 1, default: 1)
56
+ def compress(input_path, output_path, options = {})
57
+ input_data = File.binread(input_path)
58
+
59
+ File.open(output_path, "wb") do |output|
60
+ compress_stream(
61
+ StringIO.new(input_data),
62
+ output,
63
+ options,
64
+ )
65
+ end
66
+ end
67
+
68
+ # Decompress LZIP data
69
+ #
70
+ # @param input [String, IO] Input data, file path, or IO object
71
+ # @param output [String, IO, nil] Output file path or IO object
72
+ # @param options [Hash] Options
73
+ # @option options [Boolean] :ignore_check If true, skip CRC32 verification (default: false)
74
+ # @option options [Boolean] :concatenated If true, decode concatenated .lz members (default: false)
75
+ # @return [String, nil] Decompressed data (if output is nil)
76
+ def decompress(input, output = nil, options = {})
77
+ data = Omnizip::IO::Source.for(input).read
78
+
79
+ # Decode using LzipDecoder
80
+ decoder = Omnizip::Algorithms::LZMA::LzipDecoder.new(
81
+ StringIO.new(data),
82
+ options,
83
+ )
84
+ result = decoder.decode_stream
85
+
86
+ if output
87
+ Omnizip::IO::Sink.for(output).write(result)
88
+ else
89
+ result
90
+ end
91
+ end
92
+
93
+ # Decode LZIP data (alias for decompress with no output)
94
+ #
95
+ # @param input [String, IO] Input LZIP data or file path
96
+ # @return [String] Decompressed data
97
+ def decode(input)
98
+ decompress(input)
99
+ end
100
+
101
+ # Compress data stream with LZIP
102
+ #
103
+ # @param input_io [IO] Input stream
104
+ # @param output_io [IO] Output stream
105
+ # @param options [Hash] Compression options
106
+ def compress_stream(input_io, output_io, options = {})
107
+ input = input_io.read
108
+
109
+ # Version-1 member: magic + version + dict-size byte, LZMA1
110
+ # body (EOPM-terminated), 20-byte trailer (CRC32 + data
111
+ # size + member size). The dictionary byte uses lzip's
112
+ # 5-bit exponent / 3-bit fraction encoding; 4 MiB is the
113
+ # typical default.
114
+ output_io.write(MAGIC)
115
+ output_io.write([1].pack("C"))
116
+ output_io.write([22].pack("C")) # 2^22 = 4 MiB, no fraction
117
+
118
+ dict_size = options.fetch(:dict_size, 8 * 1024 * 1024)
119
+ body = Algorithms::LZMA::Lzma1Encoder
120
+ .new(dict_size: dict_size).encode(input)
121
+
122
+ member_size = 6 + body.bytesize + 20
123
+ output_io.write(body)
124
+ output_io.write([Checksums::Crc32.calculate(input)].pack("V"))
125
+ output_io.write([input.bytesize].pack("Q<"))
126
+ output_io.write([member_size].pack("Q<"))
127
+ end
128
+
129
+ # Decompress LZIP stream
130
+ #
131
+ # @param input_io [IO] Input stream
132
+ # @param output_io [IO] Output stream
133
+ # @param options [Hash] Options
134
+ # @return [Hash] Metadata (version, dict_size, member_size)
135
+ def decompress_stream(input_io, output_io, options = {})
136
+ output_io.set_encoding(Encoding::BINARY)
137
+ decoder = Omnizip::Algorithms::LZMA::LzipDecoder.new(input_io,
138
+ options)
139
+ result = decoder.decode_stream
140
+
141
+ output_io.write(result)
142
+
143
+ # Return metadata
144
+ {
145
+ version: decoder.version,
146
+ dict_size: decoder.dict_size,
147
+ member_size: decoder.member_size,
148
+ }
149
+ end
150
+
151
+ # Detect if data is LZIP format
152
+ #
153
+ # @param data [String] Data to check
154
+ # @return [Boolean] true if data has LZIP magic bytes
155
+ def lzip_file?(data)
156
+ data.start_with?(MAGIC)
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
4
+
5
+ module Omnizip
6
+ module Formats
7
+ #
8
+ # LZMA_Alone (.lzma) compression format
9
+ #
10
+ # This is the legacy LZMA_Alone format used by LZMA Utils 4.32.x.
11
+ # It is DIFFERENT from both XZ and LZIP formats:
12
+ # - XZ (.xz): Container format with stream header/footer/index, LZMA2 compression
13
+ # - LZIP (.lz): Standalone format with "LZIP" magic and CRC32 footer, LZMA1 compression
14
+ # - LZMA_Alone (.lzma): Legacy standalone format with properties byte, LZMA1 compression
15
+ #
16
+ # Format structure:
17
+ # - Properties (1 byte): encodes lc, lp, pb values
18
+ # - Dictionary size (4 bytes, little-endian)
19
+ # - Uncompressed size (8 bytes, little-endian, UINT64_MAX = unknown)
20
+ # - LZMA1 compressed stream (no footer, no CRC32)
21
+ #
22
+ # Reference: /Users/mulgogi/src/external/xz/src/liblzma/common/alone_decoder.c
23
+ #
24
+ module LzmaAlone
25
+ # Maximum valid uncompressed size (256 GiB)
26
+ # From alone_decoder.c:118
27
+ MAX_UNCOMPRESSED_SIZE = (1 << 38)
28
+
29
+ # Property byte validation limits
30
+ # From lzma_decoder.c:1218
31
+ MAX_PROPERTY_BYTE = (((4 * 5) + 4) * 9) + 8 # = 233
32
+
33
+ # Value indicating unknown uncompressed size
34
+ UINT64_MAX = (1 << 64) - 1
35
+
36
+ class << self
37
+ # Compress a file with LZMA_Alone format
38
+ #
39
+ # @param input_path [String] Input file path
40
+ # @param output_path [String] Output LZMA_Alone file path
41
+ # @param options [Hash] Compression options
42
+ # @option options [Integer] :lc Literal context bits (0-8, default: 3)
43
+ # @option options [Integer] :lp Literal position bits (0-4, default: 0)
44
+ # @option options [Integer] :pb Position bits (0-4, default: 2)
45
+ # @option options [Integer] :dict_size Dictionary size (default: 8MB)
46
+ # @option options [Integer] :uncompressed_size Explicit uncompressed size (default: unknown)
47
+ def compress(input_path, output_path, options = {})
48
+ input_data = File.binread(input_path)
49
+
50
+ File.open(output_path, "wb") do |output|
51
+ compress_stream(
52
+ StringIO.new(input_data),
53
+ output,
54
+ options,
55
+ )
56
+ end
57
+ end
58
+
59
+ # Decompress LZMA_Alone data
60
+ #
61
+ # @param input [String, IO] Input data, file path, or IO object
62
+ # @param output [String, IO, nil] Output file path or IO object
63
+ # @param options [Hash] Options
64
+ # @option options [Boolean] :picky If true, reject files unlikely to be .lzma (default: false)
65
+ # @return [String, nil] Decompressed data (if output is nil)
66
+ def decompress(input, output = nil, options = {})
67
+ data = Omnizip::IO::Source.for(input).read
68
+
69
+ # Decode using LzmaAloneDecoder
70
+ decoder = Omnizip::Algorithms::LZMA::LzmaAloneDecoder.new(
71
+ StringIO.new(data),
72
+ options,
73
+ )
74
+ result = decoder.decode_stream
75
+
76
+ if output
77
+ Omnizip::IO::Sink.for(output).write(result)
78
+ else
79
+ result
80
+ end
81
+ end
82
+
83
+ # Decode LZMA_Alone data (alias for decompress with no output)
84
+ #
85
+ # @param input [String, IO] Input LZMA_Alone data or file path
86
+ # @return [String] Decompressed data
87
+ def decode(input)
88
+ decompress(input)
89
+ end
90
+
91
+ # Compress data stream with LZMA_Alone format
92
+ #
93
+ # @param input_io [IO] Input stream
94
+ # @param output_io [IO] Output stream
95
+ # @param options [Hash] Compression options
96
+ def compress_stream(input_io, output_io, options = {})
97
+ input_data = input_io.read
98
+
99
+ # Get encoding parameters
100
+ lc = options[:lc] || 3
101
+ lp = options[:lp] || 0
102
+ pb = options[:pb] || 2
103
+ dict_size = options[:dict_size] || (8 * 1024 * 1024)
104
+ uncompressed_size = options[:uncompressed_size] || input_data.bytesize
105
+
106
+ # Encode properties byte
107
+ prop_byte = (((pb * 5) + lp) * 9) + lc
108
+
109
+ # Write header
110
+ output_io.write([prop_byte].pack("C"))
111
+ output_io.write([dict_size].pack("V"))
112
+ output_io.write([uncompressed_size].pack("Q<"))
113
+
114
+ # Raw LZMA1 body. The header carries the uncompressed size,
115
+ # but the EOPM is still emitted: the format permits it with
116
+ # a known size and it lets size-agnostic decoders stop too.
117
+ body = Algorithms::LZMA::Lzma1Encoder
118
+ .new(dict_size: dict_size, lc: lc, lp: lp, pb: pb)
119
+ .encode(input_data)
120
+ output_io.write(body)
121
+ end
122
+
123
+ # Decompress LZMA_Alone stream
124
+ #
125
+ # @param input_io [IO] Input stream
126
+ # @param output_io [IO] Output stream
127
+ # @param options [Hash] Options
128
+ # @return [Hash] Metadata (lc, lp, pb, dict_size, uncompressed_size)
129
+ def decompress_stream(input_io, output_io, options = {})
130
+ output_io.set_encoding(Encoding::BINARY)
131
+ decoder = Omnizip::Algorithms::LZMA::LzmaAloneDecoder.new(input_io,
132
+ options)
133
+ result = decoder.decode_stream
134
+
135
+ output_io.write(result)
136
+
137
+ # Return metadata
138
+ {
139
+ lc: decoder.lc,
140
+ lp: decoder.lp,
141
+ pb: decoder.pb,
142
+ dict_size: decoder.dict_size,
143
+ uncompressed_size: decoder.uncompressed_size,
144
+ }
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tempfile"
4
+ require "fileutils"
5
+
6
+ module Omnizip
7
+ module Formats
8
+ module Msi
9
+ # MSI CAB Extractor
10
+ #
11
+ # Handles extraction of files from embedded or external cabinet files.
12
+ # MSI packages can have cabinets embedded in the _Streams table or
13
+ # as separate .cab files alongside the MSI.
14
+ class CabExtractor
15
+ include Omnizip::Formats::Msi::Constants
16
+
17
+ # @return [Ole::Storage] OLE storage
18
+ attr_reader :ole
19
+
20
+ # @return [Array<Hash>] Media table data
21
+ attr_reader :media_table
22
+
23
+ # @return [String] Path to MSI file (for external CAB resolution)
24
+ attr_reader :msi_path
25
+
26
+ # @return [Proc] Stream reader method
27
+ attr_reader :read_stream
28
+
29
+ # Initialize CAB extractor
30
+ #
31
+ # @param ole [Ole::Storage] OLE storage object
32
+ # @param media_table [Array<Hash>] Parsed Media table rows
33
+ # @param msi_path [String] Path to MSI file
34
+ # @param stream_reader [Proc] Method to read streams
35
+ def initialize(ole, media_table, msi_path, stream_reader)
36
+ @ole = ole
37
+ @media_table = media_table || []
38
+ @msi_path = msi_path
39
+ @read_stream = stream_reader
40
+ end
41
+
42
+ # Extract all cabinets to temporary files
43
+ #
44
+ # @return [Hash] Map of cabinet name => temp file path
45
+ def extract_cabinets
46
+ cabinets = {}
47
+
48
+ @media_table.each do |media|
49
+ cab_name = media["Cabinet"]
50
+ next if cab_name.nil? || cab_name.empty?
51
+
52
+ cab_data = get_cabinet_data(cab_name)
53
+ next if cab_data.nil? || cab_data.empty?
54
+
55
+ # Write to temp file
56
+ temp_file = Tempfile.create(["msi_cab_", ".cab"])
57
+ temp_file.binmode
58
+ temp_file.write(cab_data)
59
+ temp_file.flush
60
+ temp_file.close
61
+
62
+ cabinets[media["DiskId"]] = {
63
+ path: temp_file.path,
64
+ name: cab_name,
65
+ last_sequence: media["LastSequence"],
66
+ temp_file: temp_file,
67
+ }
68
+ end
69
+
70
+ cabinets
71
+ end
72
+
73
+ # Get cabinet data for a media entry
74
+ #
75
+ # @param cabinet_name [String] Cabinet name from Media table
76
+ # @return [String, nil] Cabinet binary data or nil
77
+ def get_cabinet_data(cabinet_name)
78
+ return nil if cabinet_name.nil? || cabinet_name.empty?
79
+
80
+ if cabinet_name.start_with?(EMBEDDED_CAB_PREFIX)
81
+ # Embedded cabinet
82
+ extract_embedded_cabinet(cabinet_name[1..])
83
+ else
84
+ # External cabinet file
85
+ read_external_cabinet(cabinet_name)
86
+ end
87
+ end
88
+
89
+ # Find the cabinet containing a file by sequence number
90
+ #
91
+ # @param sequence [Integer] File sequence number
92
+ # @param cabinets [Hash] Cabinet info from extract_cabinets
93
+ # @return [Hash, nil] Cabinet info or nil
94
+ def find_cabinet_for_sequence(sequence, cabinets)
95
+ # Sort by LastSequence and find the cabinet where sequence <= LastSequence
96
+ sorted = cabinets.values.sort_by { |c| c[:last_sequence] }
97
+ sorted.find { |c| sequence <= c[:last_sequence] }
98
+ end
99
+
100
+ private
101
+
102
+ # Extract embedded cabinet data
103
+ #
104
+ # Embedded cabinets can be in:
105
+ # 1. _Streams table (most common)
106
+ # 2. Direct OLE stream (rare)
107
+ #
108
+ # @param stream_name [String] Stream name (without # prefix)
109
+ # @return [String, nil] Cabinet data or nil
110
+ def extract_embedded_cabinet(stream_name)
111
+ return nil if stream_name.nil? || stream_name.empty?
112
+
113
+ # Try to read from OLE directly using various name encodings
114
+ candidates = build_stream_name_candidates(stream_name)
115
+
116
+ candidates.each do |name|
117
+ data = @read_stream.call(name)
118
+ return data if data && !data.empty? && valid_cab?(data)
119
+ end
120
+
121
+ # Also try without # prefix but with standard prefixes
122
+ data = @read_stream.call(stream_name)
123
+ return data if data && !data.empty? && valid_cab?(data)
124
+
125
+ nil
126
+ end
127
+
128
+ # Build possible encoded stream name candidates
129
+ #
130
+ # @param name [String] Base stream name
131
+ # @return [Array<String>] Possible stream names
132
+ def build_stream_name_candidates(name)
133
+ candidates = []
134
+
135
+ # Try direct name
136
+ candidates << name
137
+
138
+ # Try with MSI stream name encoding prefix
139
+ # Use binary encoding for the prefix byte
140
+ utf16le = name.encode("UTF-16LE")
141
+ candidates << ("\x01".b << utf16le.dup.force_encoding("BINARY"))
142
+ candidates << ("\x05".b << utf16le.dup.force_encoding("BINARY"))
143
+
144
+ # Try without any prefix (plain ASCII)
145
+ candidates << name
146
+
147
+ candidates.uniq
148
+ end
149
+
150
+ # Check if data is a valid cabinet file
151
+ #
152
+ # @param data [String] Binary data
153
+ # @return [Boolean] true if valid CAB signature
154
+ def valid_cab?(data)
155
+ return false if data.nil? || data.bytesize < 4
156
+
157
+ # Check for MSCF signature
158
+ data[0, 4] == "MSCF"
159
+ end
160
+
161
+ # Read external cabinet file
162
+ #
163
+ # External cabinets are located in the same directory as the MSI.
164
+ #
165
+ # @param cabinet_name [String] Cabinet filename
166
+ # @return [String, nil] Cabinet data or nil
167
+ def read_external_cabinet(cabinet_name)
168
+ return nil if @msi_path.nil?
169
+
170
+ cab_path = File.join(File.dirname(@msi_path), cabinet_name)
171
+
172
+ begin
173
+ File.binread(cab_path) if File.exist?(cab_path)
174
+ rescue StandardError
175
+ nil
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end