omnizip 0.4.7-aarch64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (632) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +32 -0
  4. data/.rubocop_todo.yml +293 -0
  5. data/CHANGELOG.md +1647 -0
  6. data/CONTEXT.md +68 -0
  7. data/COPYING +502 -0
  8. data/Gemfile +19 -0
  9. data/LICENSE +12 -0
  10. data/README.adoc +1327 -0
  11. data/Rakefile +15 -0
  12. data/TODO.refactor/00-overview.md +67 -0
  13. data/TODO.refactor/01-registry-base-class.md +81 -0
  14. data/TODO.refactor/02-error-hierarchy.md +57 -0
  15. data/TODO.refactor/03-autoload-entry-point.md +69 -0
  16. data/TODO.refactor/04-filter-base-consolidation.md +49 -0
  17. data/TODO.refactor/05-send-private-methods.md +64 -0
  18. data/TODO.refactor/06-instance-variable-access.md +69 -0
  19. data/TODO.refactor/07-respond-to-replacement.md +237 -0
  20. data/TODO.refactor/08-spec-doubles.md +27 -0
  21. data/TODO.refactor/09-cli-shared-module.md +35 -0
  22. data/TODO.refactor/10-format-detector-ocp.md +34 -0
  23. data/TODO.refactor/11-convenience-decoupling.md +38 -0
  24. data/TODO.refactor/12-thread-safety.md +8 -0
  25. data/TODO.refactor/13-lutaml-model-migration.md +158 -0
  26. data/TODO.refactor/14-add-missing-specs.md +25 -0
  27. data/benchmark/README.md +260 -0
  28. data/benchmark/benchmark_suite.rb +125 -0
  29. data/benchmark/compression_bench.rb +181 -0
  30. data/benchmark/filter_bench.rb +180 -0
  31. data/benchmark/models/benchmark_result.rb +59 -0
  32. data/benchmark/models/comparison_result.rb +69 -0
  33. data/benchmark/profile_suite.rb +167 -0
  34. data/benchmark/reporter.rb +150 -0
  35. data/benchmark/run_benchmarks.rb +66 -0
  36. data/benchmark/test_data.rb +137 -0
  37. data/config/formats/rar3_spec.yml +92 -0
  38. data/config/formats/rar5_spec.yml +102 -0
  39. data/docs/.github/workflows/docs.yml +142 -0
  40. data/docs/.gitignore +21 -0
  41. data/docs/.lychee.toml +67 -0
  42. data/docs/Gemfile +13 -0
  43. data/docs/RAR_WRITE_SUPPORT.md +26 -0
  44. data/docs/README.md +101 -0
  45. data/docs/_config.yml +112 -0
  46. data/docs/assets/logo.svg +1 -0
  47. data/docs/assets/omnizip-logo.pdf +1540 -11
  48. data/docs/comparison/feature-matrix.adoc +694 -0
  49. data/docs/comparison/index.adoc +113 -0
  50. data/docs/comparison/vs-7zip.adoc +309 -0
  51. data/docs/comparison/vs-peazip.adoc +77 -0
  52. data/docs/comparison/vs-rubyzip.adoc +342 -0
  53. data/docs/comparison/vs-winrar.adoc +100 -0
  54. data/docs/compatibility.adoc +579 -0
  55. data/docs/concepts/index.adoc +129 -0
  56. data/docs/developer/architecture.adoc +256 -0
  57. data/docs/developer/contributing.adoc +158 -0
  58. data/docs/developer/index.adoc +25 -0
  59. data/docs/developer/testing.adoc +212 -0
  60. data/docs/getting-started/basic-usage.adoc +263 -0
  61. data/docs/getting-started/index.adoc +42 -0
  62. data/docs/getting-started/installation.adoc +138 -0
  63. data/docs/getting-started/quick-start.adoc +183 -0
  64. data/docs/getting-started/your-first-archive.adoc +219 -0
  65. data/docs/guides/advanced-features/encryption.adoc +277 -0
  66. data/docs/guides/advanced-features/index.adoc +59 -0
  67. data/docs/guides/advanced-features/parallel-processing.adoc +144 -0
  68. data/docs/guides/advanced-features/progress-tracking.adoc +124 -0
  69. data/docs/guides/advanced-features/streaming.adoc +142 -0
  70. data/docs/guides/archive-formats/gzip-format.adoc +105 -0
  71. data/docs/guides/archive-formats/index.adoc +160 -0
  72. data/docs/guides/archive-formats/ole-format.adoc +151 -0
  73. data/docs/guides/archive-formats/rar-format.adoc +104 -0
  74. data/docs/guides/archive-formats/rar5.adoc +521 -0
  75. data/docs/guides/archive-formats/rpm-format.adoc +108 -0
  76. data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
  77. data/docs/guides/archive-formats/tar-format.adoc +106 -0
  78. data/docs/guides/archive-formats/xz-format.adoc +118 -0
  79. data/docs/guides/archive-formats/zip-format.adoc +35 -0
  80. data/docs/guides/compression-algorithms/bzip2.adoc +114 -0
  81. data/docs/guides/compression-algorithms/deflate.adoc +313 -0
  82. data/docs/guides/compression-algorithms/index.adoc +190 -0
  83. data/docs/guides/compression-algorithms/lzma.adoc +394 -0
  84. data/docs/guides/compression-algorithms/lzma2.adoc +244 -0
  85. data/docs/guides/compression-algorithms/ppmd.adoc +313 -0
  86. data/docs/guides/compression-algorithms/zstandard.adoc +296 -0
  87. data/docs/guides/creating-archives.adoc +348 -0
  88. data/docs/guides/extracting-archives.adoc +53 -0
  89. data/docs/guides/format-conversion.adoc +64 -0
  90. data/docs/guides/index.adoc +49 -0
  91. data/docs/guides/migration-rubyzip.adoc +217 -0
  92. data/docs/guides/parity-archives.adoc +605 -0
  93. data/docs/guides/performance-tuning.adoc +88 -0
  94. data/docs/index.adoc +228 -0
  95. data/docs/lychee.toml +67 -0
  96. data/docs/reference/api/overview.adoc +187 -0
  97. data/docs/reference/cli/compress-command.adoc +114 -0
  98. data/docs/reference/cli/overview.adoc +140 -0
  99. data/docs/reference/index.adoc +26 -0
  100. data/docs/resources/faq.adoc +185 -0
  101. data/docs/resources/quick-reference.adoc +222 -0
  102. data/docs/rust-backend.md +0 -0
  103. data/docs/troubleshooting/index.adoc +207 -0
  104. data/docs/xar_format.md +216 -0
  105. data/examples/api_comparison.rb +205 -0
  106. data/examples/deflate64_example.rb +96 -0
  107. data/examples/par2_demo.rb +121 -0
  108. data/examples/quick_start_native.rb +150 -0
  109. data/examples/quick_start_rubyzip.rb +115 -0
  110. data/examples/rubyzip_compatibility_demo.rb +194 -0
  111. data/exe/omnizip +27 -0
  112. data/lib/omnizip/algorithm.rb +176 -0
  113. data/lib/omnizip/algorithm_registry.rb +65 -0
  114. data/lib/omnizip/algorithms/.keep +0 -0
  115. data/lib/omnizip/algorithms/bzip2/bwt.rb +236 -0
  116. data/lib/omnizip/algorithms/bzip2/bz2.rb +687 -0
  117. data/lib/omnizip/algorithms/bzip2/rle.rb +146 -0
  118. data/lib/omnizip/algorithms/bzip2.rb +108 -0
  119. data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
  120. data/lib/omnizip/algorithms/deflate/decoder.rb +37 -0
  121. data/lib/omnizip/algorithms/deflate/encoder.rb +45 -0
  122. data/lib/omnizip/algorithms/deflate.rb +135 -0
  123. data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
  124. data/lib/omnizip/algorithms/deflate64/decoder.rb +151 -0
  125. data/lib/omnizip/algorithms/deflate64/encoder.rb +95 -0
  126. data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +352 -0
  127. data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +140 -0
  128. data/lib/omnizip/algorithms/deflate64.rb +118 -0
  129. data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
  130. data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
  131. data/lib/omnizip/algorithms/lzma/decoder.rb +146 -0
  132. data/lib/omnizip/algorithms/lzma/dictionary.rb +70 -0
  133. data/lib/omnizip/algorithms/lzma/distance_coder.rb +326 -0
  134. data/lib/omnizip/algorithms/lzma/encoder.rb +139 -0
  135. data/lib/omnizip/algorithms/lzma/length_coder.rb +172 -0
  136. data/lib/omnizip/algorithms/lzma/literal_decoder.rb +204 -0
  137. data/lib/omnizip/algorithms/lzma/literal_encoder.rb +208 -0
  138. data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +368 -0
  139. data/lib/omnizip/algorithms/lzma/lzma1_encoder.rb +105 -0
  140. data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +194 -0
  141. data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
  142. data/lib/omnizip/algorithms/lzma/match.rb +32 -0
  143. data/lib/omnizip/algorithms/lzma/match_finder.rb +233 -0
  144. data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
  145. data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +84 -0
  146. data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +159 -0
  147. data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
  148. data/lib/omnizip/algorithms/lzma/range_coder.rb +82 -0
  149. data/lib/omnizip/algorithms/lzma/range_decoder.rb +274 -0
  150. data/lib/omnizip/algorithms/lzma/range_encoder.rb +202 -0
  151. data/lib/omnizip/algorithms/lzma/state.rb +127 -0
  152. data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +323 -0
  153. data/lib/omnizip/algorithms/lzma/xz_encoder.rb +420 -0
  154. data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +640 -0
  155. data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +224 -0
  156. data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +167 -0
  157. data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +258 -0
  158. data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
  159. data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +314 -0
  160. data/lib/omnizip/algorithms/lzma/xz_state.rb +108 -0
  161. data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +1311 -0
  162. data/lib/omnizip/algorithms/lzma.rb +266 -0
  163. data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +180 -0
  164. data/lib/omnizip/algorithms/lzma2/constants.rb +38 -0
  165. data/lib/omnizip/algorithms/lzma2/encoder.rb +145 -0
  166. data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +165 -0
  167. data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
  168. data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +122 -0
  169. data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
  170. data/lib/omnizip/algorithms/lzma2.rb +133 -0
  171. data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
  172. data/lib/omnizip/algorithms/ppmd7/context.rb +151 -0
  173. data/lib/omnizip/algorithms/ppmd7/decoder.rb +127 -0
  174. data/lib/omnizip/algorithms/ppmd7/encoder.rb +153 -0
  175. data/lib/omnizip/algorithms/ppmd7/model.rb +245 -0
  176. data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
  177. data/lib/omnizip/algorithms/ppmd7.rb +146 -0
  178. data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
  179. data/lib/omnizip/algorithms/ppmd8/context.rb +32 -0
  180. data/lib/omnizip/algorithms/ppmd8/decoder.rb +104 -0
  181. data/lib/omnizip/algorithms/ppmd8/encoder.rb +135 -0
  182. data/lib/omnizip/algorithms/ppmd8/model.rb +246 -0
  183. data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
  184. data/lib/omnizip/algorithms/ppmd8.rb +122 -0
  185. data/lib/omnizip/algorithms/ppmd_base.rb +142 -0
  186. data/lib/omnizip/algorithms/registration.rb +28 -0
  187. data/lib/omnizip/algorithms/zstandard/constants.rb +158 -0
  188. data/lib/omnizip/algorithms/zstandard/decoder.rb +249 -0
  189. data/lib/omnizip/algorithms/zstandard/dictionary.rb +73 -0
  190. data/lib/omnizip/algorithms/zstandard/encoder.rb +294 -0
  191. data/lib/omnizip/algorithms/zstandard/frame/block.rb +143 -0
  192. data/lib/omnizip/algorithms/zstandard/frame/header.rb +233 -0
  193. data/lib/omnizip/algorithms/zstandard/frame.rb +33 -0
  194. data/lib/omnizip/algorithms/zstandard/fse/bitstream.rb +183 -0
  195. data/lib/omnizip/algorithms/zstandard/fse/encoder.rb +534 -0
  196. data/lib/omnizip/algorithms/zstandard/fse/interleaved.rb +92 -0
  197. data/lib/omnizip/algorithms/zstandard/fse/table.rb +188 -0
  198. data/lib/omnizip/algorithms/zstandard/fse/table_description.rb +203 -0
  199. data/lib/omnizip/algorithms/zstandard/fse.rb +53 -0
  200. data/lib/omnizip/algorithms/zstandard/huffman.rb +276 -0
  201. data/lib/omnizip/algorithms/zstandard/huffman_encoder.rb +327 -0
  202. data/lib/omnizip/algorithms/zstandard/ldm.rb +121 -0
  203. data/lib/omnizip/algorithms/zstandard/literals.rb +241 -0
  204. data/lib/omnizip/algorithms/zstandard/literals_encoder.rb +96 -0
  205. data/lib/omnizip/algorithms/zstandard/match_finder.rb +483 -0
  206. data/lib/omnizip/algorithms/zstandard/sequences.rb +350 -0
  207. data/lib/omnizip/algorithms/zstandard/sequences_encoder.rb +333 -0
  208. data/lib/omnizip/algorithms/zstandard/xxhash.rb +159 -0
  209. data/lib/omnizip/algorithms/zstandard.rb +210 -0
  210. data/lib/omnizip/algorithms.rb +35 -0
  211. data/lib/omnizip/archive/builder.rb +48 -0
  212. data/lib/omnizip/archive/reader_session.rb +67 -0
  213. data/lib/omnizip/archive.rb +86 -0
  214. data/lib/omnizip/archive_handler.rb +82 -0
  215. data/lib/omnizip/archive_handlers/cpio_handler.rb +47 -0
  216. data/lib/omnizip/archive_handlers/iso_handler.rb +54 -0
  217. data/lib/omnizip/archive_handlers/ole_handler.rb +37 -0
  218. data/lib/omnizip/archive_handlers/rar_handler.rb +96 -0
  219. data/lib/omnizip/archive_handlers/rpm_handler.rb +45 -0
  220. data/lib/omnizip/archive_handlers/seven_zip_handler.rb +89 -0
  221. data/lib/omnizip/archive_handlers/tar_handler.rb +75 -0
  222. data/lib/omnizip/archive_handlers/xar_handler.rb +49 -0
  223. data/lib/omnizip/archive_handlers/zip_handler.rb +115 -0
  224. data/lib/omnizip/archive_handlers.rb +18 -0
  225. data/lib/omnizip/backends.rb +160 -0
  226. data/lib/omnizip/buffer/memory_archive.rb +246 -0
  227. data/lib/omnizip/buffer/memory_extractor.rb +234 -0
  228. data/lib/omnizip/buffer/seven_zip_bridge.rb +171 -0
  229. data/lib/omnizip/buffer.rb +187 -0
  230. data/lib/omnizip/checksum_registry.rb +41 -0
  231. data/lib/omnizip/checksums/crc32.rb +101 -0
  232. data/lib/omnizip/checksums/crc64.rb +102 -0
  233. data/lib/omnizip/checksums/crc_base.rb +158 -0
  234. data/lib/omnizip/checksums/registration.rb +16 -0
  235. data/lib/omnizip/checksums/verifier.rb +130 -0
  236. data/lib/omnizip/checksums.rb +11 -0
  237. data/lib/omnizip/chunked/memory_manager.rb +194 -0
  238. data/lib/omnizip/chunked/reader.rb +78 -0
  239. data/lib/omnizip/chunked/writer.rb +123 -0
  240. data/lib/omnizip/chunked.rb +123 -0
  241. data/lib/omnizip/cli/output_formatter.rb +112 -0
  242. data/lib/omnizip/cli.rb +604 -0
  243. data/lib/omnizip/commands/.keep +0 -0
  244. data/lib/omnizip/commands/archive_create_command.rb +245 -0
  245. data/lib/omnizip/commands/archive_extract_command.rb +231 -0
  246. data/lib/omnizip/commands/archive_list_command.rb +204 -0
  247. data/lib/omnizip/commands/archive_repair_command.rb +129 -0
  248. data/lib/omnizip/commands/archive_verify_command.rb +115 -0
  249. data/lib/omnizip/commands/compress_command.rb +115 -0
  250. data/lib/omnizip/commands/decompress_command.rb +149 -0
  251. data/lib/omnizip/commands/list_command.rb +51 -0
  252. data/lib/omnizip/commands/metadata_command.rb +215 -0
  253. data/lib/omnizip/commands/parity_create_command.rb +114 -0
  254. data/lib/omnizip/commands/parity_repair_command.rb +120 -0
  255. data/lib/omnizip/commands/parity_verify_command.rb +122 -0
  256. data/lib/omnizip/commands/profile_list_command.rb +54 -0
  257. data/lib/omnizip/commands/profile_show_command.rb +44 -0
  258. data/lib/omnizip/commands.rb +21 -0
  259. data/lib/omnizip/convenience.rb +389 -0
  260. data/lib/omnizip/converter/conversion_registry.rb +50 -0
  261. data/lib/omnizip/converter/conversion_strategy.rb +108 -0
  262. data/lib/omnizip/converter/extract_repack_strategy.rb +51 -0
  263. data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +43 -0
  264. data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +54 -0
  265. data/lib/omnizip/converter.rb +124 -0
  266. data/lib/omnizip/crypto/aes256/cipher.rb +104 -0
  267. data/lib/omnizip/crypto/aes256/constants.rb +28 -0
  268. data/lib/omnizip/crypto/aes256/key_derivation.rb +100 -0
  269. data/lib/omnizip/crypto/aes256.rb +102 -0
  270. data/lib/omnizip/crypto.rb +11 -0
  271. data/lib/omnizip/entry.rb +44 -0
  272. data/lib/omnizip/error.rb +110 -0
  273. data/lib/omnizip/eta/exponential_smoothing_estimator.rb +95 -0
  274. data/lib/omnizip/eta/moving_average_estimator.rb +96 -0
  275. data/lib/omnizip/eta/rate_calculator.rb +104 -0
  276. data/lib/omnizip/eta/sample_history.rb +143 -0
  277. data/lib/omnizip/eta/time_estimator.rb +106 -0
  278. data/lib/omnizip/eta.rb +68 -0
  279. data/lib/omnizip/extraction/filter_chain.rb +179 -0
  280. data/lib/omnizip/extraction/glob_pattern.rb +140 -0
  281. data/lib/omnizip/extraction/pattern_matcher.rb +66 -0
  282. data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
  283. data/lib/omnizip/extraction/regex_pattern.rb +50 -0
  284. data/lib/omnizip/extraction/selective_extractor.rb +247 -0
  285. data/lib/omnizip/extraction.rb +115 -0
  286. data/lib/omnizip/file_type/mime_classifier.rb +144 -0
  287. data/lib/omnizip/file_type.rb +117 -0
  288. data/lib/omnizip/filter.rb +141 -0
  289. data/lib/omnizip/filter_pipeline.rb +108 -0
  290. data/lib/omnizip/filter_registry.rb +113 -0
  291. data/lib/omnizip/filters/bcj.rb +277 -0
  292. data/lib/omnizip/filters/bcj2/constants.rb +53 -0
  293. data/lib/omnizip/filters/bcj2/decoder.rb +263 -0
  294. data/lib/omnizip/filters/bcj2/encoder.rb +58 -0
  295. data/lib/omnizip/filters/bcj2/stream_data.rb +91 -0
  296. data/lib/omnizip/filters/bcj2.rb +93 -0
  297. data/lib/omnizip/filters/bcj_arm.rb +174 -0
  298. data/lib/omnizip/filters/bcj_arm64.rb +242 -0
  299. data/lib/omnizip/filters/bcj_ia64.rb +194 -0
  300. data/lib/omnizip/filters/bcj_ppc.rb +188 -0
  301. data/lib/omnizip/filters/bcj_sparc.rb +174 -0
  302. data/lib/omnizip/filters/bcj_x86.rb +191 -0
  303. data/lib/omnizip/filters/delta.rb +195 -0
  304. data/lib/omnizip/filters/xz_delta.rb +258 -0
  305. data/lib/omnizip/filters.rb +20 -0
  306. data/lib/omnizip/format_detector.rb +166 -0
  307. data/lib/omnizip/formats/.keep +0 -0
  308. data/lib/omnizip/formats/bzip2_file.rb +159 -0
  309. data/lib/omnizip/formats/cpio/bounded_io.rb +66 -0
  310. data/lib/omnizip/formats/cpio/constants.rb +55 -0
  311. data/lib/omnizip/formats/cpio/entry.rb +389 -0
  312. data/lib/omnizip/formats/cpio/reader.rb +194 -0
  313. data/lib/omnizip/formats/cpio/writer.rb +232 -0
  314. data/lib/omnizip/formats/cpio.rb +132 -0
  315. data/lib/omnizip/formats/format_spec_loader.rb +228 -0
  316. data/lib/omnizip/formats/gzip.rb +236 -0
  317. data/lib/omnizip/formats/iso/directory_builder.rb +321 -0
  318. data/lib/omnizip/formats/iso/directory_record.rb +162 -0
  319. data/lib/omnizip/formats/iso/joliet.rb +204 -0
  320. data/lib/omnizip/formats/iso/path_table.rb +125 -0
  321. data/lib/omnizip/formats/iso/reader.rb +194 -0
  322. data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
  323. data/lib/omnizip/formats/iso/volume_builder.rb +319 -0
  324. data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
  325. data/lib/omnizip/formats/iso/writer.rb +543 -0
  326. data/lib/omnizip/formats/iso.rb +133 -0
  327. data/lib/omnizip/formats/lzip.rb +161 -0
  328. data/lib/omnizip/formats/lzma_alone.rb +149 -0
  329. data/lib/omnizip/formats/msi/cab_extractor.rb +181 -0
  330. data/lib/omnizip/formats/msi/constants.rb +157 -0
  331. data/lib/omnizip/formats/msi/directory_resolver.rb +188 -0
  332. data/lib/omnizip/formats/msi/entry.rb +134 -0
  333. data/lib/omnizip/formats/msi/reader.rb +301 -0
  334. data/lib/omnizip/formats/msi/string_pool.rb +246 -0
  335. data/lib/omnizip/formats/msi/table_parser.rb +244 -0
  336. data/lib/omnizip/formats/msi.rb +73 -0
  337. data/lib/omnizip/formats/ole/allocation_table.rb +263 -0
  338. data/lib/omnizip/formats/ole/constants.rb +61 -0
  339. data/lib/omnizip/formats/ole/dirent.rb +439 -0
  340. data/lib/omnizip/formats/ole/header.rb +199 -0
  341. data/lib/omnizip/formats/ole/ranges_io.rb +347 -0
  342. data/lib/omnizip/formats/ole/storage.rb +482 -0
  343. data/lib/omnizip/formats/ole/types/variant.rb +338 -0
  344. data/lib/omnizip/formats/ole.rb +143 -0
  345. data/lib/omnizip/formats/rar/archive_repairer.rb +240 -0
  346. data/lib/omnizip/formats/rar/archive_verifier.rb +192 -0
  347. data/lib/omnizip/formats/rar/block_parser.rb +282 -0
  348. data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
  349. data/lib/omnizip/formats/rar/compression/dispatcher.rb +210 -0
  350. data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +212 -0
  351. data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +154 -0
  352. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
  353. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
  354. data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
  355. data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
  356. data/lib/omnizip/formats/rar/compression/lz77_huffman.rb +25 -0
  357. data/lib/omnizip/formats/rar/compression/ppmd/context.rb +103 -0
  358. data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +238 -0
  359. data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +250 -0
  360. data/lib/omnizip/formats/rar/compression/ppmd.rb +16 -0
  361. data/lib/omnizip/formats/rar/compression.rb +17 -0
  362. data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
  363. data/lib/omnizip/formats/rar/constants.rb +88 -0
  364. data/lib/omnizip/formats/rar/decompressor.rb +316 -0
  365. data/lib/omnizip/formats/rar/external_writer.rb +311 -0
  366. data/lib/omnizip/formats/rar/header.rb +209 -0
  367. data/lib/omnizip/formats/rar/license_validator.rb +111 -0
  368. data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
  369. data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
  370. data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
  371. data/lib/omnizip/formats/rar/models.rb +14 -0
  372. data/lib/omnizip/formats/rar/parity_handler.rb +299 -0
  373. data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +200 -0
  374. data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +584 -0
  375. data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
  376. data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
  377. data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +96 -0
  378. data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
  379. data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +162 -0
  380. data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
  381. data/lib/omnizip/formats/rar/rar5/header.rb +208 -0
  382. data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
  383. data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
  384. data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
  385. data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
  386. data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
  387. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +260 -0
  388. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
  389. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +176 -0
  390. data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +108 -0
  391. data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +139 -0
  392. data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
  393. data/lib/omnizip/formats/rar/rar5/vint.rb +53 -0
  394. data/lib/omnizip/formats/rar/rar5/writer.rb +540 -0
  395. data/lib/omnizip/formats/rar/rar_format_base.rb +239 -0
  396. data/lib/omnizip/formats/rar/reader.rb +377 -0
  397. data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
  398. data/lib/omnizip/formats/rar/volume_manager.rb +166 -0
  399. data/lib/omnizip/formats/rar/writer.rb +437 -0
  400. data/lib/omnizip/formats/rar.rb +193 -0
  401. data/lib/omnizip/formats/rar3/compressor.rb +71 -0
  402. data/lib/omnizip/formats/rar3/decompressor.rb +64 -0
  403. data/lib/omnizip/formats/rar3/reader.rb +107 -0
  404. data/lib/omnizip/formats/rar3/writer.rb +220 -0
  405. data/lib/omnizip/formats/rar3.rb +15 -0
  406. data/lib/omnizip/formats/rar5/compressor.rb +71 -0
  407. data/lib/omnizip/formats/rar5/decompressor.rb +64 -0
  408. data/lib/omnizip/formats/rar5/reader.rb +130 -0
  409. data/lib/omnizip/formats/rar5/writer.rb +65 -0
  410. data/lib/omnizip/formats/rar5.rb +15 -0
  411. data/lib/omnizip/formats/rpm/constants.rb +58 -0
  412. data/lib/omnizip/formats/rpm/entry.rb +106 -0
  413. data/lib/omnizip/formats/rpm/header.rb +106 -0
  414. data/lib/omnizip/formats/rpm/lead.rb +132 -0
  415. data/lib/omnizip/formats/rpm/tag.rb +228 -0
  416. data/lib/omnizip/formats/rpm/writer.rb +652 -0
  417. data/lib/omnizip/formats/rpm.rb +458 -0
  418. data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +274 -0
  419. data/lib/omnizip/formats/seven_zip/coder_chain.rb +169 -0
  420. data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
  421. data/lib/omnizip/formats/seven_zip/encoded_header.rb +110 -0
  422. data/lib/omnizip/formats/seven_zip/encrypted_header.rb +139 -0
  423. data/lib/omnizip/formats/seven_zip/file_collector.rb +143 -0
  424. data/lib/omnizip/formats/seven_zip/header.rb +102 -0
  425. data/lib/omnizip/formats/seven_zip/header_encryptor.rb +132 -0
  426. data/lib/omnizip/formats/seven_zip/header_writer.rb +425 -0
  427. data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
  428. data/lib/omnizip/formats/seven_zip/models/file_entry.rb +65 -0
  429. data/lib/omnizip/formats/seven_zip/models/folder.rb +67 -0
  430. data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
  431. data/lib/omnizip/formats/seven_zip/models.rb +20 -0
  432. data/lib/omnizip/formats/seven_zip/parser.rb +671 -0
  433. data/lib/omnizip/formats/seven_zip/reader.rb +626 -0
  434. data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +611 -0
  435. data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +308 -0
  436. data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
  437. data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +166 -0
  438. data/lib/omnizip/formats/seven_zip/writer.rb +801 -0
  439. data/lib/omnizip/formats/seven_zip.rb +179 -0
  440. data/lib/omnizip/formats/tar/constants.rb +73 -0
  441. data/lib/omnizip/formats/tar/entry.rb +98 -0
  442. data/lib/omnizip/formats/tar/header.rb +206 -0
  443. data/lib/omnizip/formats/tar/reader.rb +119 -0
  444. data/lib/omnizip/formats/tar/writer.rb +212 -0
  445. data/lib/omnizip/formats/tar.rb +74 -0
  446. data/lib/omnizip/formats/xar/constants.rb +119 -0
  447. data/lib/omnizip/formats/xar/entry.rb +268 -0
  448. data/lib/omnizip/formats/xar/header.rb +223 -0
  449. data/lib/omnizip/formats/xar/reader.rb +400 -0
  450. data/lib/omnizip/formats/xar/toc.rb +570 -0
  451. data/lib/omnizip/formats/xar/writer.rb +461 -0
  452. data/lib/omnizip/formats/xar.rb +145 -0
  453. data/lib/omnizip/formats/xz/reader.rb +121 -0
  454. data/lib/omnizip/formats/xz/writer.rb +416 -0
  455. data/lib/omnizip/formats/xz.rb +210 -0
  456. data/lib/omnizip/formats/xz_const.rb +49 -0
  457. data/lib/omnizip/formats/xz_impl/block_decoder.rb +761 -0
  458. data/lib/omnizip/formats/xz_impl/block_encoder.rb +304 -0
  459. data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
  460. data/lib/omnizip/formats/xz_impl/block_header_parser.rb +182 -0
  461. data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
  462. data/lib/omnizip/formats/xz_impl/index_encoder.rb +120 -0
  463. data/lib/omnizip/formats/xz_impl/stream_decoder.rb +470 -0
  464. data/lib/omnizip/formats/xz_impl/stream_encoder.rb +95 -0
  465. data/lib/omnizip/formats/xz_impl/stream_footer.rb +79 -0
  466. data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +115 -0
  467. data/lib/omnizip/formats/xz_impl/stream_header.rb +53 -0
  468. data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +106 -0
  469. data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
  470. data/lib/omnizip/formats/xz_impl.rb +52 -0
  471. data/lib/omnizip/formats/zip/central_directory_header.rb +223 -0
  472. data/lib/omnizip/formats/zip/constants.rb +69 -0
  473. data/lib/omnizip/formats/zip/end_of_central_directory.rb +132 -0
  474. data/lib/omnizip/formats/zip/local_file_header.rb +136 -0
  475. data/lib/omnizip/formats/zip/reader.rb +376 -0
  476. data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
  477. data/lib/omnizip/formats/zip/writer.rb +489 -0
  478. data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +102 -0
  479. data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +64 -0
  480. data/lib/omnizip/formats/zip/zip64_extra_field.rb +112 -0
  481. data/lib/omnizip/formats/zip.rb +50 -0
  482. data/lib/omnizip/formats.rb +29 -0
  483. data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
  484. data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
  485. data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
  486. data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
  487. data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
  488. data/lib/omnizip/implementations/base.rb +19 -0
  489. data/lib/omnizip/implementations/rust/archive.rb +93 -0
  490. data/lib/omnizip/implementations/rust/library.rb +221 -0
  491. data/lib/omnizip/implementations/rust.rb +26 -0
  492. data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +428 -0
  493. data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +456 -0
  494. data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +285 -0
  495. data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +197 -0
  496. data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +194 -0
  497. data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +139 -0
  498. data/lib/omnizip/implementations/seven_zip/lzma.rb +21 -0
  499. data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +56 -0
  500. data/lib/omnizip/implementations/seven_zip/lzma2.rb +12 -0
  501. data/lib/omnizip/implementations/seven_zip.rb +11 -0
  502. data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +547 -0
  503. data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +748 -0
  504. data/lib/omnizip/implementations/xz_utils/lzma2.rb +13 -0
  505. data/lib/omnizip/implementations/xz_utils.rb +10 -0
  506. data/lib/omnizip/implementations.rb +25 -0
  507. data/lib/omnizip/io/buffered_input.rb +147 -0
  508. data/lib/omnizip/io/buffered_output.rb +106 -0
  509. data/lib/omnizip/io/source.rb +143 -0
  510. data/lib/omnizip/io/stream_manager.rb +117 -0
  511. data/lib/omnizip/io.rb +15 -0
  512. data/lib/omnizip/link_handler/hard_link.rb +79 -0
  513. data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
  514. data/lib/omnizip/link_handler.rb +129 -0
  515. data/lib/omnizip/metadata/archive_metadata.rb +114 -0
  516. data/lib/omnizip/metadata/entry_metadata.rb +153 -0
  517. data/lib/omnizip/metadata/metadata_editor.rb +169 -0
  518. data/lib/omnizip/metadata/metadata_registry.rb +71 -0
  519. data/lib/omnizip/metadata/metadata_validator.rb +101 -0
  520. data/lib/omnizip/metadata.rb +58 -0
  521. data/lib/omnizip/models/.keep +0 -0
  522. data/lib/omnizip/models/algorithm_metadata.rb +41 -0
  523. data/lib/omnizip/models/attribute_apply.rb +40 -0
  524. data/lib/omnizip/models/compression_options.rb +53 -0
  525. data/lib/omnizip/models/conversion_options.rb +79 -0
  526. data/lib/omnizip/models/conversion_result.rb +141 -0
  527. data/lib/omnizip/models/eta_result.rb +45 -0
  528. data/lib/omnizip/models/extraction_rule.rb +115 -0
  529. data/lib/omnizip/models/filter_chain.rb +142 -0
  530. data/lib/omnizip/models/filter_config.rb +148 -0
  531. data/lib/omnizip/models/match_result.rb +141 -0
  532. data/lib/omnizip/models/optimization_suggestion.rb +95 -0
  533. data/lib/omnizip/models/parallel_options.rb +116 -0
  534. data/lib/omnizip/models/performance_result.rb +85 -0
  535. data/lib/omnizip/models/profile_report.rb +116 -0
  536. data/lib/omnizip/models/progress_options.rb +39 -0
  537. data/lib/omnizip/models/split_options.rb +116 -0
  538. data/lib/omnizip/optimization_registry.rb +45 -0
  539. data/lib/omnizip/parallel/engine.rb +52 -0
  540. data/lib/omnizip/parallel/job_queue.rb +209 -0
  541. data/lib/omnizip/parallel/job_scheduler.rb +225 -0
  542. data/lib/omnizip/parallel/parallel_compressor.rb +326 -0
  543. data/lib/omnizip/parallel/parallel_extractor.rb +238 -0
  544. data/lib/omnizip/parallel/thread_pool.rb +60 -0
  545. data/lib/omnizip/parallel/worker_pool.rb +227 -0
  546. data/lib/omnizip/parallel.rb +156 -0
  547. data/lib/omnizip/parity/chunked_block_processor.rb +194 -0
  548. data/lib/omnizip/parity/galois16.rb +145 -0
  549. data/lib/omnizip/parity/models/creator_packet.rb +71 -0
  550. data/lib/omnizip/parity/models/file_description_packet.rb +131 -0
  551. data/lib/omnizip/parity/models/ifsc_packet.rb +111 -0
  552. data/lib/omnizip/parity/models/main_packet.rb +126 -0
  553. data/lib/omnizip/parity/models/packet.rb +156 -0
  554. data/lib/omnizip/parity/models/packet_registry.rb +102 -0
  555. data/lib/omnizip/parity/models/recovery_slice_packet.rb +76 -0
  556. data/lib/omnizip/parity/models.rb +27 -0
  557. data/lib/omnizip/parity/par2_creator.rb +496 -0
  558. data/lib/omnizip/parity/par2_repairer.rb +409 -0
  559. data/lib/omnizip/parity/par2_verifier.rb +373 -0
  560. data/lib/omnizip/parity/par2cmdline_algorithm.rb +108 -0
  561. data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
  562. data/lib/omnizip/parity/reed_solomon_decoder.rb +263 -0
  563. data/lib/omnizip/parity/reed_solomon_encoder.rb +108 -0
  564. data/lib/omnizip/parity/reed_solomon_matrix.rb +339 -0
  565. data/lib/omnizip/parity.rb +207 -0
  566. data/lib/omnizip/password/encryption_registry.rb +26 -0
  567. data/lib/omnizip/password/encryption_strategy.rb +96 -0
  568. data/lib/omnizip/password/password_validator.rb +129 -0
  569. data/lib/omnizip/password/winzip_aes_strategy.rb +190 -0
  570. data/lib/omnizip/password/zip_crypto_strategy.rb +135 -0
  571. data/lib/omnizip/password.rb +88 -0
  572. data/lib/omnizip/pipe/stream_compressor.rb +124 -0
  573. data/lib/omnizip/pipe/stream_decompressor.rb +173 -0
  574. data/lib/omnizip/pipe.rb +120 -0
  575. data/lib/omnizip/platform/ntfs_streams.rb +200 -0
  576. data/lib/omnizip/platform.rb +189 -0
  577. data/lib/omnizip/profile/archive_profile.rb +36 -0
  578. data/lib/omnizip/profile/balanced_profile.rb +31 -0
  579. data/lib/omnizip/profile/binary_profile.rb +33 -0
  580. data/lib/omnizip/profile/compression_profile.rb +157 -0
  581. data/lib/omnizip/profile/custom_profile.rb +155 -0
  582. data/lib/omnizip/profile/fast_profile.rb +31 -0
  583. data/lib/omnizip/profile/maximum_profile.rb +31 -0
  584. data/lib/omnizip/profile/profile_detector.rb +108 -0
  585. data/lib/omnizip/profile/profile_registry.rb +160 -0
  586. data/lib/omnizip/profile/text_profile.rb +33 -0
  587. data/lib/omnizip/profile.rb +261 -0
  588. data/lib/omnizip/profiler/memory_profiler.rb +66 -0
  589. data/lib/omnizip/profiler/method_profiler.rb +49 -0
  590. data/lib/omnizip/profiler/report_generator.rb +158 -0
  591. data/lib/omnizip/profiler.rb +192 -0
  592. data/lib/omnizip/progress/callback_reporter.rb +34 -0
  593. data/lib/omnizip/progress/console_reporter.rb +59 -0
  594. data/lib/omnizip/progress/log_reporter.rb +89 -0
  595. data/lib/omnizip/progress/operation_progress.rb +118 -0
  596. data/lib/omnizip/progress/progress_bar.rb +156 -0
  597. data/lib/omnizip/progress/progress_reporter.rb +40 -0
  598. data/lib/omnizip/progress/progress_tracker.rb +215 -0
  599. data/lib/omnizip/progress/silent_reporter.rb +22 -0
  600. data/lib/omnizip/progress.rb +131 -0
  601. data/lib/omnizip/registry.rb +111 -0
  602. data/lib/omnizip/rubyzip_compat.rb +61 -0
  603. data/lib/omnizip/temp/safe_extract.rb +124 -0
  604. data/lib/omnizip/temp/temp_file.rb +123 -0
  605. data/lib/omnizip/temp/temp_file_pool.rb +109 -0
  606. data/lib/omnizip/temp.rb +184 -0
  607. data/lib/omnizip/version.rb +5 -0
  608. data/lib/omnizip/zip/entry.rb +160 -0
  609. data/lib/omnizip/zip/file.rb +485 -0
  610. data/lib/omnizip/zip/input_stream.rb +270 -0
  611. data/lib/omnizip/zip/output_stream.rb +320 -0
  612. data/lib/omnizip/zip.rb +23 -0
  613. data/lib/omnizip.rb +157 -0
  614. data/lib/tasks/msi_test_files.rake +66 -0
  615. data/lib/tasks/platform_gems.rake +147 -0
  616. data/lib/tasks/rust_backend.rake +48 -0
  617. data/readme-docs/advanced-features.adoc +514 -0
  618. data/readme-docs/api-usage.adoc +445 -0
  619. data/readme-docs/architecture.adoc +450 -0
  620. data/readme-docs/archive-formats.adoc +479 -0
  621. data/readme-docs/cli-usage.adoc +222 -0
  622. data/readme-docs/compression-algorithms.adoc +446 -0
  623. data/readme-docs/compression-profiles.adoc +247 -0
  624. data/readme-docs/encryption-checksums.adoc +328 -0
  625. data/readme-docs/format-converter.adoc +316 -0
  626. data/readme-docs/installation.adoc +228 -0
  627. data/readme-docs/par2-archives.adoc +608 -0
  628. data/readme-docs/performance-profiler.adoc +389 -0
  629. data/readme-docs/preprocessing-filters.adoc +280 -0
  630. data/vendor/libomnizip_ffi.so +0 -0
  631. data/xz-file-format-1.2.1.txt +1174 -0
  632. metadata +768 -0
