omnizip 0.3.1

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 (511) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +32 -0
  4. data/.rubocop_todo.yml +754 -0
  5. data/COPYING +502 -0
  6. data/Gemfile +17 -0
  7. data/LICENSE +12 -0
  8. data/README.adoc +1045 -0
  9. data/Rakefile +12 -0
  10. data/benchmark/README.md +260 -0
  11. data/benchmark/benchmark_suite.rb +125 -0
  12. data/benchmark/compression_bench.rb +181 -0
  13. data/benchmark/filter_bench.rb +180 -0
  14. data/benchmark/models/benchmark_result.rb +59 -0
  15. data/benchmark/models/comparison_result.rb +69 -0
  16. data/benchmark/profile_suite.rb +167 -0
  17. data/benchmark/reporter.rb +150 -0
  18. data/benchmark/run_benchmarks.rb +66 -0
  19. data/benchmark/test_data.rb +137 -0
  20. data/config/formats/rar3_spec.yml +91 -0
  21. data/config/formats/rar5_spec.yml +102 -0
  22. data/docs/.github/workflows/docs.yml +142 -0
  23. data/docs/.gitignore +21 -0
  24. data/docs/.lychee.toml +67 -0
  25. data/docs/Gemfile +13 -0
  26. data/docs/RAR_WRITE_SUPPORT.md +26 -0
  27. data/docs/README.md +101 -0
  28. data/docs/_config.yml +112 -0
  29. data/docs/assets/logo.svg +1 -0
  30. data/docs/assets/omnizip-logo.pdf +1540 -11
  31. data/docs/comparison/feature-matrix.adoc +694 -0
  32. data/docs/comparison/index.adoc +113 -0
  33. data/docs/comparison/vs-7zip.adoc +309 -0
  34. data/docs/comparison/vs-peazip.adoc +77 -0
  35. data/docs/comparison/vs-rubyzip.adoc +342 -0
  36. data/docs/comparison/vs-winrar.adoc +100 -0
  37. data/docs/compatibility.adoc +579 -0
  38. data/docs/concepts/index.adoc +129 -0
  39. data/docs/developer/architecture.adoc +256 -0
  40. data/docs/developer/contributing.adoc +158 -0
  41. data/docs/developer/index.adoc +25 -0
  42. data/docs/developer/testing.adoc +212 -0
  43. data/docs/getting-started/basic-usage.adoc +271 -0
  44. data/docs/getting-started/index.adoc +42 -0
  45. data/docs/getting-started/installation.adoc +138 -0
  46. data/docs/getting-started/quick-start.adoc +185 -0
  47. data/docs/getting-started/your-first-archive.adoc +218 -0
  48. data/docs/guides/advanced-features/encryption.adoc +300 -0
  49. data/docs/guides/advanced-features/index.adoc +49 -0
  50. data/docs/guides/advanced-features/parallel-processing.adoc +246 -0
  51. data/docs/guides/advanced-features/progress-tracking.adoc +320 -0
  52. data/docs/guides/advanced-features/streaming.adoc +212 -0
  53. data/docs/guides/archive-formats/gzip-format.adoc +107 -0
  54. data/docs/guides/archive-formats/index.adoc +130 -0
  55. data/docs/guides/archive-formats/rar-format.adoc +104 -0
  56. data/docs/guides/archive-formats/rar5.adoc +521 -0
  57. data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
  58. data/docs/guides/archive-formats/tar-format.adoc +106 -0
  59. data/docs/guides/archive-formats/xz-format.adoc +118 -0
  60. data/docs/guides/archive-formats/zip-format.adoc +35 -0
  61. data/docs/guides/compression-algorithms/bzip2.adoc +113 -0
  62. data/docs/guides/compression-algorithms/deflate.adoc +319 -0
  63. data/docs/guides/compression-algorithms/index.adoc +190 -0
  64. data/docs/guides/compression-algorithms/lzma.adoc +398 -0
  65. data/docs/guides/compression-algorithms/lzma2.adoc +327 -0
  66. data/docs/guides/compression-algorithms/ppmd.adoc +316 -0
  67. data/docs/guides/compression-algorithms/zstandard.adoc +361 -0
  68. data/docs/guides/creating-archives.adoc +354 -0
  69. data/docs/guides/extracting-archives.adoc +53 -0
  70. data/docs/guides/format-conversion.adoc +64 -0
  71. data/docs/guides/index.adoc +49 -0
  72. data/docs/guides/migration-rubyzip.adoc +217 -0
  73. data/docs/guides/parity-archives.adoc +605 -0
  74. data/docs/guides/performance-tuning.adoc +88 -0
  75. data/docs/index.adoc +218 -0
  76. data/docs/lychee.toml +67 -0
  77. data/docs/reference/api/overview.adoc +188 -0
  78. data/docs/reference/cli/compress-command.adoc +114 -0
  79. data/docs/reference/cli/overview.adoc +140 -0
  80. data/docs/reference/index.adoc +26 -0
  81. data/docs/resources/faq.adoc +185 -0
  82. data/docs/resources/quick-reference.adoc +222 -0
  83. data/docs/troubleshooting/index.adoc +208 -0
  84. data/examples/api_comparison.rb +205 -0
  85. data/examples/deflate64_example.rb +96 -0
  86. data/examples/par2_demo.rb +121 -0
  87. data/examples/quick_start_native.rb +150 -0
  88. data/examples/quick_start_rubyzip.rb +115 -0
  89. data/examples/rubyzip_compatibility_demo.rb +194 -0
  90. data/exe/omnizip +27 -0
  91. data/lib/omnizip/algorithm.rb +130 -0
  92. data/lib/omnizip/algorithm_registry.rb +86 -0
  93. data/lib/omnizip/algorithms/.keep +0 -0
  94. data/lib/omnizip/algorithms/bzip2/bwt.rb +225 -0
  95. data/lib/omnizip/algorithms/bzip2/decoder.rb +193 -0
  96. data/lib/omnizip/algorithms/bzip2/encoder.rb +237 -0
  97. data/lib/omnizip/algorithms/bzip2/huffman.rb +206 -0
  98. data/lib/omnizip/algorithms/bzip2/mtf.rb +101 -0
  99. data/lib/omnizip/algorithms/bzip2/rle.rb +151 -0
  100. data/lib/omnizip/algorithms/bzip2.rb +130 -0
  101. data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
  102. data/lib/omnizip/algorithms/deflate/decoder.rb +38 -0
  103. data/lib/omnizip/algorithms/deflate/encoder.rb +46 -0
  104. data/lib/omnizip/algorithms/deflate.rb +128 -0
  105. data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
  106. data/lib/omnizip/algorithms/deflate64/decoder.rb +153 -0
  107. data/lib/omnizip/algorithms/deflate64/encoder.rb +98 -0
  108. data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +354 -0
  109. data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +142 -0
  110. data/lib/omnizip/algorithms/deflate64.rb +109 -0
  111. data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
  112. data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
  113. data/lib/omnizip/algorithms/lzma/decoder.rb +148 -0
  114. data/lib/omnizip/algorithms/lzma/dictionary.rb +69 -0
  115. data/lib/omnizip/algorithms/lzma/distance_coder.rb +415 -0
  116. data/lib/omnizip/algorithms/lzma/encoder.rb +142 -0
  117. data/lib/omnizip/algorithms/lzma/length_coder.rb +260 -0
  118. data/lib/omnizip/algorithms/lzma/literal_decoder.rb +320 -0
  119. data/lib/omnizip/algorithms/lzma/literal_encoder.rb +210 -0
  120. data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +341 -0
  121. data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +192 -0
  122. data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
  123. data/lib/omnizip/algorithms/lzma/match.rb +32 -0
  124. data/lib/omnizip/algorithms/lzma/match_finder.rb +205 -0
  125. data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
  126. data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +88 -0
  127. data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +130 -0
  128. data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
  129. data/lib/omnizip/algorithms/lzma/range_coder.rb +85 -0
  130. data/lib/omnizip/algorithms/lzma/range_decoder.rb +434 -0
  131. data/lib/omnizip/algorithms/lzma/range_encoder.rb +194 -0
  132. data/lib/omnizip/algorithms/lzma/state.rb +127 -0
  133. data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +325 -0
  134. data/lib/omnizip/algorithms/lzma/xz_encoder.rb +426 -0
  135. data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +645 -0
  136. data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +227 -0
  137. data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +169 -0
  138. data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +261 -0
  139. data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
  140. data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +331 -0
  141. data/lib/omnizip/algorithms/lzma/xz_state.rb +116 -0
  142. data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +2055 -0
  143. data/lib/omnizip/algorithms/lzma.rb +238 -0
  144. data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +182 -0
  145. data/lib/omnizip/algorithms/lzma2/constants.rb +41 -0
  146. data/lib/omnizip/algorithms/lzma2/encoder.rb +147 -0
  147. data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +161 -0
  148. data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
  149. data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +127 -0
  150. data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
  151. data/lib/omnizip/algorithms/lzma2.rb +141 -0
  152. data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
  153. data/lib/omnizip/algorithms/ppmd7/context.rb +154 -0
  154. data/lib/omnizip/algorithms/ppmd7/decoder.rb +126 -0
  155. data/lib/omnizip/algorithms/ppmd7/encoder.rb +163 -0
  156. data/lib/omnizip/algorithms/ppmd7/model.rb +248 -0
  157. data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
  158. data/lib/omnizip/algorithms/ppmd7.rb +116 -0
  159. data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
  160. data/lib/omnizip/algorithms/ppmd8/context.rb +34 -0
  161. data/lib/omnizip/algorithms/ppmd8/decoder.rb +107 -0
  162. data/lib/omnizip/algorithms/ppmd8/encoder.rb +138 -0
  163. data/lib/omnizip/algorithms/ppmd8/model.rb +250 -0
  164. data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
  165. data/lib/omnizip/algorithms/ppmd8.rb +82 -0
  166. data/lib/omnizip/algorithms/ppmd_base.rb +138 -0
  167. data/lib/omnizip/algorithms/sevenzip_lzma2.rb +123 -0
  168. data/lib/omnizip/algorithms/xz_lzma2.rb +118 -0
  169. data/lib/omnizip/algorithms/zstandard/constants.rb +25 -0
  170. data/lib/omnizip/algorithms/zstandard/decoder.rb +46 -0
  171. data/lib/omnizip/algorithms/zstandard/encoder.rb +51 -0
  172. data/lib/omnizip/algorithms/zstandard.rb +138 -0
  173. data/lib/omnizip/buffer/memory_archive.rb +251 -0
  174. data/lib/omnizip/buffer/memory_extractor.rb +224 -0
  175. data/lib/omnizip/buffer.rb +176 -0
  176. data/lib/omnizip/checksum_registry.rb +114 -0
  177. data/lib/omnizip/checksums/crc32.rb +100 -0
  178. data/lib/omnizip/checksums/crc64.rb +101 -0
  179. data/lib/omnizip/checksums/crc_base.rb +158 -0
  180. data/lib/omnizip/checksums/verifier.rb +131 -0
  181. data/lib/omnizip/chunked/memory_manager.rb +194 -0
  182. data/lib/omnizip/chunked/reader.rb +78 -0
  183. data/lib/omnizip/chunked/writer.rb +120 -0
  184. data/lib/omnizip/chunked.rb +129 -0
  185. data/lib/omnizip/cli/output_formatter.rb +104 -0
  186. data/lib/omnizip/cli.rb +572 -0
  187. data/lib/omnizip/commands/.keep +0 -0
  188. data/lib/omnizip/commands/archive_create_command.rb +427 -0
  189. data/lib/omnizip/commands/archive_extract_command.rb +272 -0
  190. data/lib/omnizip/commands/archive_list_command.rb +218 -0
  191. data/lib/omnizip/commands/archive_repair_command.rb +131 -0
  192. data/lib/omnizip/commands/archive_verify_command.rb +117 -0
  193. data/lib/omnizip/commands/compress_command.rb +117 -0
  194. data/lib/omnizip/commands/decompress_command.rb +120 -0
  195. data/lib/omnizip/commands/list_command.rb +53 -0
  196. data/lib/omnizip/commands/metadata_command.rb +153 -0
  197. data/lib/omnizip/commands/parity_create_command.rb +122 -0
  198. data/lib/omnizip/commands/parity_repair_command.rb +122 -0
  199. data/lib/omnizip/commands/parity_verify_command.rb +124 -0
  200. data/lib/omnizip/commands/profile_list_command.rb +56 -0
  201. data/lib/omnizip/commands/profile_show_command.rb +44 -0
  202. data/lib/omnizip/convenience.rb +359 -0
  203. data/lib/omnizip/converter/conversion_registry.rb +49 -0
  204. data/lib/omnizip/converter/conversion_strategy.rb +121 -0
  205. data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +97 -0
  206. data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +112 -0
  207. data/lib/omnizip/converter.rb +105 -0
  208. data/lib/omnizip/crypto/aes256/cipher.rb +100 -0
  209. data/lib/omnizip/crypto/aes256/constants.rb +28 -0
  210. data/lib/omnizip/crypto/aes256/key_derivation.rb +101 -0
  211. data/lib/omnizip/crypto/aes256.rb +102 -0
  212. data/lib/omnizip/error.rb +106 -0
  213. data/lib/omnizip/eta/exponential_smoothing_estimator.rb +98 -0
  214. data/lib/omnizip/eta/moving_average_estimator.rb +99 -0
  215. data/lib/omnizip/eta/rate_calculator.rb +104 -0
  216. data/lib/omnizip/eta/sample_history.rb +143 -0
  217. data/lib/omnizip/eta/time_estimator.rb +106 -0
  218. data/lib/omnizip/eta.rb +63 -0
  219. data/lib/omnizip/extraction/filter_chain.rb +177 -0
  220. data/lib/omnizip/extraction/glob_pattern.rb +140 -0
  221. data/lib/omnizip/extraction/pattern_matcher.rb +70 -0
  222. data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
  223. data/lib/omnizip/extraction/regex_pattern.rb +50 -0
  224. data/lib/omnizip/extraction/selective_extractor.rb +240 -0
  225. data/lib/omnizip/extraction.rb +111 -0
  226. data/lib/omnizip/file_type/mime_classifier.rb +144 -0
  227. data/lib/omnizip/file_type.rb +113 -0
  228. data/lib/omnizip/filter.rb +139 -0
  229. data/lib/omnizip/filter_pipeline.rb +108 -0
  230. data/lib/omnizip/filter_registry.rb +166 -0
  231. data/lib/omnizip/filters/bcj.rb +279 -0
  232. data/lib/omnizip/filters/bcj2/constants.rb +53 -0
  233. data/lib/omnizip/filters/bcj2/decoder.rb +200 -0
  234. data/lib/omnizip/filters/bcj2/encoder.rb +61 -0
  235. data/lib/omnizip/filters/bcj2/stream_data.rb +93 -0
  236. data/lib/omnizip/filters/bcj2.rb +99 -0
  237. data/lib/omnizip/filters/bcj_arm.rb +176 -0
  238. data/lib/omnizip/filters/bcj_arm64.rb +244 -0
  239. data/lib/omnizip/filters/bcj_ia64.rb +196 -0
  240. data/lib/omnizip/filters/bcj_ppc.rb +190 -0
  241. data/lib/omnizip/filters/bcj_sparc.rb +176 -0
  242. data/lib/omnizip/filters/bcj_x86.rb +193 -0
  243. data/lib/omnizip/filters/delta.rb +196 -0
  244. data/lib/omnizip/filters/filter_base.rb +72 -0
  245. data/lib/omnizip/filters/registry.rb +123 -0
  246. data/lib/omnizip/filters/xz_delta.rb +258 -0
  247. data/lib/omnizip/format_detector.rb +162 -0
  248. data/lib/omnizip/format_registry.rb +59 -0
  249. data/lib/omnizip/formats/.keep +0 -0
  250. data/lib/omnizip/formats/bzip2_file.rb +172 -0
  251. data/lib/omnizip/formats/cpio/constants.rb +55 -0
  252. data/lib/omnizip/formats/cpio/entry.rb +385 -0
  253. data/lib/omnizip/formats/cpio/reader.rb +196 -0
  254. data/lib/omnizip/formats/cpio/writer.rb +234 -0
  255. data/lib/omnizip/formats/cpio.rb +140 -0
  256. data/lib/omnizip/formats/format_spec_loader.rb +230 -0
  257. data/lib/omnizip/formats/gzip.rb +238 -0
  258. data/lib/omnizip/formats/iso/directory_builder.rb +297 -0
  259. data/lib/omnizip/formats/iso/directory_record.rb +152 -0
  260. data/lib/omnizip/formats/iso/joliet.rb +204 -0
  261. data/lib/omnizip/formats/iso/path_table.rb +125 -0
  262. data/lib/omnizip/formats/iso/reader.rb +197 -0
  263. data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
  264. data/lib/omnizip/formats/iso/volume_builder.rb +320 -0
  265. data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
  266. data/lib/omnizip/formats/iso/writer.rb +530 -0
  267. data/lib/omnizip/formats/iso.rb +140 -0
  268. data/lib/omnizip/formats/lzip.rb +175 -0
  269. data/lib/omnizip/formats/lzma_alone.rb +171 -0
  270. data/lib/omnizip/formats/rar/archive_repairer.rb +243 -0
  271. data/lib/omnizip/formats/rar/archive_verifier.rb +195 -0
  272. data/lib/omnizip/formats/rar/block_parser.rb +243 -0
  273. data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
  274. data/lib/omnizip/formats/rar/compression/dispatcher.rb +217 -0
  275. data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +216 -0
  276. data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +158 -0
  277. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
  278. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
  279. data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
  280. data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
  281. data/lib/omnizip/formats/rar/compression/ppmd/context.rb +105 -0
  282. data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +219 -0
  283. data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +262 -0
  284. data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
  285. data/lib/omnizip/formats/rar/constants.rb +82 -0
  286. data/lib/omnizip/formats/rar/decompressor.rb +238 -0
  287. data/lib/omnizip/formats/rar/external_writer.rb +312 -0
  288. data/lib/omnizip/formats/rar/header.rb +192 -0
  289. data/lib/omnizip/formats/rar/license_validator.rb +109 -0
  290. data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
  291. data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
  292. data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
  293. data/lib/omnizip/formats/rar/parity_handler.rb +292 -0
  294. data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +202 -0
  295. data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +578 -0
  296. data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
  297. data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
  298. data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +97 -0
  299. data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
  300. data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +166 -0
  301. data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
  302. data/lib/omnizip/formats/rar/rar5/header.rb +187 -0
  303. data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
  304. data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
  305. data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
  306. data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
  307. data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
  308. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +264 -0
  309. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
  310. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +194 -0
  311. data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +109 -0
  312. data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +142 -0
  313. data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
  314. data/lib/omnizip/formats/rar/rar5/vint.rb +65 -0
  315. data/lib/omnizip/formats/rar/rar5/writer.rb +466 -0
  316. data/lib/omnizip/formats/rar/rar_format_base.rb +241 -0
  317. data/lib/omnizip/formats/rar/reader.rb +366 -0
  318. data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
  319. data/lib/omnizip/formats/rar/volume_manager.rb +168 -0
  320. data/lib/omnizip/formats/rar/writer.rb +431 -0
  321. data/lib/omnizip/formats/rar.rb +205 -0
  322. data/lib/omnizip/formats/rar3/compressor.rb +73 -0
  323. data/lib/omnizip/formats/rar3/decompressor.rb +66 -0
  324. data/lib/omnizip/formats/rar3/reader.rb +386 -0
  325. data/lib/omnizip/formats/rar3/writer.rb +219 -0
  326. data/lib/omnizip/formats/rar5/compressor.rb +73 -0
  327. data/lib/omnizip/formats/rar5/decompressor.rb +66 -0
  328. data/lib/omnizip/formats/rar5/reader.rb +342 -0
  329. data/lib/omnizip/formats/rar5/writer.rb +214 -0
  330. data/lib/omnizip/formats/seven_zip/coder_chain.rb +150 -0
  331. data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
  332. data/lib/omnizip/formats/seven_zip/encoded_header.rb +114 -0
  333. data/lib/omnizip/formats/seven_zip/encrypted_header.rb +142 -0
  334. data/lib/omnizip/formats/seven_zip/file_collector.rb +144 -0
  335. data/lib/omnizip/formats/seven_zip/header.rb +106 -0
  336. data/lib/omnizip/formats/seven_zip/header_encryptor.rb +134 -0
  337. data/lib/omnizip/formats/seven_zip/header_writer.rb +466 -0
  338. data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
  339. data/lib/omnizip/formats/seven_zip/models/file_entry.rb +58 -0
  340. data/lib/omnizip/formats/seven_zip/models/folder.rb +69 -0
  341. data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
  342. data/lib/omnizip/formats/seven_zip/parser.rb +660 -0
  343. data/lib/omnizip/formats/seven_zip/reader.rb +458 -0
  344. data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +632 -0
  345. data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +315 -0
  346. data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
  347. data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +162 -0
  348. data/lib/omnizip/formats/seven_zip/writer.rb +740 -0
  349. data/lib/omnizip/formats/seven_zip.rb +93 -0
  350. data/lib/omnizip/formats/tar/constants.rb +73 -0
  351. data/lib/omnizip/formats/tar/entry.rb +94 -0
  352. data/lib/omnizip/formats/tar/header.rb +168 -0
  353. data/lib/omnizip/formats/tar/reader.rb +121 -0
  354. data/lib/omnizip/formats/tar/writer.rb +216 -0
  355. data/lib/omnizip/formats/tar.rb +84 -0
  356. data/lib/omnizip/formats/xz/reader.rb +116 -0
  357. data/lib/omnizip/formats/xz.rb +237 -0
  358. data/lib/omnizip/formats/xz_impl/block_decoder.rb +754 -0
  359. data/lib/omnizip/formats/xz_impl/block_encoder.rb +306 -0
  360. data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
  361. data/lib/omnizip/formats/xz_impl/block_header_parser.rb +186 -0
  362. data/lib/omnizip/formats/xz_impl/constants.rb +49 -0
  363. data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
  364. data/lib/omnizip/formats/xz_impl/index_encoder.rb +122 -0
  365. data/lib/omnizip/formats/xz_impl/stream_decoder.rb +468 -0
  366. data/lib/omnizip/formats/xz_impl/stream_encoder.rb +99 -0
  367. data/lib/omnizip/formats/xz_impl/stream_footer.rb +81 -0
  368. data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +117 -0
  369. data/lib/omnizip/formats/xz_impl/stream_header.rb +55 -0
  370. data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +108 -0
  371. data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
  372. data/lib/omnizip/formats/xz_impl/writer.rb +421 -0
  373. data/lib/omnizip/formats/zip/central_directory_header.rb +195 -0
  374. data/lib/omnizip/formats/zip/constants.rb +69 -0
  375. data/lib/omnizip/formats/zip/end_of_central_directory.rb +133 -0
  376. data/lib/omnizip/formats/zip/local_file_header.rb +138 -0
  377. data/lib/omnizip/formats/zip/reader.rb +250 -0
  378. data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
  379. data/lib/omnizip/formats/zip/writer.rb +375 -0
  380. data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +104 -0
  381. data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +66 -0
  382. data/lib/omnizip/formats/zip/zip64_extra_field.rb +114 -0
  383. data/lib/omnizip/formats/zip.rb +50 -0
  384. data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
  385. data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
  386. data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
  387. data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
  388. data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
  389. data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +421 -0
  390. data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +465 -0
  391. data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +288 -0
  392. data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +200 -0
  393. data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +197 -0
  394. data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +141 -0
  395. data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +519 -0
  396. data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +723 -0
  397. data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +750 -0
  398. data/lib/omnizip/io/buffered_input.rb +146 -0
  399. data/lib/omnizip/io/buffered_output.rb +105 -0
  400. data/lib/omnizip/io/stream_manager.rb +115 -0
  401. data/lib/omnizip/link_handler/hard_link.rb +79 -0
  402. data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
  403. data/lib/omnizip/link_handler.rb +124 -0
  404. data/lib/omnizip/metadata/archive_metadata.rb +114 -0
  405. data/lib/omnizip/metadata/entry_metadata.rb +146 -0
  406. data/lib/omnizip/metadata/metadata_editor.rb +171 -0
  407. data/lib/omnizip/metadata/metadata_registry.rb +64 -0
  408. data/lib/omnizip/metadata/metadata_validator.rb +99 -0
  409. data/lib/omnizip/metadata.rb +57 -0
  410. data/lib/omnizip/models/.keep +0 -0
  411. data/lib/omnizip/models/algorithm_metadata.rb +73 -0
  412. data/lib/omnizip/models/compression_options.rb +71 -0
  413. data/lib/omnizip/models/conversion_options.rb +87 -0
  414. data/lib/omnizip/models/conversion_result.rb +135 -0
  415. data/lib/omnizip/models/eta_result.rb +46 -0
  416. data/lib/omnizip/models/extraction_rule.rb +115 -0
  417. data/lib/omnizip/models/filter_chain.rb +144 -0
  418. data/lib/omnizip/models/filter_config.rb +183 -0
  419. data/lib/omnizip/models/match_result.rb +124 -0
  420. data/lib/omnizip/models/optimization_suggestion.rb +91 -0
  421. data/lib/omnizip/models/parallel_options.rb +104 -0
  422. data/lib/omnizip/models/performance_result.rb +79 -0
  423. data/lib/omnizip/models/profile_report.rb +82 -0
  424. data/lib/omnizip/models/progress_options.rb +38 -0
  425. data/lib/omnizip/models/split_options.rb +116 -0
  426. data/lib/omnizip/optimization_registry.rb +81 -0
  427. data/lib/omnizip/parallel/job_queue.rb +209 -0
  428. data/lib/omnizip/parallel/job_scheduler.rb +203 -0
  429. data/lib/omnizip/parallel/parallel_compressor.rb +347 -0
  430. data/lib/omnizip/parallel/parallel_extractor.rb +329 -0
  431. data/lib/omnizip/parallel/worker_pool.rb +223 -0
  432. data/lib/omnizip/parallel.rb +149 -0
  433. data/lib/omnizip/parity/chunked_block_processor.rb +196 -0
  434. data/lib/omnizip/parity/galois16.rb +145 -0
  435. data/lib/omnizip/parity/models/creator_packet.rb +73 -0
  436. data/lib/omnizip/parity/models/file_description_packet.rb +133 -0
  437. data/lib/omnizip/parity/models/ifsc_packet.rb +123 -0
  438. data/lib/omnizip/parity/models/main_packet.rb +128 -0
  439. data/lib/omnizip/parity/models/packet.rb +156 -0
  440. data/lib/omnizip/parity/models/packet_registry.rb +109 -0
  441. data/lib/omnizip/parity/models/recovery_slice_packet.rb +78 -0
  442. data/lib/omnizip/parity/par2_creator.rb +531 -0
  443. data/lib/omnizip/parity/par2_repairer.rb +407 -0
  444. data/lib/omnizip/parity/par2_verifier.rb +364 -0
  445. data/lib/omnizip/parity/par2cmdline_algorithm.rb +110 -0
  446. data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
  447. data/lib/omnizip/parity/reed_solomon_decoder.rb +266 -0
  448. data/lib/omnizip/parity/reed_solomon_encoder.rb +111 -0
  449. data/lib/omnizip/parity/reed_solomon_matrix.rb +342 -0
  450. data/lib/omnizip/parity.rb +186 -0
  451. data/lib/omnizip/password/encryption_registry.rb +65 -0
  452. data/lib/omnizip/password/encryption_strategy.rb +96 -0
  453. data/lib/omnizip/password/password_validator.rb +129 -0
  454. data/lib/omnizip/password/winzip_aes_strategy.rb +192 -0
  455. data/lib/omnizip/password/zip_crypto_strategy.rb +141 -0
  456. data/lib/omnizip/password.rb +87 -0
  457. data/lib/omnizip/pipe/stream_compressor.rb +124 -0
  458. data/lib/omnizip/pipe/stream_decompressor.rb +174 -0
  459. data/lib/omnizip/pipe.rb +121 -0
  460. data/lib/omnizip/platform/ntfs_streams.rb +201 -0
  461. data/lib/omnizip/platform.rb +189 -0
  462. data/lib/omnizip/profile/archive_profile.rb +39 -0
  463. data/lib/omnizip/profile/balanced_profile.rb +33 -0
  464. data/lib/omnizip/profile/binary_profile.rb +36 -0
  465. data/lib/omnizip/profile/compression_profile.rb +158 -0
  466. data/lib/omnizip/profile/custom_profile.rb +157 -0
  467. data/lib/omnizip/profile/fast_profile.rb +33 -0
  468. data/lib/omnizip/profile/maximum_profile.rb +33 -0
  469. data/lib/omnizip/profile/profile_detector.rb +110 -0
  470. data/lib/omnizip/profile/profile_registry.rb +161 -0
  471. data/lib/omnizip/profile/text_profile.rb +36 -0
  472. data/lib/omnizip/profile.rb +190 -0
  473. data/lib/omnizip/profiler/memory_profiler.rb +66 -0
  474. data/lib/omnizip/profiler/method_profiler.rb +49 -0
  475. data/lib/omnizip/profiler/report_generator.rb +169 -0
  476. data/lib/omnizip/profiler.rb +204 -0
  477. data/lib/omnizip/progress/callback_reporter.rb +36 -0
  478. data/lib/omnizip/progress/console_reporter.rb +62 -0
  479. data/lib/omnizip/progress/log_reporter.rb +91 -0
  480. data/lib/omnizip/progress/operation_progress.rb +118 -0
  481. data/lib/omnizip/progress/progress_bar.rb +156 -0
  482. data/lib/omnizip/progress/progress_reporter.rb +40 -0
  483. data/lib/omnizip/progress/progress_tracker.rb +190 -0
  484. data/lib/omnizip/progress/silent_reporter.rb +24 -0
  485. data/lib/omnizip/progress.rb +127 -0
  486. data/lib/omnizip/rubyzip_compat.rb +63 -0
  487. data/lib/omnizip/temp/safe_extract.rb +168 -0
  488. data/lib/omnizip/temp/temp_file.rb +124 -0
  489. data/lib/omnizip/temp/temp_file_pool.rb +109 -0
  490. data/lib/omnizip/temp.rb +181 -0
  491. data/lib/omnizip/version.rb +5 -0
  492. data/lib/omnizip/zip/entry.rb +156 -0
  493. data/lib/omnizip/zip/file.rb +485 -0
  494. data/lib/omnizip/zip/input_stream.rb +273 -0
  495. data/lib/omnizip/zip/output_stream.rb +324 -0
  496. data/lib/omnizip.rb +156 -0
  497. data/readme-docs/advanced-features.adoc +515 -0
  498. data/readme-docs/api-usage.adoc +444 -0
  499. data/readme-docs/architecture.adoc +449 -0
  500. data/readme-docs/archive-formats.adoc +479 -0
  501. data/readme-docs/cli-usage.adoc +222 -0
  502. data/readme-docs/compression-algorithms.adoc +442 -0
  503. data/readme-docs/compression-profiles.adoc +247 -0
  504. data/readme-docs/encryption-checksums.adoc +328 -0
  505. data/readme-docs/format-converter.adoc +325 -0
  506. data/readme-docs/installation.adoc +228 -0
  507. data/readme-docs/par2-archives.adoc +608 -0
  508. data/readme-docs/performance-profiler.adoc +389 -0
  509. data/readme-docs/preprocessing-filters.adoc +280 -0
  510. data/xz-file-format-1.2.1.txt +1174 -0
  511. metadata +617 -0
