omnizip 0.4.7-x86_64-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,604 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (C) 2024 Ribose Inc.
5
+ #
6
+ # This file is part of Omnizip.
7
+ #
8
+ # Omnizip is a pure Ruby port of 7-Zip compression algorithms.
9
+ # Based on the 7-Zip LZMA SDK by Igor Pavlov.
10
+ #
11
+ # This library is free software; you can redistribute it and/or
12
+ # modify it under the terms of the GNU Lesser General Public
13
+ # License as published by the Free Software Foundation; either
14
+ # version 2.1 of the License, or (at your option) any later version.
15
+ #
16
+ # See the COPYING file for the complete text of the license.
17
+ #
18
+
19
+ require "thor"
20
+
21
+ module Omnizip
22
+ # Shared helpers used by the Thor command groups defined below
23
+ # (ProfileCommands, ArchiveCommands, Cli). Defined here because the
24
+ # command classes include it at class-body time; a separate file
25
+ # under Omnizip::Cli would re-trigger this file's autoload
26
+ # mid-load.
27
+ module Shared
28
+ # Thor 1.x does not treat --help/-h on subcommands as a request
29
+ # for help: the flag reaches the command as a positional argument
30
+ # and arity checking fails. Classes extending this module route
31
+ # those flags to the standard help output instead.
32
+ module HelpDispatch
33
+ def dispatch(meth, given_args, given_opts, config)
34
+ wants_help = [Array(given_args), Array(given_opts)].any? do |list|
35
+ list.include?("--help") || list.include?("-h")
36
+ end
37
+ if wants_help
38
+ name = meth || Array(given_args).grep_v(/\A-/).first
39
+ # Subcommand groups intercept their own --help (e.g.
40
+ # "archive create --help" must show the create usage).
41
+ return super if subcommands.include?(name)
42
+
43
+ return start(["help", name].compact, config)
44
+ end
45
+
46
+ super
47
+ end
48
+ end
49
+
50
+ # Print a formatted error message and exit nonzero.
51
+ #
52
+ # @param error [StandardError] the error to display
53
+ def handle_error(error)
54
+ warn Omnizip::CliOutputFormatter.format_error(error)
55
+ exit 1
56
+ end
57
+
58
+ # Format a byte count with a binary-unit suffix.
59
+ #
60
+ # @param bytes [Integer] the byte count
61
+ # @return [String] human-readable size (e.g. "1.5 MB")
62
+ def format_bytes(bytes)
63
+ Omnizip::CliOutputFormatter.format_size(bytes)
64
+ end
65
+ end
66
+
67
+ # Profile commands subcommand group
68
+ class ProfileCommands < Thor
69
+ include Shared
70
+ extend Shared::HelpDispatch
71
+
72
+ class << self
73
+ def exit_on_failure?
74
+ true
75
+ end
76
+ end
77
+
78
+ desc "list", "List available compression profiles"
79
+ long_desc <<~DESC
80
+ List all available compression profiles with their descriptions.
81
+
82
+ Examples:
83
+
84
+ $ omnizip profile list
85
+
86
+ $ omnizip profile list --verbose
87
+ DESC
88
+ option :verbose, type: :boolean, default: false,
89
+ aliases: "-v",
90
+ desc: "Show detailed information"
91
+ def list
92
+ Omnizip::Commands::ProfileListCommand.new(options).run
93
+ rescue StandardError => e
94
+ handle_error(e)
95
+ end
96
+
97
+ desc "show PROFILE", "Show profile details"
98
+ long_desc <<~DESC
99
+ Show detailed information about a specific compression profile.
100
+
101
+ PROFILE is the name of the profile to show.
102
+
103
+ Examples:
104
+
105
+ $ omnizip profile show maximum
106
+
107
+ $ omnizip profile show fast
108
+ DESC
109
+ def show(profile_name)
110
+ Omnizip::Commands::ProfileShowCommand.new(options).run(profile_name)
111
+ rescue StandardError => e
112
+ handle_error(e)
113
+ end
114
+ end
115
+
116
+ # Archive commands subcommand group
117
+ class ArchiveCommands < Thor
118
+ include Shared
119
+ extend Shared::HelpDispatch
120
+
121
+ class << self
122
+ def exit_on_failure?
123
+ true
124
+ end
125
+ end
126
+
127
+ desc "create OUTPUT INPUT...", "Create .7z or .rar archive"
128
+ long_desc <<~DESC
129
+ Create a .7z or .rar archive from files and directories.
130
+
131
+ OUTPUT is the path to the archive to create (.7z or .rar extension).
132
+ INPUT can be one or more files or directories to archive.
133
+
134
+ For split archives, OUTPUT should end with .001 (e.g., backup.7z.001).
135
+
136
+ RAR5 archives are created using pure Ruby (no external tools needed).
137
+ RAR5 currently supports individual files only (not directories).
138
+
139
+ Examples:
140
+
141
+ $ omnizip archive create archive.7z file1.txt file2.txt
142
+
143
+ $ omnizip archive create archive.7z dir/ --algorithm lzma2 \\
144
+ --level 9
145
+
146
+ $ omnizip archive create archive.7z file.txt --no-solid \\
147
+ --filters bcj_x86
148
+
149
+ $ omnizip archive create backup.7z.001 large_data/ --volume-size 100M
150
+
151
+ $ omnizip archive create backup.7z.001 files/ --volume-size 4.7GB
152
+
153
+ $ omnizip archive create archive.rar file1.txt file2.txt
154
+
155
+ $ omnizip archive create archive.rar data.txt --rar-compression lzma \\
156
+ --level 5 --include-mtime --include-crc32
157
+
158
+ $ omnizip archive create secure.rar data.txt --rar-compression lzma \\
159
+ --level 5 --password "SecurePass123!" --kdf-iterations 262144
160
+
161
+ $ omnizip archive create backup.rar files/ --rar-compression lzma \\
162
+ --level 5 --solid --multi-volume --volume-size 100M
163
+
164
+ $ omnizip archive create critical.rar data/ --rar-compression lzma \\
165
+ --level 5 --password "Secure2025!" --recovery --recovery-percent 10
166
+ DESC
167
+ option :format, type: :string,
168
+ desc: "Archive format (7z or rar, default: auto-detect from extension)"
169
+ option :profile, type: :string,
170
+ desc: "Compression profile (fast, balanced, maximum, text, binary, archive, auto)"
171
+ option :algorithm, type: :string, default: "lzma2",
172
+ desc: "Compression algorithm for 7z (lzma, lzma2, ppmd7, bzip2)"
173
+ option :level, type: :numeric, default: 5,
174
+ desc: "Compression level (1-9 for 7z, 1-5 for RAR5)"
175
+ option :solid, type: :boolean, default: true,
176
+ desc: "Use solid compression (default: true for 7z, false for RAR)"
177
+ option :filters, type: :string,
178
+ desc: "Filter chain for 7z (e.g., bcj_x86,delta)"
179
+ option :volume_size, type: :string,
180
+ desc: "Volume size for split archives (e.g., 100M, 650MB, 4.7GB)"
181
+ option :password, type: :string,
182
+ desc: "Password for encryption (7z: header encryption, RAR5: AES-256-CBC)"
183
+ option :encrypt_headers, type: :boolean, default: false,
184
+ desc: "Encrypt archive headers (7z only, hides filenames)"
185
+ option :rar_version, type: :numeric, default: 5,
186
+ desc: "RAR version (4 or 5, default: 5 for pure Ruby)"
187
+ option :rar_compression, type: :string, default: "store",
188
+ desc: "RAR compression method (store, lzma, auto)"
189
+ option :include_mtime, type: :boolean, default: false,
190
+ desc: "Include modification time in RAR5 file headers"
191
+ option :include_crc32, type: :boolean, default: false,
192
+ desc: "Include CRC32 checksum in RAR5 file headers"
193
+ option :multi_volume, type: :boolean, default: false,
194
+ desc: "Create multi-volume RAR5 archive (requires --volume-size)"
195
+ option :volume_naming, type: :string, default: "part",
196
+ desc: "Volume naming pattern for RAR5 (part, volume, numeric)"
197
+ option :kdf_iterations, type: :numeric, default: 262_144,
198
+ desc: "PBKDF2 iterations for RAR5 encryption (65536-1048576, default: 262144)"
199
+ option :recovery, type: :boolean, default: false,
200
+ desc: "Generate PAR2 recovery records for RAR5"
201
+ option :recovery_percent, type: :numeric, default: 5,
202
+ desc: "PAR2 redundancy percentage for RAR5 (0-100, default: 5)"
203
+ option :verbose, type: :boolean, default: false,
204
+ aliases: "-v",
205
+ desc: "Enable verbose output"
206
+ def create(output, *inputs)
207
+ Omnizip::Commands::ArchiveCreateCommand.new(options).run(output, *inputs)
208
+ rescue StandardError => e
209
+ handle_error(e)
210
+ end
211
+
212
+ desc "extract ARCHIVE [OUTPUT_DIR]", "Extract archive"
213
+ long_desc <<~DESC
214
+ Extract a .7z, .zip, or .rar archive to a directory.
215
+
216
+ ARCHIVE is the path to the archive to extract.
217
+ OUTPUT_DIR is the directory to extract to (default: current directory).
218
+
219
+ Pattern extraction options allow selective extraction of files.
220
+
221
+ Examples:
222
+
223
+ $ omnizip archive extract archive.zip
224
+
225
+ $ omnizip archive extract archive.zip output/ --verbose
226
+
227
+ $ omnizip archive extract archive.zip output/ --pattern '**/*.txt'
228
+
229
+ $ omnizip archive extract archive.zip output/ \\
230
+ --pattern '*.txt' --pattern '*.md'
231
+
232
+ $ omnizip archive extract archive.zip output/ \\
233
+ --pattern '**/*' --exclude '**/*.tmp' --exclude '**/test/**'
234
+
235
+ $ omnizip archive extract archive.zip output/ \\
236
+ --regex '\\.log$'
237
+
238
+ $ omnizip archive extract archive.zip output/ \\
239
+ --pattern 'src/**/*.rb' --flatten
240
+ DESC
241
+ option :verbose, type: :boolean, default: false,
242
+ aliases: "-v",
243
+ desc: "Enable verbose output"
244
+ option :pattern, type: :array,
245
+ desc: "Include pattern(s) for selective extraction"
246
+ option :exclude, type: :array,
247
+ desc: "Exclude pattern(s) for selective extraction"
248
+ option :regex, type: :string,
249
+ desc: "Regular expression pattern for selective extraction"
250
+ option :flatten, type: :boolean, default: false,
251
+ desc: "Extract all files to output root (ignore paths)"
252
+ option :count, type: :boolean, default: false,
253
+ desc: "Count matches without extracting"
254
+ def extract(archive, output_dir = nil)
255
+ Omnizip::Commands::ArchiveExtractCommand.new(options).run(archive,
256
+ output_dir)
257
+ rescue StandardError => e
258
+ handle_error(e)
259
+ end
260
+
261
+ desc "list ARCHIVE", "List archive contents"
262
+ long_desc <<~DESC
263
+ List the contents of a .7z, .zip, or .rar archive.
264
+
265
+ ARCHIVE is the path to the archive to list.
266
+
267
+ Pattern filtering options allow listing only matching files.
268
+
269
+ Examples:
270
+
271
+ $ omnizip archive list archive.zip
272
+
273
+ $ omnizip archive list archive.zip --verbose
274
+
275
+ $ omnizip archive list archive.zip --pattern '**/*.rb'
276
+
277
+ $ omnizip archive list archive.zip --pattern '*.txt' --count
278
+ DESC
279
+ option :verbose, type: :boolean, default: false,
280
+ aliases: "-v",
281
+ desc: "Enable verbose output"
282
+ option :pattern, type: :array,
283
+ desc: "Include pattern(s) for filtering"
284
+ option :exclude, type: :array,
285
+ desc: "Exclude pattern(s) for filtering"
286
+ option :count, type: :boolean, default: false,
287
+ desc: "Show count of matches"
288
+ def list(archive)
289
+ Omnizip::Commands::ArchiveListCommand.new(options).run(archive)
290
+ rescue StandardError => e
291
+ handle_error(e)
292
+ end
293
+
294
+ desc "metadata ARCHIVE [PATTERN]", "View or edit archive metadata"
295
+ long_desc <<~DESC
296
+ View or edit metadata for archives and entries.
297
+
298
+ ARCHIVE is the path to the archive.
299
+ PATTERN is an optional entry name or glob pattern.
300
+
301
+ Examples:
302
+
303
+ # View archive metadata
304
+ $ omnizip archive metadata archive.zip --show
305
+
306
+ # View entry metadata
307
+ $ omnizip archive metadata archive.zip file.txt --show
308
+
309
+ # Set archive comment
310
+ $ omnizip archive metadata archive.zip --comment "My backup"
311
+
312
+ # Set entry comment
313
+ $ omnizip archive metadata archive.zip file.txt --comment "Important"
314
+
315
+ # Set modification time
316
+ $ omnizip archive metadata archive.zip file.txt --set-mtime now
317
+
318
+ # Set permissions
319
+ $ omnizip archive metadata archive.zip '*.rb' --chmod 755
320
+ DESC
321
+ option :show, type: :boolean, default: false,
322
+ desc: "Show metadata (read-only)"
323
+ option :comment, type: :string,
324
+ desc: "Set comment"
325
+ option :set_mtime, type: :string,
326
+ desc: "Set modification time (e.g., 'now', '2024-01-01')"
327
+ option :chmod, type: :string,
328
+ desc: "Set Unix permissions (e.g., '755', '0644')"
329
+ option :set_attribute, type: :string,
330
+ desc: "Set attribute flag (readonly, hidden, system, archive)"
331
+ option :verbose, type: :boolean, default: false,
332
+ aliases: "-v",
333
+ desc: "Enable verbose output"
334
+ def metadata(archive, pattern = nil)
335
+ Omnizip::Commands::MetadataCommand.new(options).run(archive, pattern)
336
+ rescue StandardError => e
337
+ handle_error(e)
338
+ end
339
+
340
+ desc "verify ARCHIVE", "Verify archive integrity"
341
+ long_desc <<~DESC
342
+ Verify the integrity of an archive (currently RAR archives via
343
+ header and recovery-record checks).
344
+ DESC
345
+ def verify(archive)
346
+ Omnizip::Commands::ArchiveVerifyCommand.new(options).run(archive)
347
+ rescue StandardError => e
348
+ handle_error(e)
349
+ end
350
+
351
+ desc "repair ARCHIVE OUTPUT", "Repair a damaged archive"
352
+ long_desc <<~DESC
353
+ Repair a damaged archive (currently RAR archives via recovery
354
+ records and .rev volumes). OUTPUT is the repaired archive path.
355
+ DESC
356
+ option :verbose, type: :boolean, default: false, aliases: "-v"
357
+ def repair(archive, output)
358
+ Omnizip::Commands::ArchiveRepairCommand.new(options).run(archive, output)
359
+ rescue StandardError => e
360
+ handle_error(e)
361
+ end
362
+ end
363
+
364
+ # Command-line interface for Omnizip.
365
+ #
366
+ # Provides Thor-based CLI commands for compressing and decompressing
367
+ # files using various compression algorithms.
368
+ class Cli < Thor
369
+ include Shared
370
+ extend Shared::HelpDispatch
371
+
372
+ class << self
373
+ def exit_on_failure?
374
+ true
375
+ end
376
+ end
377
+
378
+ desc "compress INPUT OUTPUT", "Compress a file or stream"
379
+ long_desc <<~DESC
380
+ Compress INPUT file and write the result to OUTPUT file.
381
+
382
+ Use '-' for INPUT to read from stdin or OUTPUT to write to stdout.
383
+ This enables Unix pipeline integration for streaming workflows.
384
+
385
+ The compression algorithm and level can be specified with options.
386
+ By default, LZMA compression is used with level 5.
387
+
388
+ Examples:
389
+
390
+ $ omnizip compress input.txt output.lzma
391
+
392
+ $ omnizip compress input.txt output.lzma --level 9 --verbose
393
+
394
+ $ cat input.txt | omnizip compress - output.zip --format zip
395
+
396
+ $ omnizip compress input.txt - --format zip > output.zip
397
+
398
+ $ cat data.txt | omnizip compress - - --format zip > out.zip
399
+ DESC
400
+ option :algorithm, type: :string, default: "lzma",
401
+ desc: "Compression algorithm to use"
402
+ option :format, type: :string, default: nil,
403
+ desc: "Archive format (zip, 7z) - enables pipe mode"
404
+ option :level, type: :numeric, default: 5,
405
+ desc: "Compression level (1-9)"
406
+ option :entry_name, type: :string, default: nil,
407
+ desc: "Entry name in archive (pipe mode only)"
408
+ option :verbose, type: :boolean, default: false,
409
+ aliases: "-v",
410
+ desc: "Enable verbose output"
411
+ def compress(input, output)
412
+ # Pipe mode: use streaming compression
413
+ if Omnizip::Pipe.stdin?(input) || Omnizip::Pipe.stdout?(output)
414
+ compress_pipe(input, output)
415
+ else
416
+ Commands::CompressCommand.new(options).run(input, output)
417
+ end
418
+ rescue StandardError => e
419
+ handle_error(e)
420
+ end
421
+
422
+ desc "decompress INPUT OUTPUT", "Decompress a file or stream"
423
+ long_desc <<~DESC
424
+ Decompress INPUT file and write the result to OUTPUT file or directory.
425
+
426
+ Use '-' for INPUT to read from stdin. If OUTPUT is a directory,
427
+ extracts all files. If OUTPUT is '-', streams first file to stdout.
428
+
429
+ The algorithm will be auto-detected from the compressed file,
430
+ or can be explicitly specified with the --algorithm option.
431
+
432
+ Examples:
433
+
434
+ $ omnizip decompress output.lzma restored.txt
435
+
436
+ $ omnizip decompress output.lzma restored.txt --verbose
437
+
438
+ $ cat archive.zip | omnizip decompress - extracted/
439
+
440
+ $ omnizip decompress - - < archive.zip > output.txt
441
+
442
+ $ cat archive.zip | omnizip decompress - extracted/ --verbose
443
+ DESC
444
+ option :algorithm, type: :string,
445
+ desc: "Decompression algorithm (auto-detect if omitted)"
446
+ option :verbose, type: :boolean, default: false,
447
+ aliases: "-v",
448
+ desc: "Enable verbose output"
449
+ def decompress(input, output)
450
+ # Pipe mode: use streaming decompression
451
+ if Omnizip::Pipe.stdin?(input) || Omnizip::Pipe.stdout?(output)
452
+ decompress_pipe(input, output)
453
+ else
454
+ Commands::DecompressCommand.new(options).run(input, output)
455
+ end
456
+ rescue StandardError => e
457
+ handle_error(e)
458
+ end
459
+
460
+ desc "list", "List available compression algorithms"
461
+ long_desc <<~DESC
462
+ List all registered compression algorithms with their metadata.
463
+
464
+ Displays algorithm name, description, and version information.
465
+
466
+ Example:
467
+
468
+ $ omnizip list
469
+ DESC
470
+ option :verbose, type: :boolean, default: false,
471
+ aliases: "-v",
472
+ desc: "Enable verbose output"
473
+ def list
474
+ Commands::ListCommand.new(options).run
475
+ rescue StandardError => e
476
+ handle_error(e)
477
+ end
478
+
479
+ desc "version", "Display version information"
480
+ def version
481
+ puts "Omnizip v#{Omnizip::VERSION}"
482
+ puts "Pure Ruby implementation of LZMA compression"
483
+ end
484
+
485
+ desc "profile SUBCOMMAND ...ARGS", "Manage compression profiles"
486
+ subcommand "profile", ProfileCommands
487
+
488
+ desc "archive SUBCOMMAND ...ARGS", "Manage .7z archives"
489
+ subcommand "archive", ArchiveCommands
490
+ desc "convert SOURCE TARGET", "Convert archive between formats"
491
+ long_desc <<~DESC
492
+ Convert an archive from one format to another.
493
+
494
+ SOURCE is the path to the source archive (ZIP, 7z, or RAR).
495
+ TARGET is the path to the target archive (ZIP or 7z).
496
+ Note: RAR can only be a source (read-only), not a target.
497
+
498
+ Examples:
499
+
500
+ $ omnizip convert archive.zip archive.7z
501
+
502
+ $ omnizip convert archive.7z backup.zip
503
+
504
+ $ omnizip convert archive.zip archive.7z --compression lzma2 --level 9
505
+
506
+ $ omnizip convert archive.zip archive.7z --no-solid
507
+ DESC
508
+ option :compression, type: :string,
509
+ desc: "Compression algorithm (lzma, lzma2, ppmd7, bzip2)"
510
+ option :level, type: :numeric, default: 5,
511
+ desc: "Compression level (1-9)"
512
+ option :filter, type: :string,
513
+ desc: "Filter to apply (bcj-x86, delta, etc.)"
514
+ option :solid, type: :boolean, default: true,
515
+ desc: "Use solid compression for 7z (default: true)"
516
+ option :preserve_metadata, type: :boolean, default: true,
517
+ desc: "Preserve metadata (default: true)"
518
+ option :delete_source, type: :boolean, default: false,
519
+ desc: "Delete source after conversion"
520
+ option :verbose, type: :boolean, default: false,
521
+ aliases: "-v",
522
+ desc: "Enable verbose output"
523
+ def convert(source, target)
524
+ puts "Converting #{source} to #{target}..." if options[:verbose]
525
+
526
+ result = Omnizip::Converter.convert(
527
+ source,
528
+ target,
529
+ compression: options[:compression]&.to_sym,
530
+ compression_level: options[:level],
531
+ filter: options[:filter]&.to_sym,
532
+ solid: options[:solid],
533
+ preserve_metadata: options[:preserve_metadata],
534
+ delete_source: options[:delete_source],
535
+ )
536
+
537
+ puts "Conversion complete!"
538
+ puts "Source: #{result.source_path} (#{format_bytes(result.source_size)})"
539
+ puts "Target: #{result.target_path} (#{format_bytes(result.target_size)})"
540
+ puts "Size change: #{result.size_reduction.round(1)}%"
541
+ puts "Duration: #{result.duration.round(2)}s"
542
+ puts "Entries: #{result.entry_count}"
543
+
544
+ if result.warnings?
545
+ puts "\nWarnings:"
546
+ result.warnings.each { |w| puts " - #{w}" }
547
+ end
548
+ rescue StandardError => e
549
+ handle_error(e)
550
+ end
551
+
552
+ map %w[-v --version] => :version
553
+
554
+ private
555
+
556
+ def compress_pipe(input, output)
557
+ input_io = input == "-" ? $stdin : File.open(input, "rb")
558
+ output_io = output == "-" ? $stdout : File.open(output, "wb")
559
+
560
+ format = (options[:format] || :zip).to_sym
561
+ compression = options[:algorithm]&.to_sym
562
+ entry_name = options[:entry_name] || File.basename(input == "-" ? "stream.dat" : input)
563
+
564
+ if options[:verbose]
565
+ warn "Compressing from #{input == '-' ? 'stdin' : input} to #{output == '-' ? 'stdout' : output}"
566
+ warn "Format: #{format}, Entry: #{entry_name}"
567
+ end
568
+
569
+ Omnizip::Pipe.compress(
570
+ input_io,
571
+ output_io,
572
+ format: format,
573
+ compression: compression,
574
+ entry_name: entry_name,
575
+ level: options[:level],
576
+ )
577
+
578
+ warn "Compression complete" if options[:verbose]
579
+ ensure
580
+ input_io.close if input_io && input != "-"
581
+ output_io.close if output_io && output != "-"
582
+ end
583
+
584
+ def decompress_pipe(input, output)
585
+ input_io = input == "-" ? $stdin : File.open(input, "rb")
586
+
587
+ if options[:verbose]
588
+ warn "Decompressing from #{input == '-' ? 'stdin' : input}"
589
+ end
590
+
591
+ if output == "-"
592
+ # Stream to stdout
593
+ Omnizip::Pipe.decompress(input_io, output: $stdout)
594
+ else
595
+ # Extract to directory
596
+ Omnizip::Pipe.decompress(input_io, output_dir: output)
597
+ end
598
+
599
+ warn "Decompression complete" if options[:verbose]
600
+ ensure
601
+ input_io.close if input_io && input != "-"
602
+ end
603
+ end
604
+ end
File without changes