@@ -0,0 +1,584 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
4
+
5
+ module Omnizip
6
+ module Formats
7
+ module Rar
8
+ module Rar5
9
+ module Compression
10
+ # RAR5 LZSS compression method
11
+ #
12
+ # RAR5 compression methods 1-5 use a proprietary LZSS-based algorithm
13
+ # with Huffman coding. This is the algorithm used by official RAR tools.
14
+ #
15
+ # Based on libarchive/archive_read_support_format_rar5.c
16
+ #
17
+ class Lzss
18
+ # Compression method identifiers
19
+ METHOD_STORE = 0
20
+ METHOD_FASTEST = 1
21
+ METHOD_FAST = 2
22
+ METHOD_NORMAL = 3
23
+ METHOD_GOOD = 4
24
+ METHOD_BEST = 5
25
+
26
+ # Huffman code constants (from libarchive)
27
+ HUFF_BC = 20 # Number of bit length codes
28
+ HUFF_NC = 306 # Number of literal/length codes
29
+ HUFF_DC = 64 # Number of distance codes
30
+ HUFF_LDC = 16 # Number of low distance codes
31
+ HUFF_RC = 44 # Number of repeat codes
32
+ HUFF_TABLE_SIZE = HUFF_NC + HUFF_DC + HUFF_LDC + HUFF_RC
33
+
34
+ # Distance cache size
35
+ DIST_CACHE_SIZE = 4
36
+
37
+ # Minimum match length
38
+ MIN_MATCH = 3
39
+
40
+ class << self
41
+ # Check if LZSS compression is available for official RAR compatibility
42
+ #
43
+ # @return [Boolean] true if implemented
44
+ def available?
45
+ # Decoder is implemented; the encoder is NOT compatible
46
+ # with official RAR tools (unrar "tests" its output as
47
+ # OK while extracting empty files). Callers fall back
48
+ # to STORE until a RAR-compatible encoder lands.
49
+ false
50
+ end
51
+
52
+ # Compress data using RAR5 LZSS
53
+ #
54
+ # @param data [String] Data to compress
55
+ # @param options [Hash] Compression options
56
+ # @option options [Integer] :level Compression level (1-5)
57
+ # @option options [Integer] :dict_size Dictionary size
58
+ # @return [Hash] Hash with :data, :properties, and :method
59
+ def compress(data, options = {})
60
+ level = options[:level] || METHOD_NORMAL
61
+ options[:dict_size] || dictionary_size_for_level(level)
62
+
63
+ # For now, use STORE method until encoder is compatible
64
+ # with official RAR tools
65
+ {
66
+ data: data,
67
+ properties: nil,
68
+ method: METHOD_STORE,
69
+ }
70
+ end
71
+
72
+ # Decompress RAR5 LZSS data
73
+ #
74
+ # @param data [String] Compressed data
75
+ # @param options [Hash] Decompression options
76
+ # @option options [Integer] :uncompressed_size Expected size
77
+ # @option options [Integer] :window_size Dictionary size
78
+ # @return [String] Decompressed data
79
+ def decompress(data, options = {})
80
+ uncompressed_size = options[:uncompressed_size]
81
+ window_size = options[:window_size] || (1 << 20) # Default 1MB
82
+
83
+ decoder = Decoder.new(data, window_size)
84
+ decoder.decode(uncompressed_size)
85
+ end
86
+
87
+ # Get compression method identifier
88
+ #
89
+ # @param level [Integer] Compression level (1-5)
90
+ # @return [Integer] Method ID
91
+ def method_id(level = METHOD_NORMAL)
92
+ level.clamp(METHOD_FASTEST, METHOD_BEST)
93
+ end
94
+
95
+ # Get compression info VINT value
96
+ #
97
+ # @param level [Integer] Compression level (1-5)
98
+ # @return [Integer] Compression info value
99
+ def compression_info(level = METHOD_NORMAL)
100
+ method = method_id(level)
101
+ method & 0x3F
102
+ end
103
+
104
+ private
105
+
106
+ # Get dictionary size for compression level
107
+ def dictionary_size_for_level(level)
108
+ 1 << case level
109
+ when 1 then 18 # 256 KB
110
+ when 2 then 20 # 1 MB
111
+ when 3 then 22 # 4 MB
112
+ when 4 then 23 # 8 MB
113
+ when 5 then 24 # 16 MB
114
+ else 22 # 4 MB default
115
+ end
116
+ end
117
+ end
118
+
119
+ # Bit reader for reading individual bits from compressed data
120
+ #
121
+ class BitReader
122
+ def initialize(data)
123
+ @data = data
124
+ @byte_pos = 0
125
+ @bit_pos = 0
126
+ end
127
+
128
+ # Read up to 16 bits
129
+ def read_bits(num_bits)
130
+ return 0 if num_bits.zero?
131
+
132
+ result = 0
133
+ bits_read = 0
134
+
135
+ while bits_read < num_bits
136
+ return nil if @byte_pos >= @data.bytesize
137
+
138
+ byte = @data.getbyte(@byte_pos)
139
+ bits_available = 8 - @bit_pos
140
+ bits_needed = num_bits - bits_read
141
+ bits_to_read = [bits_available, bits_needed].min
142
+
143
+ mask = ((1 << bits_to_read) - 1) << @bit_pos
144
+ bits = (byte & mask) >> @bit_pos
145
+
146
+ result |= bits << bits_read
147
+ bits_read += bits_to_read
148
+ @bit_pos += bits_to_read
149
+
150
+ if @bit_pos >= 8
151
+ @bit_pos = 0
152
+ @byte_pos += 1
153
+ end
154
+ end
155
+
156
+ result
157
+ end
158
+
159
+ # Skip specified number of bits
160
+ def skip_bits(num_bits)
161
+ @bit_pos += num_bits
162
+ while @bit_pos >= 8
163
+ @bit_pos -= 8
164
+ @byte_pos += 1
165
+ end
166
+ end
167
+
168
+ # Read 32 bits
169
+ def read_bits_32(num_bits)
170
+ return 0 if num_bits.zero?
171
+
172
+ result = 0
173
+ bits_read = 0
174
+
175
+ while bits_read < num_bits && @byte_pos < @data.bytesize
176
+ byte = @data.getbyte(@byte_pos)
177
+ bits_available = 8 - @bit_pos
178
+ bits_needed = num_bits - bits_read
179
+ bits_to_read = [bits_available, bits_needed].min
180
+
181
+ mask = ((1 << bits_to_read) - 1) << @bit_pos
182
+ bits = (byte & mask) >> @bit_pos
183
+
184
+ result |= bits << bits_read
185
+ bits_read += bits_to_read
186
+ @bit_pos += bits_to_read
187
+
188
+ if @bit_pos >= 8
189
+ @bit_pos = 0
190
+ @byte_pos += 1
191
+ end
192
+ end
193
+
194
+ result
195
+ end
196
+
197
+ def end_of_data?(block_size)
198
+ @byte_pos >= block_size || (@byte_pos == block_size - 1 && @bit_pos >= 8)
199
+ end
200
+
201
+ attr_accessor :byte_pos, :bit_pos
202
+ end
203
+
204
+ # Huffman decode table
205
+ #
206
+ class HuffmanTable
207
+ attr_reader :size, :decode_len, :decode_pos, :decode_num
208
+
209
+ def initialize(size)
210
+ @size = size
211
+ @decode_len = Array.new(16, 0)
212
+ @decode_pos = Array.new(16, 0)
213
+ @decode_num = Array.new(size, 0)
214
+ @quick_bits = 0
215
+ @quick_len = Array.new(65536, 0)
216
+ @quick_num = Array.new(65536, 0)
217
+ end
218
+
219
+ # Build decode tables from bit lengths
220
+ # Based on libarchive's create_decode_tables()
221
+ def build(bit_lengths)
222
+ # Count codes for each bit length
223
+ len_count = Array.new(16, 0)
224
+ bit_lengths.each do |len|
225
+ len_count[len] += 1 if len.positive? && len < 16
226
+ end
227
+
228
+ # Calculate decode_len and decode_pos
229
+ @decode_pos[0] = 0
230
+ @decode_len[0] = 0
231
+
232
+ upper_limit = 0
233
+ (1..15).each do |i|
234
+ upper_limit = (upper_limit + len_count[i]) << 1
235
+ @decode_len[i] = upper_limit << (16 - i)
236
+ @decode_pos[i] = @decode_pos[i - 1] + len_count[i - 1]
237
+ end
238
+
239
+ # Fill decode_num
240
+ decode_pos_copy = @decode_pos.dup
241
+ bit_lengths.each_with_index do |len, symbol|
242
+ next unless len.positive? && len < 16
243
+
244
+ pos = decode_pos_copy[len]
245
+ @decode_num[pos] = symbol if pos < @size
246
+ decode_pos_copy[len] += 1
247
+ end
248
+
249
+ # Build quick lookup table
250
+ @quick_bits = 10 # Use 10 bits for quick lookup
251
+ build_quick_table(bit_lengths)
252
+
253
+ true
254
+ end
255
+
256
+ # Decode a symbol from bit reader
257
+ def decode(bit_reader)
258
+ # Read 16 bits for lookup
259
+ bit_field = bit_reader.read_bits(16)
260
+ return nil if bit_field.nil?
261
+
262
+ # Quick lookup
263
+ if @quick_len[bit_field].positive?
264
+ bit_reader.skip_bits(@quick_len[bit_field])
265
+ return @quick_num[bit_field]
266
+ end
267
+
268
+ # Full decode
269
+ bits = 15
270
+ (1..14).each do |i|
271
+ if bit_field < @decode_len[i]
272
+ bits = i
273
+ break
274
+ end
275
+ end
276
+
277
+ bit_reader.skip_bits(bits)
278
+
279
+ dist = bit_field - @decode_len[bits - 1]
280
+ dist >>= (16 - bits)
281
+ pos = @decode_pos[bits] + dist
282
+
283
+ pos < @size ? @decode_num[pos] : 0
284
+ end
285
+
286
+ private
287
+
288
+ def build_quick_table(bit_lengths)
289
+ quick_bits = @quick_bits
290
+
291
+ # Find maximum bit length for quick table
292
+ bit_lengths.each_with_index do |len, symbol|
293
+ next unless len.positive? && len <= quick_bits
294
+
295
+ # Calculate code for this symbol
296
+ code = 0
297
+ (0...len).each do |_i|
298
+ code = (code << 1) | 1 # Simplified - should use actual codes
299
+ end
300
+
301
+ # Fill quick table entries
302
+ extra_bits = quick_bits - len
303
+ (0...(1 << extra_bits)).each do |extra|
304
+ index = (code << extra_bits) | extra
305
+ next if index >= @quick_len.size
306
+
307
+ @quick_len[index] = len
308
+ @quick_num[index] = symbol
309
+ end
310
+ end
311
+ end
312
+ end
313
+
314
+ # RAR5 LZSS Decoder
315
+ #
316
+ # Based on libarchive's do_uncompress_block()
317
+ #
318
+ class Decoder
319
+ def initialize(data, window_size)
320
+ @data = data.dup.force_encoding(Encoding::BINARY)
321
+ @window_size = window_size
322
+ @window_mask = window_size - 1
323
+ @window = "\x00" * window_size
324
+ @output = StringIO.new
325
+ @output.set_encoding(Encoding::BINARY)
326
+ @write_ptr = 0
327
+ @dist_cache = [0, 0, 0, 0] # Distance cache
328
+ @last_len = 0
329
+ end
330
+
331
+ # Decode the compressed data
332
+ #
333
+ # @param expected_size [Integer, nil] Expected uncompressed size
334
+ # @return [String] Decompressed data
335
+ def decode(expected_size = nil)
336
+ return "" if @data.empty?
337
+
338
+ @bit_reader = BitReader.new(@data)
339
+
340
+ # Parse block header
341
+ parse_block_header
342
+
343
+ return @output.string unless @table_present
344
+
345
+ # Parse Huffman tables
346
+ return @output.string unless parse_huffman_tables
347
+
348
+ # Decode data
349
+ decode_data(expected_size)
350
+
351
+ @output.string
352
+ end
353
+
354
+ private
355
+
356
+ def parse_block_header
357
+ flags = @bit_reader.read_bits(8)
358
+ return unless flags
359
+
360
+ @table_present = flags.anybits?(0x01)
361
+ end
362
+
363
+ def parse_huffman_tables
364
+ # Parse bit lengths for BC table (20 codes)
365
+ bit_lengths_bc = parse_bit_lengths(HUFF_BC)
366
+ return false unless bit_lengths_bc
367
+
368
+ # Build BC table
369
+ @table_bc = HuffmanTable.new(HUFF_BC)
370
+ @table_bc.build(bit_lengths_bc)
371
+
372
+ # Parse main table using BC table
373
+ table_data = Array.new(HUFF_TABLE_SIZE, 0)
374
+ idx = 0
375
+
376
+ while idx < HUFF_TABLE_SIZE
377
+ num = @table_bc.decode(@bit_reader)
378
+ return false if num.nil?
379
+
380
+ if num < 16
381
+ # Direct value
382
+ table_data[idx] = num
383
+ idx += 1
384
+ elsif num < 18
385
+ # Repeat previous code
386
+ count = num == 16 ? @bit_reader.read_bits(3) + 3 : @bit_reader.read_bits(7) + 11
387
+ return false if count.nil? || idx.zero?
388
+
389
+ count.times do
390
+ break if idx >= HUFF_TABLE_SIZE
391
+
392
+ table_data[idx] = table_data[idx - 1]
393
+ idx += 1
394
+ end
395
+ else
396
+ # Fill with zeros
397
+ count = num == 18 ? @bit_reader.read_bits(3) + 3 : @bit_reader.read_bits(7) + 11
398
+ return false if count.nil?
399
+
400
+ count.times do
401
+ break if idx >= HUFF_TABLE_SIZE
402
+
403
+ table_data[idx] = 0
404
+ idx += 1
405
+ end
406
+ end
407
+ end
408
+
409
+ # Build individual tables
410
+ @table_ld = HuffmanTable.new(HUFF_NC)
411
+ @table_ld.build(table_data[0, HUFF_NC])
412
+
413
+ @table_dd = HuffmanTable.new(HUFF_DC)
414
+ @table_dd.build(table_data[HUFF_NC, HUFF_DC])
415
+
416
+ @table_ldd = HuffmanTable.new(HUFF_LDC)
417
+ @table_ldd.build(table_data[HUFF_NC + HUFF_DC, HUFF_LDC])
418
+
419
+ @table_rd = HuffmanTable.new(HUFF_RC)
420
+ @table_rd.build(table_data[HUFF_NC + HUFF_DC + HUFF_LDC,
421
+ HUFF_RC])
422
+
423
+ true
424
+ end
425
+
426
+ def parse_bit_lengths(count)
427
+ lengths = Array.new(count, 0)
428
+ idx = 0
429
+ 0xF0
430
+ 4
431
+
432
+ while idx < count
433
+ byte = @bit_reader.read_bits(8)
434
+ return nil if byte.nil?
435
+
436
+ # This is a simplified version
437
+ # The actual libarchive uses nibble-based RLE
438
+ lengths[idx] = byte & 0x0F
439
+ idx += 1
440
+ break if idx >= count
441
+
442
+ lengths[idx] = (byte >> 4) & 0x0F
443
+ idx += 1
444
+ end
445
+
446
+ lengths
447
+ end
448
+
449
+ def decode_data(expected_size)
450
+ while !@bit_reader.end_of_data?(@data.bytesize) &&
451
+ (expected_size.nil? || @output.pos < expected_size)
452
+
453
+ num = @table_ld.decode(@bit_reader)
454
+ break if num.nil?
455
+
456
+ if num < 256
457
+ # Literal byte
458
+ write_byte(num)
459
+ elsif num == 256
460
+ # Filter - skip for now
461
+ skip_filter
462
+ elsif num == 257
463
+ # Repeat last match
464
+ if @last_len.positive?
465
+ copy_string(@last_len, @dist_cache[0])
466
+ end
467
+ elsif num < 262
468
+ # Use distance cache entry
469
+ cache_idx = num - 258
470
+ dist = dist_cache_touch(cache_idx)
471
+
472
+ len_slot = @table_rd.decode(@bit_reader)
473
+ break if len_slot.nil?
474
+
475
+ len = decode_code_length(len_slot)
476
+ copy_string(len, dist) if len.positive?
477
+ else
478
+ # Regular match
479
+ len = decode_code_length(num - 262)
480
+ break if len <= 0
481
+
482
+ dist_slot = @table_dd.decode(@bit_reader)
483
+ break if dist_slot.nil?
484
+
485
+ dist = decode_distance(dist_slot)
486
+ break if dist <= 0
487
+
488
+ dist_cache_push(dist)
489
+ @last_len = len
490
+ copy_string(len, dist)
491
+ end
492
+ end
493
+ end
494
+
495
+ def decode_code_length(slot)
496
+ return slot + MIN_MATCH if slot < 16
497
+
498
+ # Extended length encoding
499
+ extra_bits = (slot - 12) / 2
500
+ base = ((2 + (slot & 1)) << extra_bits)
501
+ extra = @bit_reader.read_bits(extra_bits)
502
+ return 0 if extra.nil?
503
+
504
+ base + extra + MIN_MATCH
505
+ end
506
+
507
+ def decode_distance(slot)
508
+ return 0 if slot >= 64
509
+
510
+ if slot < 4
511
+ return slot + 1
512
+ end
513
+
514
+ dbits = (slot / 2) - 1
515
+ dist = 2 | (slot & 1)
516
+ dist = (dist << dbits) | (1 << dbits)
517
+
518
+ if dbits >= 4
519
+ # Read extra bits and low distance
520
+ add = @bit_reader.read_bits_32(dbits - 4)
521
+ dist += add << 4 if add
522
+
523
+ low_dist = @table_ldd.decode(@bit_reader)
524
+ return 0 if low_dist.nil?
525
+
526
+ dist += low_dist
527
+ elsif dbits.positive?
528
+ add = @bit_reader.read_bits(dbits)
529
+ dist += add if add
530
+ end
531
+
532
+ # Adjust length based on distance
533
+ dist
534
+ end
535
+
536
+ def dist_cache_push(dist)
537
+ @dist_cache[3] = @dist_cache[2]
538
+ @dist_cache[2] = @dist_cache[1]
539
+ @dist_cache[1] = @dist_cache[0]
540
+ @dist_cache[0] = dist
541
+ end
542
+
543
+ def dist_cache_touch(idx)
544
+ dist = @dist_cache[idx]
545
+ if idx.positive?
546
+ # Move to front
547
+ (idx...DIST_CACHE_SIZE).each do |i|
548
+ if i + 1 < DIST_CACHE_SIZE
549
+ @dist_cache[i] =
550
+ @dist_cache[i + 1]
551
+ end
552
+ end
553
+ @dist_cache[0] = dist
554
+ end
555
+ dist
556
+ end
557
+
558
+ def write_byte(byte)
559
+ @output.putc(byte)
560
+ @window[@write_ptr & @window_mask] = byte.chr
561
+ @write_ptr += 1
562
+ end
563
+
564
+ def copy_string(length, distance)
565
+ return if distance <= 0 || distance > @write_ptr
566
+
567
+ length.times do
568
+ read_idx = (@write_ptr - distance) & @window_mask
569
+ byte = @window.getbyte(read_idx)
570
+ write_byte(byte)
571
+ end
572
+ end
573
+
574
+ def skip_filter
575
+ # Skip filter data - simplified implementation
576
+ @bit_reader.skip_bits(16)
577
+ end
578
+ end
579
+ end
580
+ end
581
+ end
582
+ end
583
+ end
584
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Formats
5
+ module Rar
6
+ module Rar5
7
+ module Compression
8
+ # STORE compression method (uncompressed)
9
+ #
10
+ # This is the simplest compression method - it stores data without
11
+ # any compression. The "compressed" size equals the original size.
12
+ #
13
+ # @example Compress data
14
+ # compressed = Store.compress("Hello, World!")
15
+ # compressed # => "Hello, World!"
16
+ class Store
17
+ # Compression method identifier
18
+ METHOD = 0
19
+
20
+ # Compress data (passthrough for STORE)
21
+ #
22
+ # @param data [String] Data to compress
23
+ # @param _options [Hash] Options (ignored for STORE)
24
+ # @return [String] Uncompressed data
25
+ def self.compress(data, _options = {})
26
+ data
27
+ end
28
+
29
+ # Decompress data (passthrough for STORE)
30
+ #
31
+ # @param data [String] Data to decompress
32
+ # @param _options [Hash] Options (ignored for STORE)
33
+ # @return [String] Original data
34
+ def self.decompress(data, _options = {})
35
+ data
36
+ end
37
+
38
+ # Get compression method identifier
39
+ #
40
+ # @return [Integer] Method ID (0 for STORE)
41
+ def self.method_id
42
+ METHOD
43
+ end
44
+
45
+ # Get compression info VINT value
46
+ #
47
+ # For STORE, this is just the method ID (0)
48
+ # Bits 0-5: method (0=STORE)
49
+ # Bits 6+: version (0 for STORE)
50
+ #
51
+ # @return [Integer] Compression info value
52
+ def self.compression_info
53
+ METHOD
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Formats
5
+ module Rar
6
+ module Rar5
7
+ # CRC32 calculation for RAR5 format
8
+ class CRC32
9
+ POLYNOMIAL = 0xEDB88320
10
+
11
+ # Generate CRC32 lookup table
12
+ def self.generate_table
13
+ @generate_table ||= (0..255).map do |i|
14
+ crc = i
15
+ 8.times do
16
+ crc = (crc >> 1) ^ ((crc & 1) * POLYNOMIAL)
17
+ end
18
+ crc
19
+ end
20
+ end
21
+
22
+ # Calculate CRC32 for data
23
+ # @param data [String] Binary data
24
+ # @return [Integer] 32-bit CRC
25
+ def self.calculate(data)
26
+ table = generate_table
27
+ crc = 0xFFFFFFFF
28
+
29
+ data.bytes.each do |byte|
30
+ crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF]
31
+ end
32
+
33
+ crc ^ 0xFFFFFFFF
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end