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,215 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Commands
5
+ # Metadata command implementation
6
+ class MetadataCommand
7
+ attr_reader :options
8
+
9
+ def initialize(options = {})
10
+ @options = options
11
+ end
12
+
13
+ # Run the metadata command
14
+ # @param archive_path [String] Path to archive
15
+ # @param pattern [String, nil] Optional pattern to match entries
16
+ def run(archive_path, pattern = nil)
17
+ unless File.exist?(archive_path)
18
+ raise Errno::ENOENT, "Archive not found: #{archive_path}"
19
+ end
20
+
21
+ if seven_zip?(archive_path)
22
+ show_seven_zip_metadata(archive_path, pattern)
23
+ return
24
+ end
25
+
26
+ unless zip?(archive_path)
27
+ raise ArgumentError,
28
+ "Metadata is supported for .zip and .7z archives: " \
29
+ "#{archive_path}"
30
+ end
31
+
32
+ Omnizip::Zip::File.open(archive_path) do |archive|
33
+ if options[:show] || editing_nothing?
34
+ show_metadata(archive, pattern)
35
+ else
36
+ edit_metadata(archive, pattern)
37
+ puts "Metadata updated successfully"
38
+ end
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def zip?(path)
45
+ path.end_with?(".zip")
46
+ end
47
+
48
+ def seven_zip?(path)
49
+ path.end_with?(".7z")
50
+ end
51
+
52
+ # True when no edit option was given — editing would be a no-op
53
+ def editing_nothing?
54
+ %i[comment set_mtime chmod set_attribute].none? { |key| options[key] }
55
+ end
56
+
57
+ # Read-only view for 7z archives through the handler registry;
58
+ # the edit path is zip-only
59
+ def show_seven_zip_metadata(archive_path, pattern)
60
+ if options[:comment] || options[:set_mtime] ||
61
+ options[:chmod] || options[:set_attribute]
62
+ raise ArgumentError,
63
+ "Metadata editing is only supported for ZIP archives"
64
+ end
65
+
66
+ entries = Omnizip.list_archive(archive_path, details: true)
67
+
68
+ if pattern
69
+ entries = entries.select do |entry|
70
+ File.fnmatch(pattern, entry[:name])
71
+ end
72
+ if entries.empty?
73
+ warn "No entries match pattern: #{pattern}"
74
+ return
75
+ end
76
+
77
+ entries.each { |entry| show_seven_zip_entry(entry) }
78
+ else
79
+ files = entries.reject { |entry| entry[:directory] }
80
+ puts "Archive: #{archive_path}"
81
+ puts "Entries: #{entries.size} " \
82
+ "(#{files.size} files, #{entries.size - files.size} dirs)"
83
+ puts "Total size: #{format_size(files.sum { |entry| entry[:size] })}"
84
+ end
85
+ end
86
+
87
+ # The display is driven by the registry's field contract for
88
+ # :seven_zip — optional lines print only for registered fields.
89
+ def show_seven_zip_entry(entry)
90
+ registry = Omnizip::Metadata::MetadataRegistry
91
+ puts "Entry: #{entry[:name]}" if registry.supports?(:seven_zip, :name)
92
+ puts " Type: #{entry[:directory] ? 'Directory' : 'File'}" if registry.supports?(:seven_zip, :directory)
93
+ puts " Size: #{format_size(entry[:size])}" if registry.supports?(:seven_zip, :size)
94
+ # Per-entry packed sizes are not tracked by the parser
95
+ if registry.supports?(:seven_zip, :compressed_size) &&
96
+ entry[:compressed_size]&.positive?
97
+ puts " Compressed: #{format_size(entry[:compressed_size])}"
98
+ end
99
+ if registry.supports?(:seven_zip, :mtime) && entry[:mtime]
100
+ puts " Modified: #{entry[:mtime]}"
101
+ end
102
+ if registry.supports?(:seven_zip, :crc) && entry[:crc]
103
+ puts " CRC32: 0x#{entry[:crc].to_s(16).upcase}"
104
+ end
105
+ end
106
+
107
+ def show_metadata(archive, pattern)
108
+ if pattern
109
+ # Show entry metadata
110
+ entry = archive.get_entry(pattern)
111
+ unless entry
112
+ warn "Entry not found: #{pattern}"
113
+ return
114
+ end
115
+
116
+ show_entry_metadata(entry)
117
+ else
118
+ # Show archive metadata
119
+ show_archive_metadata(archive)
120
+ end
121
+ end
122
+
123
+ def show_archive_metadata(archive)
124
+ metadata = archive.metadata
125
+ puts "Archive: #{archive.name}"
126
+ puts "Comment: #{metadata.comment}" unless metadata.comment.empty?
127
+ puts "Created: #{metadata.created_at}" if metadata.created_at
128
+ puts "Modified: #{metadata.modified_at}" if metadata.modified_at
129
+ puts "Entries: #{metadata.entry_count} (#{metadata.file_count} files, #{metadata.directory_count} dirs)"
130
+ puts "Total size: #{format_size(metadata.total_size)}"
131
+ puts "Compressed: #{format_size(metadata.total_compressed_size)}"
132
+ puts "Ratio: #{(metadata.compression_ratio * 100).round(1)}%"
133
+ end
134
+
135
+ def show_entry_metadata(entry)
136
+ metadata = entry.metadata
137
+ puts "Entry: #{entry.name}"
138
+ puts "Comment: #{metadata.comment}" unless metadata.comment.empty?
139
+ puts "Modified: #{metadata.mtime}"
140
+ puts "Permissions: 0#{metadata.unix_permissions.to_s(8)}"
141
+ puts "Size: #{format_size(entry.size)}"
142
+ puts "Compressed: #{format_size(entry.compressed_size)}"
143
+ puts "CRC32: 0x#{entry.crc.to_s(16).upcase}"
144
+ puts "Type: #{entry.directory? ? 'Directory' : 'File'}"
145
+ end
146
+
147
+ def edit_metadata(archive, pattern)
148
+ if pattern
149
+ edit_entry_metadata(archive, pattern)
150
+ else
151
+ edit_archive_metadata(archive)
152
+ end
153
+
154
+ archive.save_metadata
155
+ end
156
+
157
+ def edit_archive_metadata(archive)
158
+ metadata = archive.metadata
159
+
160
+ if options[:comment]
161
+ metadata.comment = options[:comment]
162
+ end
163
+ end
164
+
165
+ def edit_entry_metadata(archive, pattern)
166
+ entries = if pattern.include?("*") || pattern.include?("?")
167
+ # Glob pattern
168
+ archive.entries.select { |e| File.fnmatch(pattern, e.name) }
169
+ else
170
+ # Single entry
171
+ [archive.get_entry(pattern)].compact
172
+ end
173
+
174
+ if entries.empty?
175
+ warn "No entries match pattern: #{pattern}"
176
+ return
177
+ end
178
+
179
+ entries.each do |entry|
180
+ metadata = entry.metadata
181
+
182
+ metadata.comment = options[:comment] if options[:comment]
183
+ metadata.mtime = parse_time(options[:set_mtime]) if options[:set_mtime]
184
+ metadata.unix_permissions = parse_permissions(options[:chmod]) if options[:chmod]
185
+ metadata.attributes = options[:set_attribute].to_sym if options[:set_attribute]
186
+
187
+ entry.save_metadata
188
+ end
189
+
190
+ puts "Updated #{entries.size} #{entries.size == 1 ? 'entry' : 'entries'}" if options[:verbose]
191
+ end
192
+
193
+ def parse_time(time_str)
194
+ return Time.now if time_str == "now"
195
+
196
+ Time.parse(time_str)
197
+ rescue ArgumentError => e
198
+ raise ArgumentError, "Invalid time format: #{time_str} (#{e.message})"
199
+ end
200
+
201
+ def parse_permissions(perms_str)
202
+ # Handle octal (755) or decimal
203
+ if perms_str.start_with?("0")
204
+ perms_str.to_i(8)
205
+ else
206
+ perms_str.to_i
207
+ end
208
+ end
209
+
210
+ def format_size(bytes)
211
+ Omnizip::CliOutputFormatter.format_size(bytes)
212
+ end
213
+ end
214
+ end
215
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Commands
5
+ # Command to create PAR2 parity files
6
+ class ParityCreateCommand
7
+ # @return [Array<String>] Files to protect
8
+ attr_reader :files
9
+
10
+ # @return [Hash] Command options
11
+ attr_reader :options
12
+
13
+ # Initialize command
14
+ #
15
+ # @param files [Array<String>] Files or patterns to protect
16
+ # @param options [Hash] Command options
17
+ def initialize(files, options = {})
18
+ @files = files
19
+ @options = default_options.merge(options)
20
+ end
21
+
22
+ # Execute command
23
+ #
24
+ # @return [Integer] Exit code (0 for success)
25
+ def run
26
+ validate_inputs!
27
+
28
+ progress = create_progress_callback if @options[:verbose]
29
+
30
+ created_files = []
31
+ @files.each do |file_pattern|
32
+ par2_files = Parity.create(
33
+ file_pattern,
34
+ redundancy: @options[:redundancy],
35
+ block_size: @options[:block_size],
36
+ output_dir: @options[:output_dir],
37
+ progress: progress,
38
+ )
39
+
40
+ created_files.concat(par2_files)
41
+ end
42
+
43
+ report_success(created_files)
44
+ 0
45
+ rescue StandardError => e
46
+ report_error(e)
47
+ 1
48
+ end
49
+
50
+ private
51
+
52
+ # Default command options
53
+ #
54
+ # @return [Hash] Default options
55
+ def default_options
56
+ {
57
+ redundancy: 5,
58
+ block_size: Parity::Par2Creator::DEFAULT_BLOCK_SIZE,
59
+ output_dir: nil,
60
+ verbose: false,
61
+ }
62
+ end
63
+
64
+ # Validate command inputs
65
+ #
66
+ # @raise [ArgumentError] if inputs invalid
67
+ def validate_inputs!
68
+ raise ArgumentError, "No files specified" if @files.empty?
69
+
70
+ unless @options[:redundancy].between?(0, 100)
71
+ raise ArgumentError, "Redundancy must be 0-100%"
72
+ end
73
+ end
74
+
75
+ # Create progress callback
76
+ #
77
+ # @return [Proc] Progress callback
78
+ def create_progress_callback
79
+ ->(percent, message) do
80
+ puts "[#{percent.to_s.rjust(3)}%] #{message}"
81
+ end
82
+ end
83
+
84
+ # Report successful creation
85
+ #
86
+ # @param files [Array<String>] Created files
87
+ def report_success(files)
88
+ puts "\nāœ“ Created #{files.size} PAR2 file(s):"
89
+ files.each do |file|
90
+ size = File.size(file)
91
+ puts " - #{File.basename(file)} (#{format_size(size)})"
92
+ end
93
+ puts "\nRedundancy: #{@options[:redundancy]}%"
94
+ puts "Block size: #{format_size(@options[:block_size])}"
95
+ end
96
+
97
+ # Report error
98
+ #
99
+ # @param error [Exception] Error that occurred
100
+ def report_error(error)
101
+ puts "\nāœ— Failed to create PAR2 files:"
102
+ puts " #{error.message}"
103
+ end
104
+
105
+ # Format byte size for display
106
+ #
107
+ # @param bytes [Integer] Size in bytes
108
+ # @return [String] Formatted size
109
+ def format_size(bytes)
110
+ Omnizip::CliOutputFormatter.format_size(bytes)
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Commands
5
+ # Command to repair files using PAR2
6
+ class ParityRepairCommand
7
+ # @return [String] PAR2 file path
8
+ attr_reader :par2_file
9
+
10
+ # @return [Hash] Command options
11
+ attr_reader :options
12
+
13
+ # Initialize command
14
+ #
15
+ # @param par2_file [String] Path to .par2 index file
16
+ # @param options [Hash] Command options
17
+ def initialize(par2_file, options = {})
18
+ @par2_file = par2_file
19
+ @options = default_options.merge(options)
20
+ end
21
+
22
+ # Execute command
23
+ #
24
+ # @return [Integer] Exit code (0 for success)
25
+ def run
26
+ validate_inputs!
27
+
28
+ puts "Repairing files with PAR2: #{File.basename(@par2_file)}"
29
+ puts
30
+
31
+ progress = create_progress_callback if @options[:verbose]
32
+
33
+ result = Parity.repair(
34
+ @par2_file,
35
+ output_dir: @options[:output_dir],
36
+ progress: progress,
37
+ )
38
+
39
+ display_results(result)
40
+
41
+ result.success? ? 0 : 1
42
+ rescue StandardError => e
43
+ report_error(e)
44
+ 1
45
+ end
46
+
47
+ private
48
+
49
+ # Default command options
50
+ #
51
+ # @return [Hash] Default options
52
+ def default_options
53
+ {
54
+ output_dir: nil,
55
+ verbose: false,
56
+ }
57
+ end
58
+
59
+ # Validate command inputs
60
+ #
61
+ # @raise [ArgumentError] if inputs invalid
62
+ def validate_inputs!
63
+ unless File.exist?(@par2_file)
64
+ raise ArgumentError, "PAR2 file not found: #{@par2_file}"
65
+ end
66
+ end
67
+
68
+ # Create progress callback
69
+ #
70
+ # @return [Proc] Progress callback
71
+ def create_progress_callback
72
+ ->(percent, message) do
73
+ puts "[#{percent.to_s.rjust(3)}%] #{message}"
74
+ end
75
+ end
76
+
77
+ # Display repair results
78
+ #
79
+ # @param result [Omnizip::Parity::Par2Repairer::RepairResult]
80
+ def display_results(result)
81
+ if result.success?
82
+ puts "āœ“ Repair successful"
83
+ puts
84
+
85
+ if result.recovered_files.any?
86
+ puts "Recovered files (#{result.recovered_files.size}):"
87
+ result.recovered_files.each do |file|
88
+ puts " - #{file}"
89
+ end
90
+ else
91
+ puts "No repairs needed - all files were intact"
92
+ end
93
+
94
+ puts
95
+ puts "Recovered blocks: #{result.recovered_blocks}"
96
+ else
97
+ puts "āœ— Repair failed"
98
+ puts
99
+ puts "Error: #{result.error_message}"
100
+ puts
101
+
102
+ if result.unrecoverable.any?
103
+ puts "Unrecoverable files (#{result.unrecoverable.size}):"
104
+ result.unrecoverable.each do |file|
105
+ puts " - #{file}"
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ # Report error
112
+ #
113
+ # @param error [Exception] Error that occurred
114
+ def report_error(error)
115
+ puts "\nāœ— Repair failed:"
116
+ puts " #{error.message}"
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Commands
5
+ # Command to verify files using PAR2
6
+ class ParityVerifyCommand
7
+ # @return [String] PAR2 file path
8
+ attr_reader :par2_file
9
+
10
+ # @return [Hash] Command options
11
+ attr_reader :options
12
+
13
+ # Initialize command
14
+ #
15
+ # @param par2_file [String] Path to .par2 index file
16
+ # @param options [Hash] Command options
17
+ def initialize(par2_file, options = {})
18
+ @par2_file = par2_file
19
+ @options = default_options.merge(options)
20
+ end
21
+
22
+ # Execute command
23
+ #
24
+ # @return [Integer] Exit code (0 if all OK, 1 if damage, 2 if error)
25
+ def run
26
+ validate_inputs!
27
+
28
+ puts "Verifying files with PAR2: #{File.basename(@par2_file)}"
29
+ puts
30
+
31
+ result = Parity.verify(@par2_file)
32
+
33
+ display_results(result)
34
+
35
+ # Exit code based on results
36
+ if result.all_ok?
37
+ 0
38
+ elsif result.repairable?
39
+ 1 # Damage but repairable
40
+ else
41
+ 2 # Damage not repairable
42
+ end
43
+ rescue StandardError => e
44
+ report_error(e)
45
+ 2
46
+ end
47
+
48
+ private
49
+
50
+ # Default command options
51
+ #
52
+ # @return [Hash] Default options
53
+ def default_options
54
+ {
55
+ verbose: false,
56
+ }
57
+ end
58
+
59
+ # Validate command inputs
60
+ #
61
+ # @raise [ArgumentError] if inputs invalid
62
+ def validate_inputs!
63
+ unless File.exist?(@par2_file)
64
+ raise ArgumentError, "PAR2 file not found: #{@par2_file}"
65
+ end
66
+ end
67
+
68
+ # Display verification results
69
+ #
70
+ # @param result [Omnizip::Parity::Par2Verifier::VerificationResult]
71
+ def display_results(result)
72
+ if result.all_ok?
73
+ puts "āœ“ All files verified successfully"
74
+ puts
75
+ puts "Total blocks: #{result.total_blocks}"
76
+ puts "Recovery blocks available: #{result.recovery_blocks}"
77
+ else
78
+ puts "āœ— File corruption detected"
79
+ puts
80
+
81
+ if result.damaged_files.any?
82
+ puts "Damaged files (#{result.damaged_files.size}):"
83
+ result.damaged_files.each do |file|
84
+ puts " - #{file}"
85
+ end
86
+ puts
87
+ end
88
+
89
+ if result.missing_files.any?
90
+ puts "Missing files (#{result.missing_files.size}):"
91
+ result.missing_files.each do |file|
92
+ puts " - #{file}"
93
+ end
94
+ puts
95
+ end
96
+
97
+ puts "Damaged blocks: #{result.damaged_blocks.size}"
98
+ puts "Total blocks: #{result.total_blocks}"
99
+ puts "Recovery blocks available: #{result.recovery_blocks}"
100
+ puts
101
+
102
+ if result.repairable?
103
+ puts "āœ“ Damage is repairable"
104
+ puts " Run repair command to fix files:"
105
+ puts " omnizip parity repair #{@par2_file}"
106
+ else
107
+ puts "āœ— Damage exceeds recovery capacity"
108
+ puts " Cannot repair: insufficient recovery blocks"
109
+ end
110
+ end
111
+ end
112
+
113
+ # Report error
114
+ #
115
+ # @param error [Exception] Error that occurred
116
+ def report_error(error)
117
+ puts "\nāœ— Verification failed:"
118
+ puts " #{error.message}"
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Commands
5
+ # Command to list available compression profiles
6
+ class ProfileListCommand
7
+ def initialize(options = {})
8
+ @options = options
9
+ end
10
+
11
+ def run
12
+ profiles = Omnizip::Profile.registry.all.sort_by(&:name)
13
+
14
+ if @options[:verbose]
15
+ list_detailed(profiles)
16
+ else
17
+ list_simple(profiles)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def list_simple(profiles)
24
+ puts "Available compression profiles:"
25
+ puts ""
26
+
27
+ profiles.each do |profile|
28
+ default_marker = profile.name == :balanced ? " [default]" : ""
29
+ puts format(
30
+ " %-12s - %s%s",
31
+ profile.name,
32
+ profile.description,
33
+ default_marker,
34
+ )
35
+ end
36
+ end
37
+
38
+ def list_detailed(profiles)
39
+ puts "Available compression profiles:"
40
+ puts ""
41
+
42
+ profiles.each do |profile|
43
+ puts "Profile: #{profile.name}"
44
+ puts " Algorithm: #{profile.algorithm}"
45
+ puts " Level: #{profile.level}"
46
+ puts " Filter: #{profile.filter || 'none'}"
47
+ puts " Solid: #{profile.solid}"
48
+ puts " Description: #{profile.description}"
49
+ puts ""
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Commands
5
+ # Command to show details of a specific compression profile
6
+ class ProfileShowCommand
7
+ def initialize(options = {})
8
+ @options = options
9
+ end
10
+
11
+ def run(profile_name)
12
+ profile_sym = profile_name.to_sym
13
+ profile = Omnizip::Profile.get(profile_sym)
14
+
15
+ unless profile
16
+ warn "Profile '#{profile_name}' not found"
17
+ warn ""
18
+ warn "Available profiles:"
19
+ Omnizip::Profile.list.each { |name| warn " - #{name}" }
20
+ exit 1
21
+ end
22
+
23
+ display_profile(profile)
24
+ end
25
+
26
+ private
27
+
28
+ def display_profile(profile)
29
+ puts "Profile: #{profile.name}"
30
+ puts "Algorithm: #{profile.algorithm}"
31
+ puts "Level: #{profile.level}"
32
+ puts "Filter: #{profile.filter || 'none'}"
33
+ puts "Solid: #{profile.solid}"
34
+ puts "Description: #{profile.description}"
35
+
36
+ # ProfileRegistry accepts any CompressionProfile subclass.
37
+ # allowed: a registered subclass may expose base_profile
38
+ return unless profile.respond_to?(:base_profile) && profile.base_profile
39
+
40
+ puts "Based on: #{profile.base_profile.name}"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ # CLI command implementations
5
+ module Commands
6
+ autoload :CompressCommand, "omnizip/commands/compress_command"
7
+ autoload :DecompressCommand, "omnizip/commands/decompress_command"
8
+ autoload :ListCommand, "omnizip/commands/list_command"
9
+ autoload :ArchiveCreateCommand, "omnizip/commands/archive_create_command"
10
+ autoload :ArchiveExtractCommand, "omnizip/commands/archive_extract_command"
11
+ autoload :ArchiveListCommand, "omnizip/commands/archive_list_command"
12
+ autoload :ProfileListCommand, "omnizip/commands/profile_list_command"
13
+ autoload :ProfileShowCommand, "omnizip/commands/profile_show_command"
14
+ autoload :MetadataCommand, "omnizip/commands/metadata_command"
15
+ autoload :ArchiveVerifyCommand, "omnizip/commands/archive_verify_command"
16
+ autoload :ArchiveRepairCommand, "omnizip/commands/archive_repair_command"
17
+ autoload :ParityCreateCommand, "omnizip/commands/parity_create_command"
18
+ autoload :ParityVerifyCommand, "omnizip/commands/parity_verify_command"
19
+ autoload :ParityRepairCommand, "omnizip/commands/parity_repair_command"
20
+ end
21
+ end