omnizip 0.4.7-arm-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,274 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
4
+
5
+ module Omnizip
6
+ module Formats
7
+ module SevenZip
8
+ # Decompresses BCJ2 multi-stream folders
9
+ #
10
+ # BCJ2 archives have 4 separate pack streams that need to be:
11
+ # 1. Read separately
12
+ # 2. Decompressed individually (main is LZMA, others are usually COPY)
13
+ # 3. Combined via BCJ2 decoder
14
+ class Bcj2StreamDecompressor
15
+ include Omnizip::Formats::SevenZip::Constants
16
+
17
+ # Initialize BCJ2 decompressor
18
+ #
19
+ # @param archive_io [IO] Archive file handle
20
+ # @param folder [Models::Folder] Folder with BCJ2 coder
21
+ # @param pack_pos [Integer] Base position of packed data
22
+ # @param pack_sizes [Array<Integer>] Sizes of each pack stream
23
+ # @param stream_info [Models::StreamInfo] Stream info for unpack sizes
24
+ def initialize(archive_io, folder, pack_pos, pack_sizes, stream_info)
25
+ @archive_io = archive_io
26
+ @folder = folder
27
+ @pack_pos = pack_pos
28
+ @pack_sizes = pack_sizes
29
+ @stream_info = stream_info
30
+ end
31
+
32
+ # Check if a folder contains BCJ2 coder
33
+ #
34
+ # @param folder [Models::Folder] Folder to check
35
+ # @return [Boolean] true if folder has BCJ2
36
+ def self.bcj2_folder?(folder)
37
+ folder.coders.any? { |c| c.method_id == FilterId::BCJ2 }
38
+ end
39
+
40
+ # Decompress BCJ2 multi-stream folder
41
+ #
42
+ # @param expected_size [Integer] Expected final output size
43
+ # @return [String] Decompressed and BCJ2-decoded data
44
+ def decompress(expected_size)
45
+ # Find BCJ2 coder and compression coder
46
+ bcj2_coder = @folder.coders.find { |c| c.method_id == FilterId::BCJ2 }
47
+ compression_coder = find_compression_coder
48
+
49
+ raise Omnizip::InvalidArchiveError, "BCJ2 coder not found" unless bcj2_coder
50
+
51
+ # Determine stream layout based on folder structure
52
+ # BCJ2 has 4 input streams: main, call, jump, rc
53
+ stream_layout = determine_stream_layout(bcj2_coder, compression_coder)
54
+
55
+ # Read and decompress each of the 4 streams
56
+ streams = read_bcj2_streams(stream_layout)
57
+
58
+ # Apply BCJ2 decoder
59
+ bcj2_data = Omnizip::Filters::Bcj2StreamData.new
60
+ bcj2_data.main = streams[:main]
61
+ bcj2_data.call = streams[:call]
62
+ bcj2_data.jump = streams[:jump]
63
+ bcj2_data.rc = streams[:rc]
64
+
65
+ decoder = Omnizip::Filters::Bcj2Decoder.new(bcj2_data)
66
+ decoder.decode(expected_size)
67
+ end
68
+
69
+ private
70
+
71
+ # Find the compression coder (LZMA/LZMA2/etc) in the folder
72
+ #
73
+ # @return [Models::CoderInfo, nil] Compression coder
74
+ def find_compression_coder
75
+ @folder.coders.find do |c|
76
+ [MethodId::LZMA, MethodId::LZMA2, MethodId::BZIP2,
77
+ MethodId::DEFLATE, MethodId::DEFLATE64, MethodId::PPMD].include?(c.method_id)
78
+ end
79
+ end
80
+
81
+ # Determine how streams are laid out based on folder structure
82
+ #
83
+ # Analyzes bind pairs to determine which pack stream feeds which
84
+ # BCJ2 input, and which coder (if any) decompresses it.
85
+ #
86
+ # BCJ2 has 4 inputs: main(0), call(1), jump(2), rc(3)
87
+ # Each input is either:
88
+ # - Bound: fed by another coder's output (needs decompression)
89
+ # - Unbound: a direct pack stream (raw data, typically rc)
90
+ #
91
+ # @param bcj2_coder [Models::CoderInfo] BCJ2 coder
92
+ # @param _compression_coder [Models::CoderInfo] (unused, kept for API compat)
93
+ # @return [Hash] Stream layout specification
94
+ def determine_stream_layout(_bcj2_coder, _compression_coder)
95
+ # Compute composite in/out stream base indices for each coder
96
+ in_bases = []
97
+ out_bases = []
98
+ in_pos = 0
99
+ out_pos = 0
100
+ @folder.coders.each do |coder|
101
+ in_bases << in_pos
102
+ out_bases << out_pos
103
+ in_pos += coder.num_in_streams
104
+ out_pos += coder.num_out_streams
105
+ end
106
+
107
+ # Find the BCJ2 coder index and its input stream base
108
+ bcj2_idx = @folder.coders.index { |c| c.method_id == FilterId::BCJ2 }
109
+ bcj2_in_base = in_bases[bcj2_idx]
110
+
111
+ # BCJ2's 4 input streams: main, call, jump, rc
112
+ bcj2_in_streams = (0...4).map { |i| bcj2_in_base + i }
113
+
114
+ # Build bind map: in_stream -> out_stream
115
+ bind_map = {}
116
+ @folder.bind_pairs.each { |pair| bind_map[pair[0]] = pair[1] }
117
+
118
+ # Build out_stream -> coder_index map
119
+ out_to_coder = {}
120
+ @folder.coders.each_with_index do |coder, ci|
121
+ coder.num_out_streams.times do |j|
122
+ out_to_coder[out_bases[ci] + j] = ci
123
+ end
124
+ end
125
+
126
+ # Map unbound input streams to pack streams using pack_stream_indices
127
+ # pack_stream_indices[i] = unbound_input_stream for pack stream i
128
+ # This mapping is NOT necessarily sorted order!
129
+ unbound_to_pack = {}
130
+ @folder.pack_stream_indices.each_with_index do |input_stream, pack_idx|
131
+ unbound_to_pack[input_stream] = pack_idx
132
+ end
133
+
134
+ # For each BCJ2 input, determine its source
135
+ stream_names = %i[main call jump rc]
136
+ layout = { type: :generic }
137
+
138
+ bcj2_in_streams.each_with_index do |in_stream, i|
139
+ name = stream_names[i]
140
+
141
+ if bind_map.key?(in_stream)
142
+ # Bound: fed by a coder's output
143
+ source_out = bind_map[in_stream]
144
+ source_coder_idx = out_to_coder[source_out]
145
+ source_coder = @folder.coders[source_coder_idx]
146
+
147
+ # Find the source coder's pack stream (its unbound input)
148
+ source_in_base = in_bases[source_coder_idx]
149
+ source_pack_in = (source_in_base...(source_in_base + source_coder.num_in_streams))
150
+ .find do |s|
151
+ unbound_to_pack.key?(s)
152
+ end
153
+ pack_idx = unbound_to_pack[source_pack_in]
154
+
155
+ layout[name] =
156
+ { pack_idx: pack_idx, coder: source_coder,
157
+ unpack_idx: source_out }
158
+ else
159
+ # Unbound: direct pack stream (no decompression)
160
+ pack_idx = unbound_to_pack[in_stream]
161
+ layout[name] = { pack_idx: pack_idx, coder: nil }
162
+ end
163
+ end
164
+
165
+ layout
166
+ end
167
+
168
+ # Read and decompress BCJ2 streams
169
+ #
170
+ # @param layout [Hash] Stream layout specification
171
+ # @return [Hash] Decompressed stream data
172
+ def read_bcj2_streams(layout)
173
+ # Precompute absolute positions for each pack stream
174
+ pack_positions = []
175
+ pos = @pack_pos
176
+ @pack_sizes.each do |size|
177
+ pack_positions << pos
178
+ pos += size
179
+ end
180
+
181
+ streams = {}
182
+
183
+ %i[main call jump rc].each do |stream_name|
184
+ spec = layout[stream_name]
185
+ pack_idx = spec[:pack_idx]
186
+ pack_size = @pack_sizes[pack_idx] || 0
187
+
188
+ # Use absolute position for this pack stream
189
+ abs_pos = pack_positions[pack_idx]
190
+ @archive_io.seek(abs_pos)
191
+ packed_data = @archive_io.read(pack_size)
192
+
193
+ # Decompress if needed
194
+ streams[stream_name] = if spec[:coder]
195
+ unpack_idx = spec[:unpack_idx]
196
+ unpack_size = @folder.unpack_sizes[unpack_idx] if unpack_idx
197
+ decompress_stream(packed_data, spec[:coder], unpack_size)
198
+ else
199
+ # COPY - no decompression needed
200
+ packed_data || "".b
201
+ end
202
+ end
203
+
204
+ streams
205
+ end
206
+
207
+ # Decompress a single stream
208
+ #
209
+ # @param packed_data [String] Compressed data
210
+ # @param coder [Models::CoderInfo] Coder specification
211
+ # @param unpack_size [Integer, nil] Expected decompressed size
212
+ # @return [String] Decompressed data
213
+ def decompress_stream(packed_data, coder, unpack_size = nil)
214
+ return packed_data if coder.nil?
215
+
216
+ algo_sym = CoderChain.algorithm_for_method(coder.method_id)
217
+ return packed_data unless algo_sym
218
+
219
+ algo_class = Omnizip::AlgorithmRegistry.get(algo_sym)
220
+ raise Omnizip::AlgorithmNotFoundError, "Algorithm not found: #{algo_sym}" unless algo_class
221
+
222
+ # Build decoder options
223
+ options = build_decoder_options(coder, algo_sym)
224
+
225
+ # Decompress
226
+ input_io = StringIO.new(packed_data)
227
+ output_io = StringIO.new
228
+ output_io.set_encoding("BINARY")
229
+
230
+ decoder = algo_class.new(options)
231
+
232
+ # Use provided unpack size or estimate
233
+ unpack_size ||= packed_data.bytesize * 10
234
+
235
+ decoder.decompress(input_io, output_io, size: unpack_size)
236
+ output_io.string
237
+ end
238
+
239
+ # Build decoder options from coder properties
240
+ #
241
+ # @param coder [Models::CoderInfo] Coder with properties
242
+ # @param algo_sym [Symbol] Algorithm symbol
243
+ # @return [Hash] Decoder options
244
+ def build_decoder_options(coder, algo_sym)
245
+ options = {}
246
+ properties = coder.properties
247
+
248
+ return options if properties.nil? || properties.empty?
249
+
250
+ case algo_sym
251
+ when :lzma2
252
+ prop_byte = properties.getbyte(0)
253
+ dict_size = Omnizip::Algorithms::LZMA2::Properties.decode_dict_size(prop_byte)
254
+ options[:raw_mode] = true
255
+ options[:dict_size] = dict_size
256
+ when :lzma
257
+ if properties.bytesize >= 5
258
+ props_byte = properties.getbyte(0)
259
+ dict_size = properties[1, 4].unpack1("V")
260
+ options[:lzma2_mode] = true
261
+ options[:lc] = props_byte % 9
262
+ remainder = props_byte / 9
263
+ options[:lp] = remainder % 5
264
+ options[:pb] = remainder / 5
265
+ options[:dict_size] = dict_size
266
+ end
267
+ end
268
+
269
+ options
270
+ end
271
+ end
272
+ end
273
+ end
274
+ end
@@ -0,0 +1,169 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Formats
5
+ module SevenZip
6
+ # Builds coder chains from .7z folder specifications
7
+ # Maps method IDs to algorithms and filters, reconstructing the
8
+ # decompression pipeline
9
+ class CoderChain
10
+ include Omnizip::Formats::SevenZip::Constants
11
+
12
+ # Build coder chain from folder specification
13
+ #
14
+ # @param folder [Models::Folder] Folder specification
15
+ # @return [Hash] Coder chain configuration
16
+ # @raise [RuntimeError] if unsupported method encountered
17
+ def self.build_from_folder(folder)
18
+ return nil if folder.coders.empty?
19
+
20
+ # Find the compression method (not a filter) among coders
21
+ # Filters like BCJ, BCJ2 have specific method IDs
22
+ main_coder = find_compression_coder(folder.coders)
23
+ raise Omnizip::InvalidArchiveError, "No compression method found in folder" unless main_coder
24
+
25
+ algorithm = algorithm_for_method(main_coder.method_id)
26
+
27
+ # Check for filters (all coders except the compression method)
28
+ filters = []
29
+ folder.coders.each do |coder|
30
+ next if coder == main_coder
31
+
32
+ filter = filter_for_method(coder.method_id)
33
+ filters << filter if filter
34
+ end
35
+
36
+ {
37
+ algorithm: algorithm,
38
+ filters: filters,
39
+ properties: main_coder.properties,
40
+ unpack_size: folder.unpack_sizes.last,
41
+ }
42
+ end
43
+
44
+ # Find the compression coder among all coders
45
+ #
46
+ # @param coders [Array<Models::CoderInfo>] All coders in the folder
47
+ # @return [Models::CoderInfo, nil] The compression coder or nil
48
+ def self.find_compression_coder(coders)
49
+ # Try to find a known compression method
50
+ coders.each do |coder|
51
+ case coder.method_id
52
+ when MethodId::LZMA, MethodId::LZMA2, MethodId::BZIP2,
53
+ MethodId::DEFLATE, MethodId::DEFLATE64, MethodId::PPMD,
54
+ MethodId::COPY
55
+ return coder
56
+ end
57
+ end
58
+
59
+ # Fall back to last coder if no known compression method found
60
+ coders.last
61
+ end
62
+
63
+ # Map method ID to algorithm
64
+ #
65
+ # @param method_id [Integer] Method ID from .7z file
66
+ # @return [Symbol] Algorithm identifier
67
+ # @raise [RuntimeError] if method not supported
68
+ def self.algorithm_for_method(method_id)
69
+ case method_id
70
+ when MethodId::COPY
71
+ nil # No decompression needed
72
+ when MethodId::LZMA
73
+ :lzma
74
+ when MethodId::LZMA2
75
+ :lzma2
76
+ when MethodId::PPMD
77
+ :ppmd7
78
+ when MethodId::BZIP2
79
+ :bzip2
80
+ when MethodId::DEFLATE
81
+ :deflate
82
+ when MethodId::DEFLATE64
83
+ :deflate64
84
+ else
85
+ raise Omnizip::UnsupportedFormatError, "Unsupported compression method: " \
86
+ "0x#{method_id.to_s(16)}"
87
+ end
88
+ end
89
+
90
+ # Map method ID to filter
91
+ #
92
+ # @param method_id [Integer] Method ID from .7z file
93
+ # @return [Symbol, nil] Filter identifier or nil
94
+ def self.filter_for_method(method_id)
95
+ case method_id
96
+ when FilterId::BCJ_X86
97
+ :bcj_x86
98
+ when FilterId::BCJ_PPC
99
+ :bcj_ppc
100
+ when FilterId::BCJ_IA64
101
+ :bcj_ia64
102
+ when FilterId::BCJ_ARM
103
+ :bcj_arm
104
+ when FilterId::BCJ_ARMT
105
+ :bcj_armt
106
+ when FilterId::BCJ_SPARC
107
+ :bcj_sparc
108
+ when FilterId::ARM64
109
+ :bcj_arm64
110
+ when FilterId::DELTA
111
+ :delta
112
+ when FilterId::BCJ2
113
+ :bcj2
114
+ end
115
+ end
116
+
117
+ # Create decompressor for coder chain
118
+ #
119
+ # @param chain_config [Hash] Chain configuration
120
+ # @param input_io [IO] Input stream
121
+ # @return [Object] Decompressor instance
122
+ def self.create_decompressor(chain_config, input_io)
123
+ return nil unless chain_config
124
+ return input_io unless chain_config[:algorithm]
125
+
126
+ # Get algorithm
127
+ algo_class = AlgorithmRegistry.get(chain_config[:algorithm])
128
+ unless algo_class
129
+ raise Omnizip::AlgorithmNotFoundError, "Algorithm not found: #{chain_config[:algorithm]}"
130
+ end
131
+
132
+ # Create algorithm instance
133
+ decompressor = algo_class.new
134
+ # Pass properties if algorithm supports them
135
+ # Some algorithms (LZMA2) need properties
136
+ if chain_config[:properties] && !chain_config[:properties].empty? && decompressor.is_a?(Omnizip::Algorithms::LZMA2)
137
+ decompressor.properties = chain_config[:properties]
138
+ end
139
+
140
+ # Apply filters if present
141
+ if chain_config[:filters] && !chain_config[:filters].empty?
142
+ # Build filter pipeline
143
+ pipeline = FilterPipeline.new
144
+ chain_config[:filters].each do |filter_sym|
145
+ filter_class = FilterRegistry.get(filter_sym)
146
+ raise Omnizip::UnknownFilterError, "Filter not found: #{filter_sym}" unless filter_class
147
+
148
+ pipeline.add_filter(filter_class.new)
149
+ end
150
+
151
+ # Return composite: input -> algorithm -> filters
152
+ {
153
+ decompressor: decompressor,
154
+ pipeline: pipeline,
155
+ input: input_io,
156
+ }
157
+ else
158
+ # Just algorithm
159
+ {
160
+ decompressor: decompressor,
161
+ pipeline: nil,
162
+ input: input_io,
163
+ }
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Formats
5
+ module SevenZip
6
+ # Constants for .7z archive format
7
+ # Based on 7-Zip specification
8
+ module Constants
9
+ # Archive signature and header
10
+ SIGNATURE = "7z\xBC\xAF\x27\x1C".b.freeze
11
+ SIGNATURE_SIZE = 6
12
+ START_HEADER_SIZE = 32 # 0x20
13
+ MAJOR_VERSION = 0
14
+ MINOR_VERSION = 4
15
+
16
+ # Property IDs for .7z format structure
17
+ module PropertyId
18
+ K_END = 0x00
19
+ HEADER = 0x01
20
+ ARCHIVE_PROPERTIES = 0x02
21
+ ADDITIONAL_STREAMS_INFO = 0x03
22
+ MAIN_STREAMS_INFO = 0x04
23
+ FILES_INFO = 0x05
24
+ PACK_INFO = 0x06
25
+ UNPACK_INFO = 0x07
26
+ SUBSTREAMS_INFO = 0x08
27
+ SIZE = 0x09
28
+ CRC = 0x0A
29
+ FOLDER = 0x0B
30
+ CODERS_UNPACK_SIZE = 0x0C
31
+ NUM_UNPACK_STREAM = 0x0D
32
+ EMPTY_STREAM = 0x0E
33
+ EMPTY_FILE = 0x0F
34
+ ANTI = 0x10
35
+ NAME = 0x11
36
+ CTIME = 0x12
37
+ ATIME = 0x13
38
+ MTIME = 0x14
39
+ WIN_ATTRIB = 0x15
40
+ COMMENT = 0x16
41
+ ENCODED_HEADER = 0x17
42
+ START_POS = 0x18
43
+ DUMMY = 0x19
44
+ end
45
+
46
+ # Method IDs for compression algorithms
47
+ module MethodId
48
+ # Compression methods
49
+ COPY = 0x00
50
+ LZMA = 0x030101
51
+ LZMA2 = 0x21
52
+ PPMD = 0x030401
53
+ BZIP2 = 0x040202
54
+ DEFLATE = 0x040108
55
+ DEFLATE64 = 0x040109
56
+
57
+ # Crypto methods
58
+ AES = 0x06F10701
59
+
60
+ def self.name(id)
61
+ case id
62
+ when COPY then "Copy"
63
+ when LZMA then "LZMA"
64
+ when LZMA2 then "LZMA2"
65
+ when PPMD then "PPMd"
66
+ when BZIP2 then "BZip2"
67
+ when DEFLATE then "Deflate"
68
+ when DEFLATE64 then "Deflate64"
69
+ when AES then "AES256"
70
+ else "Unknown(0x#{id.to_s(16)})"
71
+ end
72
+ end
73
+ end
74
+
75
+ # Filter IDs
76
+ module FilterId
77
+ # BCJ filters for executable files
78
+ BCJ_X86 = 0x03030103
79
+ BCJ_PPC = 0x03030205
80
+ BCJ_IA64 = 0x03030401
81
+ BCJ_ARM = 0x03030501
82
+ BCJ_ARMT = 0x03030701
83
+ BCJ_SPARC = 0x03030805
84
+ ARM64 = 0x03030601
85
+
86
+ # BCJ2 filter
87
+ BCJ2 = 0x0303011B
88
+
89
+ # Swap filters for byte order conversion
90
+ SWAP2 = 0x03030204
91
+ SWAP4 = 0x03030208
92
+
93
+ # Delta filter
94
+ DELTA = 0x03
95
+
96
+ def self.name(id)
97
+ case id
98
+ when BCJ_X86 then "BCJ-x86"
99
+ when BCJ_PPC then "BCJ-PPC"
100
+ when BCJ_IA64 then "BCJ-IA64"
101
+ when BCJ_ARM then "BCJ-ARM"
102
+ when BCJ_ARMT then "BCJ-ARMT"
103
+ when BCJ_SPARC then "BCJ-SPARC"
104
+ when DELTA then "Delta"
105
+ when ARM64 then "BCJ-ARM64"
106
+ when BCJ2 then "BCJ2"
107
+ when SWAP2 then "Swap2"
108
+ when SWAP4 then "Swap4"
109
+ else "Unknown(0x#{id.to_s(16)})"
110
+ end
111
+ end
112
+
113
+ def self.bcj_filter?(id)
114
+ [BCJ_X86, BCJ_PPC, BCJ_IA64, BCJ_ARM, BCJ_ARMT, BCJ_SPARC,
115
+ ARM64].include?(id)
116
+ end
117
+ end
118
+
119
+ # Maximum limits
120
+ MAX_NUM_CODERS = 4
121
+ MAX_NUM_BONDS = 3
122
+ MAX_NUM_PACK_STREAMS = 4
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Formats
5
+ module SevenZip
6
+ # Handles 7-Zip encoded headers
7
+ #
8
+ # 7-Zip can compress the Next Header metadata with LZMA2 to save space.
9
+ # This module provides functionality to encode and decode headers.
10
+ module EncodedHeader
11
+ include Omnizip::Formats::SevenZip::Constants
12
+
13
+ module_function
14
+
15
+ # Encode next header with LZMA2 compression
16
+ #
17
+ # @param header_data [String] Uncompressed header data
18
+ # @return [String] Encoded header property with compressed data
19
+ def encode(header_data)
20
+ # Compress header with LZMA2
21
+ compressed = compress_header(header_data)
22
+
23
+ # Build encoded header property
24
+ encoded = String.new(encoding: "BINARY")
25
+ encoded << [PropertyId::ENCODED_HEADER].pack("C")
26
+
27
+ # Write pack info for compressed header
28
+ encoded << [PropertyId::PACK_INFO].pack("C")
29
+ encoded << encode_uint64(0) # Pack position
30
+ encoded << encode_uint64(1) # Number of pack streams
31
+
32
+ # Write size
33
+ encoded << [PropertyId::SIZE].pack("C")
34
+ encoded << encode_uint64(compressed.bytesize)
35
+
36
+ encoded << [PropertyId::K_END].pack("C")
37
+
38
+ # Write coder info (LZMA2)
39
+ encoded << [PropertyId::UNPACK_INFO].pack("C")
40
+ encoded << [PropertyId::FOLDER].pack("C")
41
+ encoded << encode_uint64(1) # Number of folders
42
+ encoded << [0].pack("C") # External flag (0 = inline)
43
+
44
+ # Number of coders
45
+ encoded << encode_uint64(1)
46
+
47
+ # Coder info for LZMA2
48
+ # Method ID: LZMA2 = 0x21
49
+ encoded << [1].pack("C") # Main byte (1 byte for ID, no properties)
50
+ encoded << [0x21].pack("C") # LZMA2 method ID
51
+
52
+ # Unpack size
53
+ encoded << [PropertyId::CODERS_UNPACK_SIZE].pack("C")
54
+ encoded << encode_uint64(header_data.bytesize)
55
+
56
+ encoded << [PropertyId::K_END].pack("C")
57
+
58
+ # Append compressed data
59
+ encoded << compressed
60
+
61
+ encoded
62
+ end
63
+
64
+ # Compress header data with LZMA2
65
+ #
66
+ # @param header_data [String] Uncompressed header
67
+ # @return [String] Compressed header
68
+ def compress_header(header_data)
69
+ # Use 7-Zip SDK LZMA2 encoder for 7-Zip format
70
+ encoder = Omnizip::Implementations::SevenZip::LZMA2::Encoder.new(
71
+ dict_size: 4096, # Small dictionary for headers
72
+ lc: 3,
73
+ lp: 0,
74
+ pb: 2,
75
+ standalone: false, # No property byte
76
+ )
77
+
78
+ encoder.encode(header_data)
79
+ end
80
+
81
+ # Encode unsigned 64-bit integer in 7-Zip variable-length format
82
+ #
83
+ # @param value [Integer] Value to encode
84
+ # @return [String] Encoded bytes
85
+ def encode_uint64(value)
86
+ return [value].pack("C") if value < 0x80
87
+
88
+ result = String.new(encoding: "BINARY")
89
+ shift = 0
90
+
91
+ loop do
92
+ byte = value & 0x7F
93
+ value >>= 7
94
+
95
+ if value.zero?
96
+ result << [byte].pack("C")
97
+ break
98
+ else
99
+ result << [byte | 0x80].pack("C")
100
+ end
101
+
102
+ shift += 7
103
+ end
104
+
105
+ result
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end