@@ -0,0 +1,73 @@
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 "json"
20
+
21
+ module Omnizip
22
+ module Models
23
+ # Model representing metadata about a compression algorithm.
24
+ #
25
+ # This class encapsulates information about a compression algorithm,
26
+ # including its name, description, version, and capabilities.
27
+ class AlgorithmMetadata
28
+ attr_accessor :name, :description, :version, :author,
29
+ :max_compression_level, :min_compression_level,
30
+ :default_compression_level, :supports_streaming,
31
+ :supports_multithreading
32
+
33
+ def initialize(**kwargs)
34
+ @supports_streaming = false
35
+ @supports_multithreading = false
36
+
37
+ kwargs.each do |key, value|
38
+ instance_variable_set("@#{key}", value)
39
+ end
40
+ end
41
+
42
+ def to_h
43
+ {
44
+ name: @name,
45
+ description: @description,
46
+ version: @version,
47
+ author: @author,
48
+ max_compression_level: @max_compression_level,
49
+ min_compression_level: @min_compression_level,
50
+ default_compression_level: @default_compression_level,
51
+ supports_streaming: @supports_streaming,
52
+ supports_multithreading: @supports_multithreading,
53
+ }.compact
54
+ end
55
+
56
+ # Serialize to JSON
57
+ #
58
+ # @return [String] JSON representation
59
+ def to_json(*args)
60
+ to_h.to_json(*args)
61
+ end
62
+
63
+ # Deserialize from JSON
64
+ #
65
+ # @param json [String] JSON string
66
+ # @return [AlgorithmMetadata] Deserialized instance
67
+ def self.from_json(json)
68
+ data = JSON.parse(json)
69
+ new(**data.transform_keys(&:to_sym))
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,71 @@
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 "json"
20
+
21
+ module Omnizip
22
+ module Models
23
+ # Model representing compression operation options.
24
+ #
25
+ # This class encapsulates configuration options for compression
26
+ # operations, including compression level, threading, and buffer sizes.
27
+ class CompressionOptions
28
+ attr_accessor :level, :dictionary_size, :num_fast_bytes, :match_finder,
29
+ :num_threads, :solid, :buffer_size
30
+
31
+ def initialize(**kwargs)
32
+ @level = 5
33
+ @num_threads = 1
34
+ @solid = false
35
+ @buffer_size = 65_536
36
+
37
+ kwargs.each do |key, value|
38
+ instance_variable_set("@#{key}", value)
39
+ end
40
+ end
41
+
42
+ def to_h
43
+ {
44
+ level: @level,
45
+ dictionary_size: @dictionary_size,
46
+ num_fast_bytes: @num_fast_bytes,
47
+ match_finder: @match_finder,
48
+ num_threads: @num_threads,
49
+ solid: @solid,
50
+ buffer_size: @buffer_size,
51
+ }.compact
52
+ end
53
+
54
+ # Serialize to JSON
55
+ #
56
+ # @return [String] JSON representation
57
+ def to_json(*args)
58
+ to_h.to_json(*args)
59
+ end
60
+
61
+ # Deserialize from JSON
62
+ #
63
+ # @param json [String] JSON string
64
+ # @return [CompressionOptions] Deserialized instance
65
+ def self.from_json(json)
66
+ data = JSON.parse(json)
67
+ new(**data.transform_keys(&:to_sym))
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Models
5
+ # Model for format conversion options
6
+ class ConversionOptions
7
+ attr_accessor :source_format, :target_format, :compression,
8
+ :compression_level, :filter, :preserve_metadata,
9
+ :temp_directory, :solid, :delete_source
10
+
11
+ # Initialize conversion options
12
+ # @param source_format [Symbol, nil] Source format (auto-detect if nil)
13
+ # @param target_format [Symbol] Target format
14
+ # @param compression [Symbol, nil] Compression algorithm
15
+ # @param compression_level [Integer] Compression level (1-9)
16
+ # @param filter [Symbol, nil] Filter to apply
17
+ # @param preserve_metadata [Boolean] Preserve metadata
18
+ # @param temp_directory [String, nil] Temporary directory
19
+ # @param solid [Boolean] Use solid compression (7z only)
20
+ # @param delete_source [Boolean] Delete source after conversion
21
+ def initialize(
22
+ source_format: nil,
23
+ target_format: :seven_zip,
24
+ compression: nil,
25
+ compression_level: 5,
26
+ filter: nil,
27
+ preserve_metadata: true,
28
+ temp_directory: nil,
29
+ solid: true,
30
+ delete_source: false
31
+ )
32
+ @source_format = source_format
33
+ @target_format = target_format
34
+ @compression = compression
35
+ @compression_level = compression_level
36
+ @filter = filter
37
+ @preserve_metadata = preserve_metadata
38
+ @temp_directory = temp_directory
39
+ @solid = solid
40
+ @delete_source = delete_source
41
+ end
42
+
43
+ # Convert to hash
44
+ # @return [Hash] Options as hash
45
+ def to_h
46
+ {
47
+ source_format: source_format,
48
+ target_format: target_format,
49
+ compression: compression,
50
+ compression_level: compression_level,
51
+ filter: filter,
52
+ preserve_metadata: preserve_metadata,
53
+ temp_directory: temp_directory,
54
+ solid: solid,
55
+ delete_source: delete_source,
56
+ }
57
+ end
58
+
59
+ # Validate options
60
+ # @raise [ArgumentError] If options are invalid
61
+ def validate
62
+ validate_format(target_format, "target")
63
+ validate_format(source_format, "source") if source_format
64
+ validate_compression_level
65
+
66
+ true
67
+ end
68
+
69
+ private
70
+
71
+ def validate_format(format, type)
72
+ valid_formats = %i[zip seven_zip 7z]
73
+ return if valid_formats.include?(format)
74
+
75
+ raise ArgumentError, "Invalid #{type} format: #{format}. " \
76
+ "Valid formats: #{valid_formats.join(', ')}"
77
+ end
78
+
79
+ def validate_compression_level
80
+ return if (1..9).cover?(compression_level)
81
+
82
+ raise ArgumentError,
83
+ "Invalid compression level: #{compression_level}. Must be 1-9"
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Models
5
+ # Model for format conversion results
6
+ class ConversionResult
7
+ attr_reader :source_path, :target_path, :source_format, :target_format,
8
+ :source_size, :target_size, :duration, :entry_count,
9
+ :compression_ratio, :warnings
10
+
11
+ # Initialize conversion result
12
+ # @param source_path [String] Source file path
13
+ # @param target_path [String] Target file path
14
+ # @param source_format [Symbol] Source format
15
+ # @param target_format [Symbol] Target format
16
+ # @param source_size [Integer] Source file size in bytes
17
+ # @param target_size [Integer] Target file size in bytes
18
+ # @param duration [Float] Conversion duration in seconds
19
+ # @param entry_count [Integer] Number of entries converted
20
+ # @param warnings [Array<String>] Conversion warnings
21
+ def initialize(
22
+ source_path:,
23
+ target_path:,
24
+ source_format:,
25
+ target_format:,
26
+ source_size:,
27
+ target_size:,
28
+ duration:,
29
+ entry_count:,
30
+ warnings: []
31
+ )
32
+ @source_path = source_path
33
+ @target_path = target_path
34
+ @source_format = source_format
35
+ @target_format = target_format
36
+ @source_size = source_size
37
+ @target_size = target_size
38
+ @duration = duration
39
+ @entry_count = entry_count
40
+ @warnings = warnings
41
+ @compression_ratio = calculate_compression_ratio
42
+ end
43
+
44
+ # Get size reduction percentage
45
+ # @return [Float] Size reduction as percentage
46
+ def size_reduction
47
+ return 0.0 if source_size.zero?
48
+
49
+ ((source_size - target_size).to_f / source_size * 100).round(2)
50
+ end
51
+
52
+ # Get size ratio
53
+ # @return [Float] Target size as percentage of source size
54
+ def size_ratio
55
+ return 0.0 if source_size.zero?
56
+
57
+ (target_size.to_f / source_size * 100).round(2)
58
+ end
59
+
60
+ # Check if conversion resulted in smaller file
61
+ # @return [Boolean] True if target is smaller
62
+ def smaller?
63
+ target_size < source_size
64
+ end
65
+
66
+ # Check if conversion resulted in larger file
67
+ # @return [Boolean] True if target is larger
68
+ def larger?
69
+ target_size > source_size
70
+ end
71
+
72
+ # Check if there were warnings
73
+ # @return [Boolean] True if warnings exist
74
+ def warnings?
75
+ !warnings.empty?
76
+ end
77
+
78
+ # Get average processing speed
79
+ # @return [Float] MB/s processing speed
80
+ def processing_speed
81
+ return 0.0 if duration.zero? || source_size.zero?
82
+
83
+ speed = source_size / duration / 1_048_576.0
84
+ rounded = speed.round(2)
85
+ # Return actual speed if rounding would give 0 but speed is positive
86
+ rounded.zero? && speed.positive? ? speed : rounded
87
+ end
88
+
89
+ # Convert to hash
90
+ # @return [Hash] Result as hash
91
+ def to_h
92
+ {
93
+ source_path: source_path,
94
+ target_path: target_path,
95
+ source_format: source_format,
96
+ target_format: target_format,
97
+ source_size: source_size,
98
+ target_size: target_size,
99
+ size_reduction: size_reduction,
100
+ size_ratio: size_ratio,
101
+ duration: duration,
102
+ entry_count: entry_count,
103
+ processing_speed: processing_speed,
104
+ warnings: warnings,
105
+ }
106
+ end
107
+
108
+ # Format as human-readable string
109
+ # @return [String] Formatted result
110
+ def to_s
111
+ "Converted #{source_path} (#{format_size(source_size)}) to " \
112
+ "#{target_path} (#{format_size(target_size)}) in #{duration.round(2)}s. " \
113
+ "#{size_reduction.positive? ? "Saved #{size_reduction.to_i}%" : "Increased #{(-size_reduction).to_i}%"}"
114
+ end
115
+
116
+ private
117
+
118
+ def calculate_compression_ratio
119
+ return 0.0 if source_size.zero?
120
+
121
+ (1.0 - (target_size.to_f / source_size)).round(4)
122
+ end
123
+
124
+ def format_size(bytes)
125
+ return "0 B" if bytes.zero?
126
+
127
+ units = %w[B KB MB GB TB]
128
+ exp = (Math.log(bytes) / Math.log(1024)).to_i
129
+ exp = [exp, units.size - 1].min
130
+
131
+ "%.1f %s" % [bytes.to_f / (1024**exp), units[exp]]
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (C) 2025 Ribose Inc.
5
+ #
6
+
7
+ module Omnizip
8
+ module Models
9
+ # Model representing an ETA (Estimated Time to Arrival) calculation result.
10
+ #
11
+ # This class encapsulates the result of ETA calculations, including
12
+ # seconds remaining, formatted time string, and confidence interval.
13
+ class ETAResult
14
+ attr_accessor :seconds_remaining, :formatted, :confidence_lower,
15
+ :confidence_upper
16
+
17
+ # Get confidence interval as array
18
+ #
19
+ # @return [Array<Float>] [lower, upper] bounds in seconds
20
+ def confidence_interval
21
+ [confidence_lower, confidence_upper]
22
+ end
23
+
24
+ # Check if ETA is reliable (confidence interval is reasonable)
25
+ #
26
+ # @return [Boolean] true if confidence interval is within 50% of estimate
27
+ def reliable?
28
+ unless seconds_remaining && confidence_lower && confidence_upper
29
+ return false
30
+ end
31
+
32
+ range = confidence_upper - confidence_lower
33
+ range < (seconds_remaining * 0.5)
34
+ end
35
+
36
+ def to_h
37
+ {
38
+ seconds_remaining: @seconds_remaining,
39
+ formatted: @formatted,
40
+ confidence_lower: @confidence_lower,
41
+ confidence_upper: @confidence_upper,
42
+ }.compact
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Models
5
+ # Represents a rule for extracting files from an archive
6
+ #
7
+ # Defines what files to extract and how to extract them using
8
+ # patterns, predicates, and options.
9
+ class ExtractionRule
10
+ attr_reader :patterns, :predicates, :options
11
+
12
+ # Initialize a new extraction rule
13
+ #
14
+ # @param patterns [Array<String, Regexp>] Patterns to match
15
+ # @param predicates [Array<Proc>] Custom predicates for matching
16
+ # @param options [Hash] Extraction options
17
+ # @option options [Boolean] :preserve_paths Keep directory structure
18
+ # @option options [Boolean] :flatten Extract all to destination root
19
+ # @option options [Boolean] :overwrite Overwrite existing files
20
+ # @option options [String] :dest_prefix Prefix for destination paths
21
+ def initialize(patterns: [], predicates: [], options: {})
22
+ @patterns = Array(patterns)
23
+ @predicates = Array(predicates)
24
+ @options = default_options.merge(options)
25
+ end
26
+
27
+ # Add a pattern to the rule
28
+ #
29
+ # @param pattern [String, Regexp] Pattern to add
30
+ # @return [self]
31
+ def add_pattern(pattern)
32
+ @patterns << pattern
33
+ self
34
+ end
35
+
36
+ # Add a predicate to the rule
37
+ #
38
+ # @param predicate [Proc] Predicate block to add
39
+ # @return [self]
40
+ def add_predicate(&predicate)
41
+ @predicates << predicate if predicate
42
+ self
43
+ end
44
+
45
+ # Check if any patterns are defined
46
+ #
47
+ # @return [Boolean]
48
+ def patterns?
49
+ !@patterns.empty?
50
+ end
51
+
52
+ # Check if any predicates are defined
53
+ #
54
+ # @return [Boolean]
55
+ def predicates?
56
+ !@predicates.empty?
57
+ end
58
+
59
+ # Check if the rule has any conditions
60
+ #
61
+ # @return [Boolean]
62
+ def conditions?
63
+ patterns? || predicates?
64
+ end
65
+
66
+ # Get option value
67
+ #
68
+ # @param key [Symbol] Option key
69
+ # @return [Object] Option value
70
+ def [](key)
71
+ @options[key]
72
+ end
73
+
74
+ # Set option value
75
+ #
76
+ # @param key [Symbol] Option key
77
+ # @param value [Object] Option value
78
+ def []=(key, value)
79
+ @options[key] = value
80
+ end
81
+
82
+ # Check if paths should be preserved
83
+ #
84
+ # @return [Boolean]
85
+ def preserve_paths?
86
+ @options[:preserve_paths]
87
+ end
88
+
89
+ # Check if paths should be flattened
90
+ #
91
+ # @return [Boolean]
92
+ def flatten?
93
+ @options[:flatten]
94
+ end
95
+
96
+ # Check if existing files should be overwritten
97
+ #
98
+ # @return [Boolean]
99
+ def overwrite?
100
+ @options[:overwrite]
101
+ end
102
+
103
+ private
104
+
105
+ def default_options
106
+ {
107
+ preserve_paths: true,
108
+ flatten: false,
109
+ overwrite: false,
110
+ dest_prefix: nil,
111
+ }
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (C) 2025 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_relative "filter_config"
20
+
21
+ module Omnizip
22
+ module Models
23
+ # Ordered sequence of filters for compression/decompression
24
+ #
25
+ # Manages a pipeline of filters that are applied in sequence.
26
+ # Filters are applied in reverse order during decode.
27
+ #
28
+ # @example Create filter chain for XZ executable
29
+ # chain = FilterChain.new(format: :xz)
30
+ # chain.add_filter(name: :"bcj-x86", architecture: :x86)
31
+ # chain.add_filter(name: :lzma2) # Main compression
32
+ # encoded = chain.encode_all(data, position)
33
+ class FilterChain
34
+ # @return [Array<FilterConfig>] Ordered filter configurations
35
+ attr_reader :filters
36
+
37
+ # @return [Symbol] Format identifier (:xz, :seven_zip)
38
+ attr_reader :format
39
+
40
+ # Maximum filters in XZ format
41
+ MAX_FILTERS_XZ = 4
42
+
43
+ # Maximum filters in 7z format
44
+ MAX_FILTERS_SEVEN_ZIP = 4
45
+
46
+ # Initialize filter chain
47
+ #
48
+ # @param attributes [Hash] Initialization attributes
49
+ # @option attributes [Symbol] :format Target format
50
+ def initialize(attributes = {})
51
+ @format = attributes[:format] || :xz
52
+ @filters = attributes[:filters] || []
53
+ end
54
+
55
+ # Add a filter to the chain
56
+ #
57
+ # @param filter_attributes [Hash] Filter configuration
58
+ # @option filter_attributes [Symbol] :name Filter name
59
+ # @option filter_attributes [String] :properties Filter properties
60
+ # @option filter_attributes [Symbol] :architecture Target architecture
61
+ # @return [self] For chaining
62
+ def add_filter(filter_attributes = {})
63
+ filter = FilterConfig.new(filter_attributes)
64
+ filter.validate!
65
+ @filters << filter
66
+ self
67
+ end
68
+
69
+ # Get maximum filters for current format
70
+ #
71
+ # @return [Integer] Maximum number of filters allowed
72
+ def max_filters
73
+ case @format
74
+ when :xz then MAX_FILTERS_XZ
75
+ when :seven_zip then MAX_FILTERS_SEVEN_ZIP
76
+ else raise ArgumentError, "Unknown format: #{@format}"
77
+ end
78
+ end
79
+
80
+ # Validate filter chain
81
+ #
82
+ # @return [Boolean] True if valid
83
+ # @raise [ArgumentError] If validation fails
84
+ def validate!
85
+ if @filters.size > max_filters
86
+ raise ArgumentError,
87
+ "Too many filters for #{@format}: #{@filters.size} > #{max_filters}"
88
+ end
89
+
90
+ @filters.each(&:validate!)
91
+ true
92
+ end
93
+
94
+ # Encode data through all filters in order
95
+ #
96
+ # @param data [String] Input data
97
+ # @param position [Integer] Stream position
98
+ # @return [String] Encoded data
99
+ def encode_all(data, position = 0)
100
+ result = data
101
+ @filters.each do |filter_config|
102
+ filter = filter_config.filter_instance
103
+ result = filter.encode(result, position)
104
+ end
105
+ result
106
+ end
107
+
108
+ # Decode data through all filters in reverse order
109
+ #
110
+ # @param data [String] Input data
111
+ # @param position [Integer] Stream position
112
+ # @return [String] Decoded data
113
+ def decode_all(data, position = 0)
114
+ result = data
115
+ @filters.reverse_each do |filter_config|
116
+ filter = filter_config.filter_instance
117
+ result = filter.decode(result, position)
118
+ end
119
+ result
120
+ end
121
+
122
+ # Get filter IDs for current format
123
+ #
124
+ # @return [Array<Integer>] Array of filter IDs in order
125
+ def filter_ids
126
+ @filters.map { |f| f.id_for_format(@format) }
127
+ end
128
+
129
+ # Check if chain is empty
130
+ #
131
+ # @return [Boolean] True if no filters
132
+ def empty?
133
+ @filters.empty?
134
+ end
135
+
136
+ # Get number of filters in chain
137
+ #
138
+ # @return [Integer] Filter count
139
+ def size
140
+ @filters.size
141
+ end
142
+ end
143
+ end
144
+ end