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,224 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2025 Ribose Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a
6
+ # copy of this software and associated documentation files (the "Software"),
7
+ # to deal in the Software without restriction, including without limitation
8
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
+ # and/or sell copies of the Software, and to permit persons to whom the
10
+ # Software is furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
+ # DEALINGS IN THE SOFTWARE.
22
+
23
+ module Omnizip
24
+ module Algorithms
25
+ class LZMA < Algorithm
26
+ # XZ Utils-compatible match finder adapter
27
+ #
28
+ # Wraps existing MatchFinder to provide XZ Utils interface with:
29
+ # - Cursor-based position tracking
30
+ # - Multiple match finding (not just longest)
31
+ # - Skip and lookahead operations
32
+ #
33
+ # Based on: xz/src/liblzma/lz/lz_encoder_mf.c
34
+ class XzMatchFinderAdapter
35
+ include Constants
36
+
37
+ # Match structure matching XZ Utils
38
+ Match = Struct.new(:len, :dist, keyword_init: true) do
39
+ def to_s
40
+ "Match(len=#{len}, dist=#{dist})"
41
+ end
42
+ end
43
+
44
+ attr_reader :matches, :longest_len, :pos
45
+
46
+ # Initialize match finder adapter
47
+ #
48
+ # @param data [String, Array<Integer>] Input data
49
+ # @param dict_size [Integer] Dictionary size (default 8MB for XZ)
50
+ # @param nice_len [Integer] Nice match length (default 32)
51
+ def initialize(data, dict_size: 1 << 23, nice_len: 32)
52
+ @data = data.is_a?(String) ? data.bytes : data
53
+ @pos = 0
54
+ @dict_size = dict_size
55
+ @nice_len = nice_len
56
+
57
+ # Internal state
58
+ @matches = []
59
+ @longest_len = 0
60
+
61
+ # Hash table for match finding
62
+ @hash_table = {}
63
+ end
64
+
65
+ # Find all matches at current position
66
+ #
67
+ # Finds multiple matches of different lengths, not just the longest.
68
+ # Results stored in @matches array, longest length in @longest_len.
69
+ #
70
+ # @return [Integer] Longest match length (0 if no matches)
71
+ def find_matches
72
+ @matches.clear
73
+ @longest_len = 0
74
+
75
+ return 0 if @pos >= @data.size
76
+ return 0 if available < MATCH_LEN_MIN
77
+
78
+ # CRITICAL: Don't produce matches until there's enough data for decoder
79
+ # The decoder validates: dict_full > distance
80
+ # Where dict_full = decoded_byte_count (starting from 0)
81
+ # So for distance=N to be valid, we need at least N+1 bytes decoded
82
+ # We're at position @pos (0-based), so @pos bytes have been processed
83
+ # For distance=1 match: need @pos >= 2 (so decoder has dict_full=2)
84
+ # For distance=N match: need @pos >= N+1
85
+ # Simple check: Don't produce matches until @pos >= 2
86
+ return 0 if @pos < 2
87
+
88
+ # Find matches using hash chains
89
+ hash_val = compute_hash
90
+ positions = @hash_table[hash_val] || []
91
+
92
+ # Track best matches at each length
93
+ best_distances = {}
94
+
95
+ positions.reverse_each do |prev_pos|
96
+ distance = @pos - prev_pos
97
+ break if distance > @dict_size
98
+
99
+ # Skip self-matching (can happen when lookahead searches same position twice)
100
+ next if distance.zero?
101
+
102
+ match_len = calculate_match_length(prev_pos)
103
+ next if match_len < MATCH_LEN_MIN
104
+
105
+ # Keep best (shortest) distance for each length
106
+ if !best_distances[match_len] || distance < best_distances[match_len]
107
+ best_distances[match_len] = distance
108
+ end
109
+
110
+ # Update longest
111
+ @longest_len = match_len if match_len > @longest_len
112
+
113
+ # Stop if we found nice length
114
+ break if match_len >= @nice_len
115
+ end
116
+
117
+ # Convert to matches array (sorted by length)
118
+ best_distances.keys.sort.each do |len|
119
+ @matches << Match.new(len: len, dist: best_distances[len])
120
+ end
121
+
122
+ # Update hash table
123
+ update_hash(hash_val, @pos)
124
+
125
+ @longest_len
126
+ end
127
+
128
+ # Skip n bytes without finding matches
129
+ #
130
+ # Advances position and updates hash tables but doesn't search for matches.
131
+ # Used for rep matches where we already know what to encode.
132
+ #
133
+ # @param n [Integer] Number of bytes to skip
134
+ def skip(n)
135
+ n.times do
136
+ return if @pos >= @data.size
137
+
138
+ hash_val = compute_hash
139
+ update_hash(hash_val, @pos)
140
+ @pos += 1
141
+ end
142
+ end
143
+
144
+ # Move position forward by one byte
145
+ def move_pos
146
+ @pos += 1
147
+ end
148
+
149
+ # Bytes available from current position
150
+ #
151
+ # @return [Integer] Number of bytes remaining
152
+ def available
153
+ @data.size - @pos
154
+ end
155
+
156
+ # Get current byte at position
157
+ #
158
+ # @return [Integer, nil] Byte value or nil if at end
159
+ def current_byte
160
+ return nil if @pos >= @data.size
161
+
162
+ @data[@pos]
163
+ end
164
+
165
+ # Get byte at offset from current position
166
+ #
167
+ # @param offset [Integer] Offset from current position (can be negative)
168
+ # @return [Integer] Byte value (0 if out of bounds)
169
+ def get_byte(offset)
170
+ pos = @pos + offset
171
+ return 0 if pos.negative? || pos >= @data.size
172
+
173
+ @data[pos]
174
+ end
175
+
176
+ # Reset match finder to beginning
177
+ def reset
178
+ @pos = 0
179
+ @matches.clear
180
+ @longest_len = 0
181
+ @hash_table.clear
182
+ end
183
+
184
+ private
185
+
186
+ # Compute hash value for sequence at current position
187
+ #
188
+ # @return [Integer] Hash value
189
+ def compute_hash
190
+ return 0 if @pos + 2 >= @data.size
191
+
192
+ (@data[@pos] << 16) ^ (@data[@pos + 1] << 8) ^ @data[@pos + 2]
193
+ end
194
+
195
+ # Calculate match length between current position and previous position
196
+ #
197
+ # @param prev_pos [Integer] Previous position to compare against
198
+ # @return [Integer] Length of match
199
+ def calculate_match_length(prev_pos)
200
+ max_len = [available, @nice_len].min
201
+ length = 0
202
+
203
+ while length < max_len && @data[@pos + length] == @data[prev_pos + length]
204
+ length += 1
205
+ end
206
+
207
+ length
208
+ end
209
+
210
+ # Update hash table with position
211
+ #
212
+ # @param hash_val [Integer] Hash value
213
+ # @param pos [Integer] Position to add
214
+ def update_hash(hash_val, pos)
215
+ @hash_table[hash_val] ||= []
216
+ @hash_table[hash_val] << pos
217
+
218
+ # Keep hash chains from growing too large
219
+ @hash_table[hash_val].shift if @hash_table[hash_val].size > 1024
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,167 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Algorithms
5
+ class LZMA < Algorithm
6
+ # XZ Utils-compatible price calculator
7
+ #
8
+ # Calculates the cost (in price units) of encoding symbols using
9
+ # probability models. Prices are based on logarithmic probabilities:
10
+ # price = -log2(probability) * scale_factor
11
+ #
12
+ # Uses precomputed tables for efficiency, matching XZ Utils exactly.
13
+ #
14
+ # Based on: xz/src/liblzma/rangecoder/price.h
15
+ class XzPriceCalculator
16
+ include Constants
17
+
18
+ # Price scale factor (matches XZ Utils)
19
+ PRICE_SHIFT_BITS = 4
20
+ PRICE_SCALE = 1 << PRICE_SHIFT_BITS
21
+
22
+ # BIT_MODEL_TOTAL = 2^11 = 2048 (from Constants, but define locally for clarity)
23
+ BIT_MODEL_TOTAL_LOCAL = 0x800
24
+ BIT_MODEL_TOTAL_BITS = 11
25
+
26
+ # Number of entries in price table
27
+ PRICE_TABLE_SIZE = BIT_MODEL_TOTAL_LOCAL >> PRICE_SHIFT_BITS
28
+
29
+ class << self
30
+ # Calculate price for encoding a single bit
31
+ #
32
+ # @param prob [Integer] Probability model value (0..BIT_MODEL_TOTAL)
33
+ # @param bit [Integer] Bit value (0 or 1)
34
+ # @return [Integer] Price in price units
35
+ def bit_price(prob, bit)
36
+ if bit.zero?
37
+ # Price for encoding 0
38
+ PRICE_TABLE[prob >> PRICE_SHIFT_BITS]
39
+ else
40
+ # Price for encoding 1
41
+ PRICE_TABLE[(BIT_MODEL_TOTAL_LOCAL - prob) >> PRICE_SHIFT_BITS]
42
+ end
43
+ end
44
+
45
+ # Calculate price for encoding a symbol using bit tree
46
+ #
47
+ # A bit tree encodes a symbol by encoding its bits from MSB to LSB,
48
+ # using probability models indexed by the partial symbol value.
49
+ #
50
+ # @param probs [Array<BitModel>] Probability models for tree
51
+ # @param num_bits [Integer] Number of bits in symbol
52
+ # @param symbol [Integer] Symbol value to encode
53
+ # @return [Integer] Total price in price units
54
+ def bittree_price(probs, num_bits, symbol)
55
+ price = 0
56
+ symbol |= (1 << num_bits) # Add sentinel bit
57
+
58
+ # Encode bits from MSB to LSB
59
+ (num_bits - 1).downto(0) do |i|
60
+ bit = (symbol >> i) & 1
61
+ model_idx = symbol >> (i + 1)
62
+ price += bit_price(probs[model_idx].probability, bit)
63
+ end
64
+
65
+ price
66
+ end
67
+
68
+ # Calculate price for encoding a symbol using reverse bit tree
69
+ #
70
+ # A reverse bit tree encodes a symbol by encoding its bits from
71
+ # LSB to MSB, used for distance encoding.
72
+ #
73
+ # @param probs [Array<BitModel>] Probability models for tree
74
+ # @param num_bits [Integer] Number of bits in symbol
75
+ # @param symbol [Integer] Symbol value to encode
76
+ # @return [Integer] Total price in price units
77
+ def bittree_reverse_price(probs, num_bits, symbol)
78
+ price = 0
79
+ model_idx = 1
80
+
81
+ # Encode bits from LSB to MSB
82
+ num_bits.times do |i|
83
+ bit = (symbol >> i) & 1
84
+ price += bit_price(probs[model_idx].probability, bit)
85
+ model_idx = (model_idx << 1) | bit
86
+ end
87
+
88
+ price
89
+ end
90
+
91
+ # Calculate price for direct bits (uniform distribution)
92
+ #
93
+ # Direct bits have no probability model, each bit costs the same.
94
+ #
95
+ # @param num_bits [Integer] Number of direct bits
96
+ # @return [Integer] Total price in price units
97
+ def direct_price(num_bits)
98
+ # Each direct bit costs 64 units (price of 0.5 probability)
99
+ num_bits << (PRICE_SHIFT_BITS + 2)
100
+ end
101
+
102
+ # Precompute logarithmic price table using Math.log2
103
+ #
104
+ # Generates a table mapping probabilities to prices using the formula:
105
+ # price[i] = -log2(i / BIT_MODEL_TOTAL) * PRICE_SCALE
106
+ #
107
+ # @return [Array<Integer>] Precomputed price table
108
+ def precompute_price_table
109
+ table = Array.new(PRICE_TABLE_SIZE)
110
+
111
+ PRICE_TABLE_SIZE.times do |i|
112
+ if i.zero?
113
+ # Handle zero probability case (maximum price)
114
+ table[i] = 15 << PRICE_SHIFT_BITS
115
+ else
116
+ # Reconstruct probability from table index
117
+ prob = (i << PRICE_SHIFT_BITS) + (PRICE_SCALE >> 1)
118
+ probability = prob.to_f / BIT_MODEL_TOTAL_LOCAL
119
+
120
+ # price = -log2(probability) * PRICE_SCALE
121
+ price = (-Math.log2(probability) * PRICE_SCALE).round
122
+ table[i] = price
123
+ end
124
+ end
125
+
126
+ table
127
+ end
128
+ end
129
+
130
+ # Precomputed logarithmic price table
131
+ # Each entry represents -log2(i/BIT_MODEL_TOTAL) * PRICE_SCALE
132
+ PRICE_TABLE = precompute_price_table.freeze
133
+
134
+ # Instance methods for convenience
135
+
136
+ # @param prob [Integer] Probability value
137
+ # @param bit [Integer] Bit value
138
+ # @return [Integer] Price
139
+ def bit_price(prob, bit)
140
+ self.class.bit_price(prob, bit)
141
+ end
142
+
143
+ # @param probs [Array<BitModel>] Probability models
144
+ # @param num_bits [Integer] Number of bits
145
+ # @param symbol [Integer] Symbol value
146
+ # @return [Integer] Price
147
+ def bittree_price(probs, num_bits, symbol)
148
+ self.class.bittree_price(probs, num_bits, symbol)
149
+ end
150
+
151
+ # @param probs [Array<BitModel>] Probability models
152
+ # @param num_bits [Integer] Number of bits
153
+ # @param symbol [Integer] Symbol value
154
+ # @return [Integer] Price
155
+ def bittree_reverse_price(probs, num_bits, symbol)
156
+ self.class.bittree_reverse_price(probs, num_bits, symbol)
157
+ end
158
+
159
+ # @param num_bits [Integer] Number of direct bits
160
+ # @return [Integer] Price
161
+ def direct_price(num_bits)
162
+ self.class.direct_price(num_bits)
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,258 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Algorithms
5
+ class LZMA < Algorithm
6
+ # XZ Utils-compatible probability models
7
+ #
8
+ # Organizes all probability models used by LZMA encoder, matching
9
+ # XZ Utils structure exactly. All models start at probability 1024
10
+ # (BIT_MODEL_TOTAL / 2 = 0.5 probability).
11
+ #
12
+ # Uses XzBufferedRangeEncoder::Probability for mutable inline updates.
13
+ #
14
+ # Based on: xz/src/liblzma/lzma/lzma_encoder_private.h
15
+ class XzProbabilityModels
16
+ include Constants
17
+
18
+ # Literal context models
19
+ attr_reader :literal
20
+
21
+ # Match type models
22
+ attr_reader :is_match, :is_rep, :is_rep0, :is_rep1, :is_rep2
23
+ attr_reader :is_rep0_long
24
+
25
+ # Distance models
26
+ attr_reader :dist_slot, :dist_special, :dist_align
27
+
28
+ # Length encoders
29
+ attr_reader :match_len_encoder, :rep_len_encoder
30
+
31
+ # Initialize all probability models
32
+ #
33
+ # @param lc [Integer] Number of literal context bits (0-8)
34
+ # @param lp [Integer] Number of literal position bits (0-4)
35
+ # @param pb [Integer] Number of position bits (0-4)
36
+ def initialize(lc, lp, pb)
37
+ @lc = lc
38
+ @lp = lp
39
+ @pb = pb
40
+
41
+ init_literal_models(lc, lp)
42
+ init_match_models(pb)
43
+ init_distance_models
44
+ init_length_encoders(pb)
45
+ end
46
+
47
+ # Reset all probability models to initial state
48
+ def reset
49
+ reset_literal_models
50
+ reset_match_models
51
+ reset_distance_models
52
+ reset_length_encoders
53
+ end
54
+
55
+ private
56
+
57
+ # Initialize literal context models
58
+ # Ported from XZ Utils literal_init() in lzma_common.h
59
+ # Size: LITERAL_CODER_SIZE << (lc + lp) = 0x300 * (1 << (lc + lp))
60
+ # This is a FLAT array, not 2D, to match XZ Utils structure
61
+ def init_literal_models(lc, lp)
62
+ coders = 0x300 << (lc + lp)
63
+ @literal = Array.new(coders) { XzBufferedRangeEncoder::Probability.new }
64
+ end
65
+
66
+ # Initialize match type models
67
+ def init_match_models(pb)
68
+ num_pos_states = 1 << pb
69
+
70
+ # is_match[state][pos_state]
71
+ @is_match = Array.new(NUM_STATES) do
72
+ Array.new(num_pos_states) { XzBufferedRangeEncoder::Probability.new }
73
+ end
74
+
75
+ # is_rep[state]
76
+ @is_rep = Array.new(NUM_STATES) { XzBufferedRangeEncoder::Probability.new }
77
+
78
+ # is_rep0[state]
79
+ @is_rep0 = Array.new(NUM_STATES) { XzBufferedRangeEncoder::Probability.new }
80
+
81
+ # is_rep1[state]
82
+ @is_rep1 = Array.new(NUM_STATES) { XzBufferedRangeEncoder::Probability.new }
83
+
84
+ # is_rep2[state]
85
+ @is_rep2 = Array.new(NUM_STATES) { XzBufferedRangeEncoder::Probability.new }
86
+
87
+ # is_rep0_long[state][pos_state]
88
+ @is_rep0_long = Array.new(NUM_STATES) do
89
+ Array.new(num_pos_states) { XzBufferedRangeEncoder::Probability.new }
90
+ end
91
+ end
92
+
93
+ # Initialize distance models
94
+ def init_distance_models
95
+ # dist_slot[len_to_pos_state][dist_slot]
96
+ # len_to_pos_state: 0-3 (maps match length to state)
97
+ # dist_slot: 0-63 (6-bit distance slot)
98
+ @dist_slot = Array.new(NUM_LEN_TO_POS_STATES) do
99
+ Array.new(NUM_DIST_SLOTS) { XzBufferedRangeEncoder::Probability.new }
100
+ end
101
+
102
+ # dist_special[dist - 4] for slots 4-13 (160 models)
103
+ # Each slot has varying number of bits encoded with models
104
+ num_dist_special = NUM_FULL_DISTANCES - START_POS_MODEL_INDEX
105
+ @dist_special = Array.new(num_dist_special) { XzBufferedRangeEncoder::Probability.new }
106
+
107
+ # dist_align[align_bit] for alignment (16 models)
108
+ @dist_align = Array.new(DIST_ALIGN_SIZE) { XzBufferedRangeEncoder::Probability.new }
109
+ end
110
+
111
+ # Initialize length encoders
112
+ def init_length_encoders(pb)
113
+ @match_len_encoder = LengthEncoder.new(pb)
114
+ @rep_len_encoder = LengthEncoder.new(pb)
115
+ end
116
+
117
+ # Reset methods
118
+ def reset_literal_models
119
+ @literal.each { |prob| prob.value = BIT_MODEL_TOTAL >> 1 }
120
+ end
121
+
122
+ def reset_match_models
123
+ @is_match.each do |pos_states|
124
+ pos_states.each do |prob|
125
+ prob.value = BIT_MODEL_TOTAL >> 1
126
+ end
127
+ end
128
+ @is_rep.each { |prob| prob.value = BIT_MODEL_TOTAL >> 1 }
129
+ @is_rep0.each { |prob| prob.value = BIT_MODEL_TOTAL >> 1 }
130
+ @is_rep1.each { |prob| prob.value = BIT_MODEL_TOTAL >> 1 }
131
+ @is_rep2.each { |prob| prob.value = BIT_MODEL_TOTAL >> 1 }
132
+ @is_rep0_long.each do |pos_states|
133
+ pos_states.each do |prob|
134
+ prob.value = BIT_MODEL_TOTAL >> 1
135
+ end
136
+ end
137
+ end
138
+
139
+ def reset_distance_models
140
+ @dist_slot.each do |slots|
141
+ slots.each do |prob|
142
+ prob.value = BIT_MODEL_TOTAL >> 1
143
+ end
144
+ end
145
+ @dist_special.each { |prob| prob.value = BIT_MODEL_TOTAL >> 1 }
146
+ @dist_align.each { |prob| prob.value = BIT_MODEL_TOTAL >> 1 }
147
+ end
148
+
149
+ def reset_length_encoders
150
+ @match_len_encoder.reset
151
+ @rep_len_encoder.reset
152
+ end
153
+ end
154
+
155
+ # Length encoder with probability models and price tables
156
+ #
157
+ # Encodes match lengths using a 3-tier structure:
158
+ # - Low: lengths 2-9 (choice=0, 3 bits)
159
+ # - Mid: lengths 10-17 (choice=1, choice2=0, 3 bits)
160
+ # - High: lengths 18-273 (choice=1, choice2=1, 8 bits)
161
+ class LengthEncoder
162
+ include Constants
163
+
164
+ attr_reader :choice, :choice2, :low, :mid, :high, :prices, :counters
165
+
166
+ # Initialize length encoder
167
+ #
168
+ # @param pb [Integer] Number of position bits
169
+ def initialize(pb)
170
+ @pb = pb
171
+ @num_pos_states = 1 << pb
172
+
173
+ # Choice bits
174
+ @choice = XzBufferedRangeEncoder::Probability.new
175
+ @choice2 = XzBufferedRangeEncoder::Probability.new
176
+
177
+ # Low lengths (per position state)
178
+ @low = Array.new(@num_pos_states) do
179
+ Array.new(LEN_LOW_SYMBOLS) { XzBufferedRangeEncoder::Probability.new }
180
+ end
181
+
182
+ # Mid lengths (per position state)
183
+ @mid = Array.new(@num_pos_states) do
184
+ Array.new(LEN_MID_SYMBOLS) { XzBufferedRangeEncoder::Probability.new }
185
+ end
186
+
187
+ # High lengths (shared across position states)
188
+ @high = Array.new(LEN_HIGH_SYMBOLS) { XzBufferedRangeEncoder::Probability.new }
189
+
190
+ # Price tables (updated incrementally)
191
+ # prices[pos_state][length - MATCH_LEN_MIN]
192
+ @prices = Array.new(@num_pos_states) do
193
+ Array.new(MATCH_LEN_MAX - MATCH_LEN_MIN + 1, 0)
194
+ end
195
+
196
+ # Counters for price table updates
197
+ @counters = Array.new(@num_pos_states, 0)
198
+ end
199
+
200
+ # Reset all models to initial state
201
+ def reset
202
+ @choice.value = BIT_MODEL_TOTAL >> 1
203
+ @choice2.value = BIT_MODEL_TOTAL >> 1
204
+ @low.each do |models|
205
+ models.each do |prob|
206
+ prob.value = BIT_MODEL_TOTAL >> 1
207
+ end
208
+ end
209
+ @mid.each do |models|
210
+ models.each do |prob|
211
+ prob.value = BIT_MODEL_TOTAL >> 1
212
+ end
213
+ end
214
+ @high.each { |prob| prob.value = BIT_MODEL_TOTAL >> 1 }
215
+
216
+ # Reset price tables
217
+ @prices.each { |pos_prices| pos_prices.fill(0) }
218
+ @counters.fill(0)
219
+ end
220
+
221
+ # Get price for encoding length at position state
222
+ #
223
+ # @param pos_state [Integer] Position state (0 to 2^pb - 1)
224
+ # @param length [Integer] Match length (2 to 273)
225
+ # @return [Integer] Price in price units
226
+ def get_price(pos_state, length)
227
+ @prices[pos_state][length - MATCH_LEN_MIN]
228
+ end
229
+
230
+ # Set price for length at position state
231
+ #
232
+ # @param pos_state [Integer] Position state
233
+ # @param length [Integer] Match length
234
+ # @param price [Integer] Price value
235
+ def set_price(pos_state, length, price)
236
+ @prices[pos_state][length - MATCH_LEN_MIN] = price
237
+ end
238
+
239
+ # Decrement counter for position state
240
+ #
241
+ # @param pos_state [Integer] Position state
242
+ # @return [Boolean] True if counter reached zero
243
+ def decrement_counter(pos_state)
244
+ @counters[pos_state] -= 1
245
+ @counters[pos_state] <= 0
246
+ end
247
+
248
+ # Reset counter for position state
249
+ #
250
+ # @param pos_state [Integer] Position state
251
+ # @param value [Integer] Counter value
252
+ def reset_counter(pos_state, value)
253
+ @counters[pos_state] = value
254
+ end
255
+ end
256
+ end
257
+ end
258
+ end