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,223 @@
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
+ # Range Encoder ported from XZ Utils range_encoder.c
27
+ #
28
+ # This class implements binary range coding, which is the core
29
+ # compression algorithm for LZMA. Range coding is a form of
30
+ # arithmetic coding that encodes bits into a compressed bitstream
31
+ # using probability models.
32
+ #
33
+ # The encoder maintains a range [low, low+range) and narrows this
34
+ # range as bits are encoded. When the range becomes too small, it
35
+ # is normalized and output bytes are produced.
36
+ #
37
+ # Ported from XZ Utils liblzma/range_encoder.c
38
+ class XZRangeEncoder
39
+ TOP_VALUE = 1 << 24
40
+ SHIFT_BITS = 8
41
+ BIT_MODEL_TOTAL_BITS = 11
42
+ BIT_MODEL_TOTAL = 1 << BIT_MODEL_TOTAL_BITS
43
+
44
+ attr_reader :cache, :range, :low
45
+
46
+ # Initialize a new range encoder
47
+ #
48
+ # @param output [IO] Output stream for compressed data
49
+ def initialize(output)
50
+ @output = output
51
+ @low = 0
52
+ @range = 0xFFFFFFFF
53
+ @cache = 0
54
+ @cache_size = 1
55
+ end
56
+
57
+ # Encode a single bit using probability model
58
+ #
59
+ # This method encodes a bit (0 or 1) using an adaptive probability
60
+ # model. The probability model is updated after encoding to adapt
61
+ # to the input data statistics.
62
+ #
63
+ # Ported from XZ Utils range_encoder.c rc_bit()
64
+ #
65
+ # @param model [BitModel] Probability model for this bit
66
+ # @param bit [Integer] Bit value to encode (0 or 1)
67
+ # @return [void]
68
+ def encode_bit(model, bit)
69
+ prob = model.probability
70
+ bound = (@range >> BIT_MODEL_TOTAL_BITS) * prob
71
+
72
+ if bit.zero?
73
+ @range = bound
74
+ else
75
+ @low += bound
76
+ @range -= bound
77
+ end
78
+
79
+ normalize! if @range < TOP_VALUE
80
+
81
+ # Update probability model based on bit value
82
+ # Matches decoder behavior (proper OOP symmetry)
83
+ model.update(bit)
84
+ end
85
+
86
+ # Encode multiple bits as a bittree
87
+ #
88
+ # A bittree is a binary tree where each node has a probability model.
89
+ # This method encodes a value by traversing the tree from the root,
90
+ # encoding the bit at each node and following the corresponding branch.
91
+ #
92
+ # Ported from XZ Utils range_encoder.c rc_bittree()
93
+ #
94
+ # @param models [Array<BitModel>] Array of probability models for tree nodes
95
+ # @param num_bits [Integer] Number of bits to encode
96
+ # @param value [Integer] Value to encode
97
+ # @return [void]
98
+ def encode_bittree(models, num_bits, value)
99
+ index = 1
100
+ bit = num_bits - 1
101
+
102
+ while bit >= 0
103
+ bit_value = (value >> bit) & 1
104
+ encode_bit(models[index - 1], bit_value)
105
+ index = (index << 1) | bit_value
106
+ bit -= 1
107
+ end
108
+ end
109
+
110
+ # Encode multiple bits as a reverse bittree
111
+ #
112
+ # Similar to encode_bittree but processes bits in reverse order.
113
+ # This is used for certain LZMA encoding operations.
114
+ #
115
+ # Ported from XZ Utils range_encoder.c rc_bittree_reverse()
116
+ #
117
+ # @param models [Array<BitModel>] Array of probability models for tree nodes
118
+ # @param num_bits [Integer] Number of bits to encode
119
+ # @param value [Integer] Value to encode
120
+ # @return [void]
121
+ def encode_bittree_reverse(models, num_bits, value)
122
+ index = 1
123
+ bit = 0
124
+
125
+ while bit < num_bits
126
+ bit_value = (value >> bit) & 1
127
+ encode_bit(models[index - 1], bit_value)
128
+ index = (index << 1) | bit_value
129
+ bit += 1
130
+ end
131
+ end
132
+
133
+ # Encode a direct bit (without probability model)
134
+ #
135
+ # This method encodes a bit with fixed 0.5 probability.
136
+ # Used for encoding values where no adaptive model is available.
137
+ #
138
+ # Ported from XZ Utils range_encoder.c rc_direct()
139
+ #
140
+ # @param value [Integer] Value to encode (0 or 1)
141
+ # @return [void]
142
+ def encode_direct(value)
143
+ @range >>= 1
144
+ @low += @range if value != 0
145
+ normalize! if @range < TOP_VALUE
146
+ end
147
+
148
+ # Flush pending data to output stream
149
+ #
150
+ # This method flushes any remaining data in the range encoder
151
+ # to the output stream. This must be called before the encoder
152
+ # is discarded.
153
+ #
154
+ # Ported from XZ Utils range_encoder.c rc_flush()
155
+ #
156
+ # @return [void]
157
+ def flush!
158
+ (5 - @cache_size).times do
159
+ shift_low
160
+ end
161
+ end
162
+
163
+ private
164
+
165
+ # Normalize the range encoder state
166
+ #
167
+ # When the range becomes too small (< TOP_VALUE), it needs to be
168
+ # normalized by shifting left and outputting bytes as needed.
169
+ #
170
+ # Ported from XZ Utils range_encoder.c rc_normalize()
171
+ #
172
+ # @return [void]
173
+ def normalize!
174
+ if @range < TOP_VALUE
175
+ @range <<= SHIFT_BITS
176
+ shift_low
177
+ end
178
+ end
179
+
180
+ # Shift low value and output bytes as needed
181
+ #
182
+ # This method handles the carry propagation and byte output
183
+ # for the range encoder. When the high byte of low changes,
184
+ # it outputs bytes to the stream.
185
+ #
186
+ # Ported from XZ Utils range_encoder.c rc_shift_low()
187
+ # See: /Users/mulgogi/src/external/xz/src/liblzma/rangecoder/range_encoder.h:140-186
188
+ #
189
+ # @return [void]
190
+ def shift_low
191
+ # Extract low 32 bits and high 32 bits (carry)
192
+ # XZ Utils: if ((uint32_t)(rc->low) < (uint32_t)(0xFF000000) || (uint32_t)(rc->low >> 32) != 0)
193
+ # This condition is TRUE when:
194
+ # - low32 < 0xFF000000 (the high byte of low is NOT 0xFF)
195
+ # - OR high != 0 (there's a carry from the low value)
196
+ # When TRUE: write output bytes
197
+ # When FALSE: increment cache_size (we're in a run of 0xFF bytes)
198
+ low32 = @low & 0xFFFFFFFF
199
+ high = (@low >> 32) & 0xFF
200
+
201
+ if low32 < 0xFF000000 || high != 0
202
+ # Write pending cache bytes (with carry if present)
203
+ temp = @cache
204
+ while @cache_size.positive?
205
+ @output.putc((temp + high) & 0xFF)
206
+ temp = 0xFF
207
+ @cache_size -= 1
208
+ end
209
+ # Update cache to the high byte of low
210
+ @cache = (low32 >> 24) & 0xFF
211
+ else
212
+ # High byte of low is 0xFF and no carry - increment pending count
213
+ @cache_size += 1
214
+ end
215
+
216
+ # Shift low left by 8 bits (keeping only low 24 bits before shift)
217
+ # XZ Utils: low = (low & 0x00FFFFFF) << RC_SHIFT_BITS;
218
+ @low = (low32 & 0x00FFFFFF) << SHIFT_BITS
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,314 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2025 Ribose Inc.
4
+ #
5
+ # Direct port of XZ Utils range encoder to Ruby
6
+ # Based on: xz/src/liblzma/rangecoder/range_encoder.h
7
+
8
+ module Omnizip
9
+ module Algorithms
10
+ class LZMA < Algorithm
11
+ # XZ Utils-compatible range encoder (direct port)
12
+ #
13
+ # This is a direct port of the XZ Utils range encoder implementation
14
+ # to ensure exact algorithmic compatibility with XZ Utils output.
15
+ class XzRangeEncoder
16
+ include Constants
17
+
18
+ # Range encoder constants (matching XZ Utils range_common.h)
19
+ SHIFT_BITS = 8 # RC_SHIFT_BITS
20
+ TOP_BITS = 24 # RC_TOP_BITS
21
+ TOP = 0x01000000 # 2^24
22
+ BIT_MODEL_TOTAL_BITS = 11
23
+ BIT_MODEL_TOTAL = 2048 # 2^11
24
+
25
+ # Symbol types (matching XZ Utils enum)
26
+ RC_BIT_0 = 0
27
+ RC_BIT_1 = 1
28
+ RC_DIRECT_0 = 2
29
+ RC_DIRECT_1 = 3
30
+ RC_FLUSH = 4
31
+
32
+ # Maximum symbols that can be queued
33
+ RC_SYMBOLS_MAX = 53
34
+
35
+ attr_reader :out_total, :count, :low, :range, :cache, :cache_size
36
+
37
+ # Initialize the range encoder
38
+ #
39
+ # @param output_stream [IO] The output stream for encoded bytes
40
+ def initialize(output_stream)
41
+ @stream = output_stream
42
+ # Initialize @out_total BEFORE calling reset
43
+ @out_total = 0
44
+ reset
45
+ end
46
+
47
+ # Reset encoder to initial state (matches XZ Utils rc_reset)
48
+ def reset
49
+ @low = 0
50
+ @cache_size = 1 # CRITICAL: XZ starts with 1, not 0
51
+ @range = 0xFFFFFFFF
52
+ @cache = 0
53
+ # CRITICAL: Reset @out_total to match XZ Utils behavior (line 63 of range_encoder.h)
54
+ # This ensures bytes_for_decode returns the correct count
55
+ @out_total = 0
56
+ # NOTE: @pre_flush_out_total is NOT reset - it retains its value for bytes_for_decode
57
+ # It will be reset to 0 when a new chunk starts (via initialize)
58
+ @count = 0
59
+ @pos = 0
60
+ @symbols = Array.new(RC_SYMBOLS_MAX, 0)
61
+ @probs = Array.new(RC_SYMBOLS_MAX, nil)
62
+ end
63
+
64
+ # Forget pending symbols (matches XZ Utils rc_forget)
65
+ def forget
66
+ raise Omnizip::CompressionError, "Cannot forget while encoding" if @pos != 0
67
+
68
+ @count = 0
69
+ end
70
+
71
+ # Queue a bit for encoding (matches XZ Utils rc_bit)
72
+ #
73
+ # @param prob [Probability] Probability model
74
+ # @param bit [Integer] Bit value (0 or 1)
75
+ def bit(prob, bit)
76
+ raise Omnizip::CompressionError, "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
77
+
78
+ @symbols[@count] = bit
79
+ @probs[@count] = prob
80
+ @count += 1
81
+ end
82
+ alias queue_bit bit
83
+
84
+ # Queue bittree encoding (matches XZ Utils rc_bittree)
85
+ #
86
+ # @param probs [Array<Probability>] Probability array
87
+ # @param bit_count [Integer] Number of bits
88
+ # @param symbol [Integer] Symbol to encode
89
+ def bittree(probs, bit_count, symbol)
90
+ model_index = 1
91
+
92
+ bit_count.times do
93
+ bit = (symbol >> (bit_count -= 1)) & 1
94
+ bit(probs[model_index], bit)
95
+ model_index = (model_index << 1) | bit
96
+ end
97
+ end
98
+
99
+ # Queue bittree encoding in reverse (matches XZ Utils rc_bittree_reverse)
100
+ #
101
+ # @param probs [Array<Probability>] Probability array
102
+ # @param bit_count [Integer] Number of bits
103
+ # @param symbol [Integer] Symbol to encode
104
+ def bittree_reverse(probs, bit_count, symbol)
105
+ model_index = 1
106
+
107
+ bit_count.times do
108
+ bit = symbol & 1
109
+ symbol >>= 1
110
+ bit(probs[model_index], bit)
111
+ model_index = (model_index << 1) | bit
112
+ end
113
+ end
114
+
115
+ # Queue direct bits (matches XZ Utils rc_direct)
116
+ #
117
+ # @param value [Integer] Value to encode
118
+ # @param bit_count [Integer] Number of bits
119
+ def direct(value, bit_count)
120
+ bit_count.times do
121
+ raise Omnizip::CompressionError, "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
122
+
123
+ @symbols[@count] = RC_DIRECT_0 | ((value >> (bit_count -= 1)) & 1)
124
+ @probs[@count] = nil
125
+ @count += 1
126
+ end
127
+ end
128
+
129
+ # Queue flush operation (matches XZ Utils rc_flush)
130
+ def flush
131
+ 5.times do
132
+ raise Omnizip::CompressionError, "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
133
+
134
+ @symbols[@count] = RC_FLUSH
135
+ @probs[@count] = nil
136
+ @count += 1
137
+ end
138
+ end
139
+ alias queue_flush flush
140
+
141
+ # Get number of pending bytes (matches XZ Utils rc_pending)
142
+ #
143
+ # @return [Integer] Number of pending output bytes
144
+ def pending
145
+ @cache_size + 5 - 1
146
+ end
147
+
148
+ # Check if no symbols are queued
149
+ #
150
+ # @return [Boolean] True if no symbols queued
151
+ def none?
152
+ @count.zero?
153
+ end
154
+
155
+ # Encode all queued symbols to output (matches XZ Utils rc_encode)
156
+ #
157
+ # @param out [IO,String] Output buffer
158
+ # @param out_pos [IntegerRef] Current output position
159
+ # @param out_size [Integer] Output buffer size
160
+ # @return [Boolean] True if output buffer filled before encoding complete
161
+ def encode(out, out_pos, out_size)
162
+ raise Omnizip::CompressionError, "Symbol buffer overflow" if @count > RC_SYMBOLS_MAX
163
+
164
+ skip_increment = false
165
+
166
+ while @pos < @count
167
+ # Normalize (matches XZ Utils exactly)
168
+ if @range < TOP
169
+ return true if shift_low(out, out_pos, out_size)
170
+
171
+ @range <<= SHIFT_BITS
172
+ end
173
+
174
+ # Encode current symbol
175
+ case @symbols[@pos]
176
+ when RC_BIT_0
177
+ prob = @probs[@pos]
178
+ # XZ Utils: rc->range = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * prob
179
+ @range = (@range >> BIT_MODEL_TOTAL_BITS) * prob.value
180
+ # XZ Utils: prob += (RC_BIT_MODEL_TOTAL - prob) >> RC_MOVE_BITS
181
+ prob.value += (BIT_MODEL_TOTAL - prob.value) >> MOVE_BITS
182
+ @probs[@pos] = prob
183
+
184
+ when RC_BIT_1
185
+ prob = @probs[@pos]
186
+ # XZ Utils: bound = prob * (rc->range >> RC_BIT_MODEL_TOTAL_BITS)
187
+ bound = prob.value * (@range >> BIT_MODEL_TOTAL_BITS)
188
+ @low += bound
189
+ @range -= bound
190
+ # XZ Utils: prob -= prob >> RC_MOVE_BITS
191
+ prob.value -= prob.value >> MOVE_BITS
192
+ @probs[@pos] = prob
193
+
194
+ when RC_DIRECT_0
195
+ @range >>= 1
196
+
197
+ when RC_DIRECT_1
198
+ @range >>= 1
199
+ @low += @range
200
+
201
+ when RC_FLUSH
202
+ # Prevent further normalizations (XZ Utils behavior)
203
+ @range = 0xFFFFFFFF
204
+
205
+ # Flush the last five bytes (see rc_flush)
206
+ begin
207
+ return true if shift_low(out, out_pos, out_size)
208
+ end while (@pos += 1) < @count
209
+
210
+ # Reset the range encoder (matches XZ Utils)
211
+ reset
212
+ # CRITICAL: Skip the @pos increment at loop end because do-while already did it
213
+ skip_increment = true
214
+ break
215
+
216
+ else
217
+ raise Omnizip::CompressionError, "Unknown symbol type: #{@symbols[@pos]}"
218
+ end
219
+
220
+ @pos += 1 unless skip_increment
221
+ end
222
+
223
+ @count = 0
224
+ @pos = 0
225
+
226
+ false
227
+ end
228
+
229
+ # Shift low bytes to output (matches XZ Utils rc_shift_low)
230
+ #
231
+ # @param out [IO,String] Output buffer
232
+ # @param out_pos [IntegerRef] Current output position
233
+ # @param out_size [Integer] Output buffer size
234
+ # @return [Boolean] True if output buffer filled
235
+ def shift_low(out, out_pos, out_size)
236
+ # XZ Utils: if ((uint32_t)(rc->low) < (uint32_t)(0xFF000000) || (uint32_t)(rc->low >> 32) != 0)
237
+ if (@low & 0xFFFFFFFF) < 0xFF000000 || (@low >> 32) != 0
238
+ # XZ Utils: do { ... } while (--rc->cache_size != 0);
239
+ while @cache_size.positive?
240
+ return true if out_pos.value == out_size
241
+
242
+ # XZ Utils: out[*out_pos] = rc->cache + (uint8_t)(rc->low >> 32)
243
+ output_byte = @cache + ((@low >> 32) & 0xFF)
244
+
245
+ if out.is_a?(String)
246
+ out.setbyte(out_pos.value, output_byte)
247
+ else
248
+ out.putc(output_byte)
249
+ end
250
+
251
+ out_pos.value += 1
252
+ @out_total += 1
253
+ @cache = 0xFF
254
+
255
+ @cache_size -= 1
256
+ end
257
+
258
+ # XZ Utils: rc->cache = (rc->low >> 24) & 0xFF
259
+ @cache = (@low >> 24) & 0xFF
260
+ end
261
+
262
+ # XZ Utils: ++rc->cache_size; rc->low = (rc->low & 0x00FFFFFF) << RC_SHIFT_BITS
263
+ @cache_size += 1
264
+ @low = (@low & 0x00FFFFFF) << SHIFT_BITS
265
+
266
+ false
267
+ end
268
+
269
+ # Adapter method: alias for bit (to match existing API)
270
+ alias queue_bit bit
271
+
272
+ # Adapter method: alias for bittree (to match existing API)
273
+ alias queue_bittree bittree
274
+
275
+ # Adapter method: alias for bittree_reverse (to match existing API)
276
+ alias queue_bittree_reverse bittree_reverse
277
+
278
+ # Adapter method: alias for direct (to match existing API)
279
+ def queue_direct_bits(value, num_bits)
280
+ direct(value, num_bits)
281
+ end
282
+
283
+ # Adapter method: alias for encode (to match existing API)
284
+ alias encode_symbols encode
285
+
286
+ # Adapter method: match existing API
287
+ alias queue_flush flush
288
+
289
+ # Forget pending symbols (matches XZ Utils rc_forget)
290
+ def forget
291
+ raise Omnizip::CompressionError, "Cannot forget while encoding" if @pos != 0
292
+
293
+ @count = 0
294
+ end
295
+
296
+ # Calculate pending output bytes
297
+ #
298
+ # @return [Integer] Number of bytes decoder will consume
299
+ def bytes_for_decode
300
+ @out_total
301
+ end
302
+ end
303
+
304
+ # Reference wrapper for integer (for out_pos parameter)
305
+ class IntRef
306
+ attr_accessor :value
307
+
308
+ def initialize(val)
309
+ @value = val
310
+ end
311
+ end
312
+ end
313
+ end
314
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Algorithms
5
+ class LZMA < Algorithm
6
+ # XZ Utils-compatible LZMA state machine
7
+ #
8
+ # Tracks encoding context via 12-state machine to predict
9
+ # optimal probability models for upcoming symbols.
10
+ #
11
+ # Based on: xz/src/liblzma/lzma/lzma_common.h
12
+ class XzState
13
+ # 12 LZMA states (matching XZ Utils exactly)
14
+ STATE_LIT_LIT = 0 # literal after literal
15
+ STATE_MATCH_LIT_LIT = 1 # literal after literal after match
16
+ STATE_REP_LIT_LIT = 2 # literal after literal after rep
17
+ STATE_SHORTREP_LIT_LIT = 3 # literal after literal after shortrep
18
+ STATE_MATCH_LIT = 4 # literal after match
19
+ STATE_REP_LIT = 5 # literal after rep
20
+ STATE_SHORTREP_LIT = 6 # literal after shortrep
21
+ STATE_LIT_MATCH = 7 # match after literal
22
+ STATE_LIT_LONGREP = 8 # longrep after literal
23
+ STATE_LIT_SHORTREP = 9 # shortrep after literal
24
+ STATE_NONLIT_MATCH = 10 # match after non-literal
25
+ STATE_NONLIT_REP = 11 # rep after non-literal
26
+
27
+ LIT_STATES = 7 # States 0-6 indicate previous was literal
28
+
29
+ attr_accessor :value
30
+
31
+ def initialize(initial = STATE_LIT_LIT)
32
+ @value = initial
33
+ end
34
+
35
+ # Update state after encoding literal
36
+ # Matches XZ Utils update_literal() macro
37
+ def update_literal
38
+ @value = if @value <= STATE_SHORTREP_LIT_LIT
39
+ STATE_LIT_LIT
40
+ elsif @value <= STATE_LIT_SHORTREP
41
+ @value - 3
42
+ else
43
+ @value - 6
44
+ end
45
+ end
46
+
47
+ # Update state after encoding match
48
+ # Matches XZ Utils update_match() macro
49
+ def update_match
50
+ @value = @value < LIT_STATES ? STATE_LIT_MATCH : STATE_NONLIT_MATCH
51
+ end
52
+
53
+ # Update state after encoding long rep match
54
+ # Matches XZ Utils update_long_rep() macro
55
+ def update_long_rep
56
+ @value = @value < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP
57
+ end
58
+
59
+ # Update state after encoding short rep (1 byte)
60
+ # Matches XZ Utils update_short_rep() macro
61
+ def update_short_rep
62
+ @value = @value < LIT_STATES ? STATE_LIT_SHORTREP : STATE_NONLIT_REP
63
+ end
64
+
65
+ # Check if previous symbol was literal
66
+ def literal_state?
67
+ @value < LIT_STATES
68
+ end
69
+
70
+ # Create a copy of this state
71
+ def dup
72
+ XzState.new(@value)
73
+ end
74
+
75
+ # Reset to initial state
76
+ def reset
77
+ @value = STATE_LIT_LIT
78
+ end
79
+
80
+ # Check if state is valid
81
+ def valid?
82
+ @value.between?(STATE_LIT_LIT, STATE_NONLIT_REP)
83
+ end
84
+
85
+ # String representation for debugging
86
+ def to_s
87
+ STATE_NAMES[@value] || "INVALID(#{@value})"
88
+ end
89
+
90
+ # State names for debugging
91
+ STATE_NAMES = {
92
+ STATE_LIT_LIT => "STATE_LIT_LIT",
93
+ STATE_MATCH_LIT_LIT => "STATE_MATCH_LIT_LIT",
94
+ STATE_REP_LIT_LIT => "STATE_REP_LIT_LIT",
95
+ STATE_SHORTREP_LIT_LIT => "STATE_SHORTREP_LIT_LIT",
96
+ STATE_MATCH_LIT => "STATE_MATCH_LIT",
97
+ STATE_REP_LIT => "STATE_REP_LIT",
98
+ STATE_SHORTREP_LIT => "STATE_SHORTREP_LIT",
99
+ STATE_LIT_MATCH => "STATE_LIT_MATCH",
100
+ STATE_LIT_LONGREP => "STATE_LIT_LONGREP",
101
+ STATE_LIT_SHORTREP => "STATE_LIT_SHORTREP",
102
+ STATE_NONLIT_MATCH => "STATE_NONLIT_MATCH",
103
+ STATE_NONLIT_REP => "STATE_NONLIT_REP",
104
+ }.freeze
105
+ end
106
+ end
107
+ end
108
+ end