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,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Algorithms
5
+ class LZMA2 < Algorithm
6
+ # LZMA2 Chunk structure using Array#pack for binary serialization
7
+ class LZMA2Chunk
8
+ TYPE_END = :end
9
+ TYPE_UNCOMPRESSED = :uncompressed
10
+ TYPE_COMPRESSED = :compressed
11
+
12
+ attr_reader :chunk_type, :uncompressed_data, :compressed_data,
13
+ :properties, :control_byte
14
+
15
+ # Factory method for end marker
16
+ def self.end_chunk
17
+ new(
18
+ chunk_type: TYPE_END,
19
+ uncompressed_data: "",
20
+ compressed_data: "",
21
+ need_dict_reset: false,
22
+ need_state_reset: false,
23
+ need_props: false,
24
+ )
25
+ end
26
+
27
+ def initialize(chunk_type:, need_dict_reset:, need_state_reset:,
28
+ need_props:, uncompressed_data: "",
29
+ compressed_data: "", properties: nil,
30
+ compressed_size: nil)
31
+ # Validate chunk_type
32
+ valid_types = [TYPE_END, TYPE_UNCOMPRESSED, TYPE_COMPRESSED]
33
+ unless valid_types.include?(chunk_type)
34
+ raise ArgumentError,
35
+ "Invalid chunk_type: #{chunk_type.inspect}. " \
36
+ "Must be :end, :uncompressed, or :compressed"
37
+ end
38
+
39
+ @chunk_type = chunk_type
40
+ @uncompressed_data = uncompressed_data
41
+ @compressed_data = compressed_data
42
+ # For XZ format, compressed_size excludes flush bytes
43
+ # For standalone LZMA2, compressed_size includes all bytes
44
+ @compressed_size = compressed_size || @compressed_data.bytesize
45
+ @properties = properties
46
+ @need_dict_reset = need_dict_reset
47
+ @need_state_reset = need_state_reset
48
+ @need_props = need_props
49
+
50
+ @control_byte = build_control_byte if chunk_type != TYPE_END
51
+ end
52
+
53
+ # Serialize to binary format
54
+ def to_bytes
55
+ case @chunk_type
56
+ when TYPE_END
57
+ [0x00].pack("C")
58
+ when TYPE_UNCOMPRESSED
59
+ serialize_uncompressed
60
+ when TYPE_COMPRESSED
61
+ serialize_compressed
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def build_control_byte
68
+ case @chunk_type
69
+ when TYPE_COMPRESSED
70
+ # XZ Utils LZMA2 compressed chunk format:
71
+ # Base is 0x80 (bit 7 = 1 for compressed)
72
+ # Bits 6-5 encode reset state (shifted left by 5):
73
+ # 3 << 5 = 0x60 = dict reset + state reset + properties
74
+ # 2 << 5 = 0x40 = state reset + properties
75
+ # 1 << 5 = 0x20 = state reset only
76
+ # 0 << 5 = 0x00 = no reset (no properties)
77
+ #
78
+ # Control byte format: 0x80 + (reset_type << 5)
79
+ # High 5 bits of (uncompressed_size - 1) are added later in serialize_compressed
80
+
81
+ control = if @need_props
82
+ if @need_dict_reset
83
+ 0x80 + (3 << 5) # 0xE0 = dict reset + state reset + properties
84
+ elsif @need_state_reset
85
+ 0x80 + (2 << 5) # 0xC0 = state reset + properties
86
+ else
87
+ # This shouldn't happen - if need_props, we need some reset
88
+ 0x80 + (2 << 5) # Default to state reset + properties
89
+ end
90
+ elsif @need_state_reset
91
+ 0x80 + (1 << 5)
92
+ else
93
+ 0x80 # 0x80 = no reset
94
+ end
95
+
96
+ # DEBUG: Print control byte calculation
97
+ if ENV["DEBUG_CHUNK"]
98
+ warn "LZMA2Chunk build_control_byte: need_props=#{@need_props}, need_dict_reset=#{@need_dict_reset}, need_state_reset=#{@need_state_reset}, control=0x#{control.to_s(16)}"
99
+ end
100
+
101
+ control
102
+ when TYPE_UNCOMPRESSED
103
+ # XZ Utils LZMA2 uncompressed chunk format:
104
+ # Control byte is simply 1 or 2 (NOT complex bit encoding!)
105
+ # 1 = dictionary reset
106
+ # 2 = no dictionary reset
107
+ if @need_dict_reset
108
+ 1
109
+ else
110
+ 2
111
+ end
112
+ end
113
+ end
114
+
115
+ def serialize_uncompressed
116
+ size = @uncompressed_data.bytesize - 1
117
+
118
+ # LZMA2 uncompressed chunk format (matches XZ Utils lzma2_encoder.c lzma2_header_uncompressed):
119
+ # 1 byte: control (1 = dict reset, 2 = no reset)
120
+ # 2 bytes: Uncompressed Size Minus One in BIG-ENDIAN
121
+ # N bytes: uncompressed data
122
+ [
123
+ @control_byte, # Control byte (1 or 2)
124
+ (size >> 8) & 0xFF, # Size high byte (BIG-ENDIAN)
125
+ size & 0xFF, # Size low byte (BIG-ENDIAN)
126
+ ].pack("CCC") + @uncompressed_data
127
+ end
128
+
129
+ def serialize_compressed
130
+ uncomp_size = @uncompressed_data.bytesize - 1
131
+ comp_size = @compressed_size - 1
132
+
133
+ # Add high 5 bits to control byte
134
+ high_bits = ((uncomp_size >> 16) & 0x1F)
135
+ control = @control_byte | high_bits
136
+
137
+ # DEBUG: Print final control byte calculation
138
+ if ENV["DEBUG_CHUNK"]
139
+ warn "LZMA2Chunk serialize_compressed: @control_byte=0x#{@control_byte.to_s(16)}, high_bits=0x#{high_bits.to_s(16)}, final_control=0x#{control.to_s(16)}"
140
+ warn " uncomp_size=#{@uncompressed_data.bytesize} (uncomp_size-1=#{uncomp_size}), comp_size=#{@compressed_size}"
141
+ end
142
+
143
+ # XZ Utils LZMA2 compressed chunk format (matches lzma2_encoder.c lzma2_header_lzma):
144
+ # 1 byte: control + high 5 bits of (uncompressed_size - 1)
145
+ # 2 bytes: low 16 bits of (uncompressed_size - 1) in BIG-ENDIAN
146
+ # 2 bytes: (compressed_size - 1) in BIG-ENDIAN
147
+ header = [
148
+ control,
149
+ (uncomp_size >> 8) & 0xFF, # Uncompressed size mid byte (BIG-ENDIAN)
150
+ uncomp_size & 0xFF, # Uncompressed size low byte (BIG-ENDIAN)
151
+ (comp_size >> 8) & 0xFF, # Compressed size high byte (BIG-ENDIAN)
152
+ comp_size & 0xFF, # Compressed size low byte (BIG-ENDIAN)
153
+ ].pack("CCCCC")
154
+
155
+ # The properties byte is only present when the control byte
156
+ # announces it (reset level >= 2, i.e. 0xC0/0xE0). Writing it for
157
+ # plain continuation chunks (0x80) desynchronizes the decoder,
158
+ # which does not expect a byte there.
159
+ prop_bytes = @need_props && @properties ? [@properties].pack("C") : ""
160
+ header + prop_bytes + @compressed_data
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,179 @@
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 LZMA2
26
+ # LZMA2 Properties - handles dictionary size encoding/decoding
27
+ #
28
+ # The LZMA2 format uses a single property byte that encodes the
29
+ # dictionary size. This is more compact than LZMA's multiple
30
+ # property bytes.
31
+ #
32
+ # Dictionary size encoding formula:
33
+ # dictSize = (2 | (props & 1)) << (props / 2 + 11)
34
+ #
35
+ # This gives sizes from 4KB (props=0) to 4GB (props=40)
36
+ #
37
+ # Note: In XZ format, the LZMA2 filter properties byte contains ONLY
38
+ # the dictionary size encoding. The lc/lp/pb parameters are encoded
39
+ # in the LZMA chunk properties (inside the compressed data).
40
+ class Properties
41
+ include LZMA2Const
42
+
43
+ attr_reader :dict_size, :prop_byte
44
+
45
+ # Initialize properties from dictionary size
46
+ #
47
+ # @param dict_size [Integer] Dictionary size in bytes
48
+ def initialize(dict_size)
49
+ @dict_size = validate_dict_size(dict_size)
50
+ @prop_byte = encode_dict_size(@dict_size)
51
+ end
52
+
53
+ # Create properties from property byte
54
+ #
55
+ # @param prop_byte [Integer] Encoded property byte
56
+ # @return [Properties] New properties instance
57
+ def self.from_byte(prop_byte)
58
+ validate_prop_byte(prop_byte)
59
+ dict_size = decode_dict_size(prop_byte)
60
+ new(dict_size)
61
+ end
62
+
63
+ # Encode dictionary size to property byte
64
+ #
65
+ # @param dict_size [Integer] Dictionary size
66
+ # @return [Integer] Property byte value
67
+ def encode_dict_size(dict_size)
68
+ # Find the smallest prop value that gives >= dict_size
69
+ # Valid range for property byte is 0-40 (per XZ spec)
70
+ (0..40).each do |prop|
71
+ size = self.class.decode_dict_size(prop)
72
+ return prop if size >= dict_size
73
+ end
74
+
75
+ # If we couldn't find a suitable prop, use maximum
76
+ 40
77
+ end
78
+
79
+ # Decode property byte to dictionary size
80
+ #
81
+ # XZ Utils formula from lzma_lzma2_props_decode (lzma2_decoder.c:290-302):
82
+ # dict_size = (2 | (props & 1)) << (props / 2 + 11)
83
+ #
84
+ # For even props: dict_size = 2 * 2^((props/2) + 11) = 2^((props/2) + 12)
85
+ # For odd props: dict_size = 3 * 2^((props-1)/2 + 11)
86
+ #
87
+ # @param prop [Integer] Property byte
88
+ # @return [Integer] Dictionary size in bytes
89
+ def self.decode_dict_size(prop)
90
+ # XZ Utils formula: dict_size = (2 | (prop & 1)) << (prop / 2 + 11)
91
+ base = 2 | (prop & 1)
92
+ base << ((prop / 2) + 11)
93
+ end
94
+
95
+ # Encode properties to property byte
96
+ # This is for standalone LZMA2 files where the property byte
97
+ # encodes both dictionary size and lc/lp/pb parameters
98
+ #
99
+ # @param dict_size [Integer] Dictionary size
100
+ # @param lc [Integer] Literal context bits
101
+ # @param lp [Integer] Literal position bits
102
+ # @param pb [Integer] Position bits
103
+ # @return [Integer] Property byte value
104
+ def self.encode(dict_size, _lc = 3, _lp = 0, _pb = 2)
105
+ # For standalone LZMA2 files, we only encode the dictionary size
106
+ # The lc/lp/pb parameters are encoded in the LZMA chunk properties instead
107
+ validate_prop_byte_range(dict_size)
108
+ encode_dict_size_to_byte(dict_size)
109
+ end
110
+
111
+ # Encode dictionary size to property byte
112
+ #
113
+ # @param dict_size [Integer] Dictionary size
114
+ # @return [Integer] Property byte value
115
+ def self.encode_dict_size_to_byte(dict_size)
116
+ # Find the smallest prop value that gives >= dict_size
117
+ (0..40).each do |prop|
118
+ size = decode_dict_size(prop)
119
+ return prop if size >= dict_size
120
+ end
121
+ 40
122
+ end
123
+
124
+ # Validate dictionary size for property byte encoding
125
+ #
126
+ # @param size [Integer] Dictionary size to validate
127
+ # @raise [ArgumentError] If size is invalid
128
+ def self.validate_prop_byte_range(size)
129
+ unless size.between?(DICT_SIZE_MIN, DICT_SIZE_MAX)
130
+ raise ArgumentError,
131
+ "Dictionary size must be between #{DICT_SIZE_MIN} " \
132
+ "and #{DICT_SIZE_MAX}"
133
+ end
134
+ end
135
+
136
+ # Get the actual dictionary size (may differ from requested)
137
+ #
138
+ # @return [Integer] Actual dictionary size (capped at 64MB to prevent memory exhaustion)
139
+ def actual_dict_size
140
+ # Cap at 64MB to prevent memory exhaustion from malformed files
141
+ max_dict = 64 * 1024 * 1024
142
+ [self.class.decode_dict_size(@prop_byte), max_dict].min
143
+ end
144
+
145
+ private
146
+
147
+ # Validate dictionary size
148
+ #
149
+ # @param size [Integer] Dictionary size to validate
150
+ # @return [Integer] Validated size
151
+ # @raise [ArgumentError] If size is invalid
152
+ def validate_dict_size(size)
153
+ # LZMA2 practical maximum is 2GB due to implementation limitations
154
+ # The spec allows up to 4GB, but practical limits are lower
155
+ # Maximum is (1 << 31) - 1 due to signed 32-bit integer limits
156
+ max_size = [DICT_SIZE_MAX, (1 << 31) - 1].min
157
+ unless size.between?(DICT_SIZE_MIN, max_size)
158
+ raise ArgumentError,
159
+ "Dictionary size must be between #{DICT_SIZE_MIN} " \
160
+ "and #{max_size}"
161
+ end
162
+ size
163
+ end
164
+
165
+ # Validate property byte
166
+ #
167
+ # @param prop [Integer] Property byte to validate
168
+ # @return [void]
169
+ # @raise [ArgumentError] If property byte is invalid
170
+ def self.validate_prop_byte(prop)
171
+ return if prop.between?(0, 40)
172
+
173
+ raise ArgumentError,
174
+ "Property byte must be between 0 and 40"
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,122 @@
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
+ require "stringio"
24
+
25
+ module Omnizip
26
+ module Algorithms
27
+ class LZMA2 < Algorithm
28
+ # Simple LZMA2 encoder using XzEncoder internally
29
+ #
30
+ # This encoder uses the working XzEncoder for LZMA compression
31
+ # and wraps the result in proper LZMA2 chunks.
32
+ #
33
+ # For 7-Zip format compatibility, we need to produce LZMA2 chunks
34
+ # without a leading property byte (raw mode).
35
+ class SimpleLZMA2Encoder
36
+ # Maximum uncompressed size per LZMA2 chunk (2MB)
37
+ UNCOMPRESSED_MAX = 1 << 21
38
+
39
+ # Initialize the encoder
40
+ # @param dict_size [Integer] Dictionary size (default: 8MB)
41
+ # @param lc [Integer] Literal context bits (default: 3)
42
+ # @param lp [Integer] Literal position bits (default: 0)
43
+ # @param pb [Integer] Position bits (default: 2)
44
+ # @param standalone [Boolean] If true, write property byte at start
45
+ def initialize(
46
+ dict_size: 8 * 1024 * 1024,
47
+ lc: 3,
48
+ lp: 0,
49
+ pb: 2,
50
+ standalone: true
51
+ )
52
+ @dict_size = dict_size
53
+ @lc = lc
54
+ @lp = lp
55
+ @pb = pb
56
+ @standalone = standalone
57
+ end
58
+
59
+ # Encode data into LZMA2 format
60
+ # @param input_data [String] Input data to compress
61
+ # @return [String] LZMA2 compressed data
62
+ def encode(input_data)
63
+ output = StringIO.new
64
+ output.set_encoding(Encoding::BINARY)
65
+
66
+ # Write property byte if standalone
67
+ # LZMA2 property byte encodes dictionary size
68
+ if @standalone
69
+ prop_byte = encode_dict_size(@dict_size)
70
+ output.putc(prop_byte)
71
+ end
72
+
73
+ # Use XZ Utils LZMA2 encoder for proper LZMA2 encoding (no EOS marker)
74
+ # Pass standalone: false since SimpleLZMA2Encoder handles property byte
75
+ encoder = Omnizip::Implementations::XZUtils::LZMA2::Encoder.new(
76
+ dict_size: @dict_size,
77
+ lc: @lc,
78
+ lp: @lp,
79
+ pb: @pb,
80
+ standalone: false,
81
+ )
82
+
83
+ # Encode data - returns LZMA2 data as String (includes end marker)
84
+ encoded = encoder.encode(input_data)
85
+
86
+ # Write encoded data to output
87
+ output.write(encoded)
88
+
89
+ output.string
90
+ end
91
+
92
+ private
93
+
94
+ # Encode dictionary size to LZMA2 property byte
95
+ # @param dict_size [Integer] Dictionary size
96
+ # @return [Integer] Property byte (0-40)
97
+ def encode_dict_size(dict_size)
98
+ # Clamp to valid range
99
+ d = [dict_size, LZMA2Const::DICT_SIZE_MIN].max
100
+
101
+ # Calculate log2 of dict_size
102
+ log2_size = 0
103
+ temp = d
104
+ while temp > 1
105
+ log2_size += 1
106
+ temp >>= 1
107
+ end
108
+
109
+ # Encoding formula for power-of-2 sizes:
110
+ # d = 2 * (log2_size - 12)
111
+ if d == (1 << log2_size)
112
+ # Exact power of 2
113
+ [(log2_size - 12) * 2, 40].min
114
+ else
115
+ # Between 2^n and 2^n + 2^(n-1), use odd encoding
116
+ [((log2_size - 12) * 2) + 1, 40].min
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,85 @@
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
+ require "stringio"
24
+
25
+ module Omnizip
26
+ module Algorithms
27
+ # Adapter for XZ Encoder to work with LZMA2 chunking
28
+ #
29
+ # Wraps the pure Ruby XZ encoder to provide LZMA2-compatible interface
30
+ # for chunked encoding with size limits.
31
+ class LZMA2XzEncoderAdapter
32
+ # Initialize XZ encoder adapter
33
+ #
34
+ # @param options [Hash] Encoding options
35
+ # @option options [Integer] :lc Literal context bits (default 3)
36
+ # @option options [Integer] :lp Literal position bits (default 0)
37
+ # @option options [Integer] :pb Position bits (default 2)
38
+ # @option options [Integer] :nice_len Nice match length (default 32)
39
+ # @option options [Integer] :dict_size Dictionary size (default 8MB)
40
+ def initialize(options = {})
41
+ @options = options
42
+ @lc = options[:lc] || 3
43
+ @lp = options[:lp] || 0
44
+ @pb = options[:pb] || 2
45
+ end
46
+
47
+ # Encode data chunk
48
+ #
49
+ # @param data [String] Input data to encode
50
+ # @param limit [Integer, nil] Optional output size limit
51
+ # @return [String] Encoded data
52
+ def encode_chunk(data, _limit = nil)
53
+ output = StringIO.new
54
+ encoder = LZMA::XzEncoder.new(@options)
55
+
56
+ # Encode with optional size limit
57
+ # XZ encoder returns bytes written to output
58
+ encoder.encode(data, output)
59
+
60
+ # Return the encoded data string
61
+ output.string
62
+ end
63
+
64
+ # Get LZMA properties byte
65
+ #
66
+ # Encodes lc, lp, pb into single byte using formula:
67
+ # (pb * 5 + lp) * 9 + lc
68
+ #
69
+ # @return [Integer] Properties byte (0x00-0xFF)
70
+ def properties
71
+ (((@pb * 5) + @lp) * 9) + @lc
72
+ end
73
+
74
+ # Get dictionary size
75
+ #
76
+ # @return [Integer] Dictionary size in bytes
77
+ def dict_size
78
+ @options[:dict_size] || (1 << 23) # 8MB default
79
+ end
80
+ end
81
+
82
+ # Backward compatibility alias
83
+ XzEncoderAdapter = LZMA2XzEncoderAdapter unless defined?(XzEncoderAdapter)
84
+ end
85
+ end
@@ -0,0 +1,133 @@
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
+ require "stringio"
24
+
25
+ module Omnizip
26
+ module Algorithms
27
+ # LZMA2 compression algorithm
28
+ # Improved version of LZMA with chunked format for better streaming
29
+ class LZMA2 < Algorithm
30
+ # Nested classes - autoloaded
31
+ autoload :Constants, "omnizip/algorithms/lzma2/constants"
32
+ autoload :Properties, "omnizip/algorithms/lzma2/properties"
33
+ autoload :LZMA2Chunk, "omnizip/algorithms/lzma2/lzma2_chunk"
34
+ autoload :Encoder, "omnizip/algorithms/lzma2/encoder"
35
+ autoload :XzEncoderAdapter, "omnizip/algorithms/lzma2/xz_encoder_adapter"
36
+ autoload :LZMA2XzEncoderAdapter,
37
+ "omnizip/algorithms/lzma2/xz_encoder_adapter"
38
+ autoload :ChunkManager, "omnizip/algorithms/lzma2/chunk_manager"
39
+ autoload :SimpleLZMA2Encoder,
40
+ "omnizip/algorithms/lzma2/simple_lzma2_encoder"
41
+ end
42
+ end
43
+ end
44
+
45
+ module Omnizip
46
+ module Algorithms
47
+ class LZMA2 < Algorithm
48
+ class << self
49
+ # Get algorithm metadata
50
+ #
51
+ # @return [Models::AlgorithmMetadata] Algorithm metadata
52
+ def metadata
53
+ Models::AlgorithmMetadata.new.tap do |meta|
54
+ meta.name = "lzma2"
55
+ meta.description = "LZMA2 compression with improved chunking format for better streaming"
56
+ meta.version = "1.0.0"
57
+ meta.supports_streaming = true
58
+ end
59
+ end
60
+ end
61
+
62
+ def initialize(options = {})
63
+ super()
64
+ @dict_size = options[:dict_size] || (8 * 1024 * 1024) # 8 MB default
65
+ @lc = options[:lc] || 3
66
+ @lp = options[:lp] || 0
67
+ @pb = options[:pb] || 2
68
+ @level = options[:level] || 6
69
+ @raw_mode = options[:raw_mode] # For 7-Zip format (no property byte)
70
+ end
71
+
72
+ # Compress data using LZMA2
73
+ def compress(input, output, options = {})
74
+ # For 7-Zip format, use raw_mode (no property byte in data stream)
75
+ # Standalone LZMA2 files include a property byte
76
+ standalone = options.fetch(:standalone, true)
77
+ options.fetch(:raw_mode, !standalone)
78
+
79
+ encoder = LZMA2Encoder.new(
80
+ dict_size: @dict_size,
81
+ lc: @lc,
82
+ lp: @lp,
83
+ pb: @pb,
84
+ standalone: standalone, # Write property byte only for standalone files
85
+ )
86
+
87
+ # Read input
88
+ input_data = Omnizip::IO::Source.for(input).read
89
+
90
+ # Encode with LZMA2
91
+ compressed = encoder.encode(input_data)
92
+
93
+ # Write to output
94
+ Omnizip::IO::Sink.for(output).write(compressed)
95
+ end
96
+
97
+ # Decompress LZMA2 data
98
+ def decompress(input, output, options = {})
99
+ # Read input data
100
+ input_data = Omnizip::IO::Source.for(input).read
101
+ input_stream = StringIO.new(input_data)
102
+ input_stream.set_encoding(Encoding::BINARY)
103
+
104
+ # Determine raw_mode:
105
+ # - For 7-Zip format: raw_mode=true, dict_size from coder properties
106
+ # - For standalone LZMA2 files: raw_mode=false, dict_size from property byte
107
+ raw_mode = options.fetch(:raw_mode, @raw_mode || false)
108
+ dict_size = options.fetch(:dict_size, @dict_size)
109
+
110
+ # Create decoder using XZ Utils implementation
111
+ decoder = Omnizip::Implementations::XZUtils::LZMA2::Decoder.new(
112
+ input_stream,
113
+ raw_mode: raw_mode,
114
+ dict_size: dict_size,
115
+ )
116
+
117
+ # Decode LZMA2 data
118
+ decompressed = decoder.decode_stream
119
+
120
+ # Write to output
121
+ Omnizip::IO::Sink.for(output).write(decompressed)
122
+ end
123
+
124
+ # Encode dictionary size as single byte for LZMA2 properties
125
+ def self.encode_dict_size(dict_size)
126
+ LZMA2Encoder.encode_dict_size(dict_size)
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ # Auto-register LZMA2 in algorithm registry
133
+ Omnizip::Algorithms::LZMA2.register_algorithm