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,183 @@
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_registry"
20
+
21
+ module Omnizip
22
+ module Models
23
+ # Configuration model for a filter in a compression pipeline.
24
+ #
25
+ # This class replaces hash-based filter configuration with a proper
26
+ # model class. It provides format-aware ID resolution and validation.
27
+ #
28
+ # @example Create a BCJ filter configuration
29
+ # config = FilterConfig.new(name: :bcj_x86, architecture: :x86)
30
+ # config.id_for_format(:xz) # => 0x04
31
+ # config.id_for_format(:seven_zip) # => 0x03030103
32
+ #
33
+ # @example Create a Delta filter configuration
34
+ # config = FilterConfig.new(name: :delta)
35
+ # config.delta? # => true
36
+ class FilterConfig
37
+ # @return [Symbol] Filter name (:bcj_x86, :delta, etc.)
38
+ attr_reader :name_sym
39
+
40
+ # @return [String] Binary properties data for filter configuration
41
+ attr_accessor :properties
42
+
43
+ # @return [Symbol] Target architecture for BCJ filters
44
+ attr_accessor :architecture
45
+
46
+ # Initialize filter configuration.
47
+ #
48
+ # @param attributes [Hash] Initialization attributes
49
+ # @option attributes [Symbol] :name Filter name
50
+ # @option attributes [Symbol] :name_sym Filter name (alternative key)
51
+ # @option attributes [String] :properties Binary properties data
52
+ # @option attributes [Symbol] :architecture Target architecture
53
+ def initialize(attributes = {})
54
+ @name_sym = attributes[:name] || attributes[:name_sym]
55
+ @properties = attributes[:properties] || "".b
56
+ @architecture = attributes[:architecture]
57
+ end
58
+
59
+ # Set filter name.
60
+ #
61
+ # @param value [Symbol] Filter name
62
+ # @return [void]
63
+ def name=(value)
64
+ @name_sym = value
65
+ end
66
+
67
+ # Get filter name as symbol.
68
+ #
69
+ # @return [Symbol] Filter name
70
+ def name_sym
71
+ @name_sym
72
+ end
73
+
74
+ # Get filter instance from registry.
75
+ #
76
+ # Returns a new instance of the filter. Handles both old-style
77
+ # registration (direct class) and new-style registration (hash with :class).
78
+ #
79
+ # @return [Object] Filter instance from FilterRegistry
80
+ # @raise [KeyError] If filter not found in registry
81
+ def filter_instance
82
+ filter = Omnizip::FilterRegistry.get(@name_sym)
83
+
84
+ # Handle both hash-style and direct class registration
85
+ if filter.is_a?(Hash)
86
+ # New-style registration - check if architecture is needed
87
+ klass = filter[:class]
88
+ if architecture_required?(klass)
89
+ klass.new(architecture: @architecture) if @architecture
90
+ else
91
+ klass.new
92
+ end
93
+ elsif filter.is_a?(Class)
94
+ # Old-style registration - try with architecture if available
95
+ if @architecture && requires_initialize_kwargs?(filter)
96
+ filter.new(architecture: @architecture)
97
+ else
98
+ filter.new
99
+ end
100
+ else
101
+ # Already an instance
102
+ filter
103
+ end
104
+ end
105
+
106
+ # Get filter ID for specific format.
107
+ #
108
+ # Delegates to filter instance's id_for_format method if available.
109
+ # For older filters without id_for_format, returns a default value.
110
+ #
111
+ # @param format [Symbol] Format identifier (:seven_zip, :xz)
112
+ # @return [Integer] Format-specific filter ID
113
+ # @raise [NotImplementedError] If filter doesn't support id_for_format
114
+ def id_for_format(format)
115
+ filter = filter_instance
116
+ if filter.respond_to?(:id_for_format)
117
+ filter.id_for_format(format)
118
+ else
119
+ raise NotImplementedError,
120
+ "Filter #{@name_sym} doesn't support format-aware IDs. " \
121
+ "Use the newer BCJ filter instead."
122
+ end
123
+ end
124
+
125
+ # Check if this is a BCJ filter.
126
+ #
127
+ # @return [Boolean] True if BCJ filter variant
128
+ def bcj?
129
+ @name_sym.to_s.start_with?("bcj_")
130
+ end
131
+
132
+ # Check if this is a Delta filter.
133
+ #
134
+ # @return [Boolean] True if Delta filter
135
+ def delta?
136
+ @name_sym == :delta
137
+ end
138
+
139
+ # Validate configuration.
140
+ #
141
+ # @return [Boolean] True if valid
142
+ # @raise [ArgumentError] If filter name is nil or not registered
143
+ def validate!
144
+ raise ArgumentError, "Filter name is required" if @name_sym.nil?
145
+
146
+ unless Omnizip::FilterRegistry.registered?(@name_sym)
147
+ raise ArgumentError, "Filter not registered: #{@name_sym}"
148
+ end
149
+
150
+ true
151
+ end
152
+
153
+ # Convert to hash for backward compatibility.
154
+ #
155
+ # @return [Hash] Hash representation with :name, :properties, :architecture
156
+ def to_h
157
+ {
158
+ name: @name_sym,
159
+ properties: @properties,
160
+ architecture: @architecture,
161
+ }
162
+ end
163
+
164
+ private
165
+
166
+ # Check if filter class requires architecture argument.
167
+ #
168
+ # @param klass [Class] Filter class to check
169
+ # @return [Boolean] True if architecture is required
170
+ def architecture_required?(klass)
171
+ klass.name.include?("BCJ") && !klass.name.include?("BcjX86")
172
+ end
173
+
174
+ # Check if filter class requires keyword arguments for initialize.
175
+ #
176
+ # @param klass [Class] Filter class to check
177
+ # @return [Boolean] True if kwargs are required
178
+ def requires_initialize_kwargs?(klass)
179
+ klass.name.include?("BCJ") && !klass.name.include?("BcjX86")
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Models
5
+ # Represents the result of pattern matching against archive entries
6
+ #
7
+ # Contains matched entries with metadata about the matching process.
8
+ class MatchResult
9
+ include Enumerable
10
+
11
+ attr_reader :matches, :total_scanned, :pattern
12
+
13
+ # Initialize a new match result
14
+ #
15
+ # @param pattern [Object] The pattern that was matched
16
+ # @param matches [Array] Array of matched entries
17
+ # @param total_scanned [Integer] Total entries scanned
18
+ def initialize(pattern, matches: [], total_scanned: 0)
19
+ @pattern = pattern
20
+ @matches = Array(matches)
21
+ @total_scanned = total_scanned
22
+ end
23
+
24
+ # Add a matched entry
25
+ #
26
+ # @param entry [Object] Entry that matched
27
+ # @return [self]
28
+ def add_match(entry)
29
+ @matches << entry
30
+ self
31
+ end
32
+
33
+ # Increment the scan counter
34
+ #
35
+ # @param count [Integer] Number to increment by
36
+ # @return [self]
37
+ def increment_scanned(count = 1)
38
+ @total_scanned += count
39
+ self
40
+ end
41
+
42
+ # Get the number of matches
43
+ #
44
+ # @return [Integer]
45
+ def count
46
+ @matches.size
47
+ end
48
+
49
+ # Check if any matches were found
50
+ #
51
+ # @return [Boolean]
52
+ def any?
53
+ !@matches.empty?
54
+ end
55
+
56
+ # Check if no matches were found
57
+ #
58
+ # @return [Boolean]
59
+ def none?
60
+ @matches.empty?
61
+ end
62
+
63
+ # Get match rate (matches/scanned)
64
+ #
65
+ # @return [Float] Match rate between 0.0 and 1.0
66
+ def match_rate
67
+ return 0.0 if @total_scanned.zero?
68
+
69
+ count.to_f / @total_scanned
70
+ end
71
+
72
+ # Get match percentage
73
+ #
74
+ # @return [Float] Match percentage between 0.0 and 100.0
75
+ def match_percentage
76
+ match_rate * 100.0
77
+ end
78
+
79
+ # Iterate over matches
80
+ #
81
+ # @yield [entry] Each matched entry
82
+ # @return [Enumerator, self]
83
+ def each(&block)
84
+ return matches.to_enum unless block
85
+
86
+ matches.each(&block)
87
+ self
88
+ end
89
+
90
+ # Get first match
91
+ #
92
+ # @return [Object, nil]
93
+ def first
94
+ @matches.first
95
+ end
96
+
97
+ # Get last match
98
+ #
99
+ # @return [Object, nil]
100
+ def last
101
+ @matches.last
102
+ end
103
+
104
+ # Convert to array
105
+ #
106
+ # @return [Array]
107
+ def to_a
108
+ @matches.dup
109
+ end
110
+
111
+ # Get summary hash
112
+ #
113
+ # @return [Hash]
114
+ def to_h
115
+ {
116
+ pattern: @pattern.to_s,
117
+ matches: count,
118
+ scanned: @total_scanned,
119
+ match_rate: match_rate,
120
+ }
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Models
5
+ # Represents a performance optimization suggestion based on profiling data
6
+ class OptimizationSuggestion
7
+ SEVERITY_LEVELS = %i[low medium high critical].freeze
8
+ CATEGORIES = %i[
9
+ memory cpu hotpath algorithm io gc allocation concurrency
10
+ ].freeze
11
+
12
+ attr_reader :title, :description, :severity, :category, :impact_estimate,
13
+ :implementation_effort, :related_operations, :code_locations,
14
+ :metrics
15
+
16
+ def initialize(
17
+ title:,
18
+ description:,
19
+ severity:,
20
+ category:,
21
+ impact_estimate: nil,
22
+ implementation_effort: nil,
23
+ related_operations: [],
24
+ code_locations: [],
25
+ metrics: {}
26
+ )
27
+ validate_severity!(severity)
28
+ validate_category!(category)
29
+
30
+ @title = title
31
+ @description = description
32
+ @severity = severity
33
+ @category = category
34
+ @impact_estimate = impact_estimate
35
+ @implementation_effort = implementation_effort
36
+ @related_operations = related_operations
37
+ @code_locations = code_locations
38
+ @metrics = metrics
39
+ end
40
+
41
+ def critical?
42
+ severity == :critical
43
+ end
44
+
45
+ def high_priority?
46
+ severity == :high || critical?
47
+ end
48
+
49
+ def priority_score
50
+ severity_weight = SEVERITY_LEVELS.index(severity) + 1
51
+ impact_weight = impact_estimate || 1.0
52
+ effort_weight = implementation_effort ? (1.0 / implementation_effort) : 1.0
53
+
54
+ severity_weight * impact_weight * effort_weight
55
+ end
56
+
57
+ def to_h
58
+ {
59
+ title: title,
60
+ description: description,
61
+ severity: severity,
62
+ category: category,
63
+ impact_estimate: impact_estimate,
64
+ implementation_effort: implementation_effort,
65
+ priority_score: priority_score,
66
+ related_operations: related_operations,
67
+ code_locations: code_locations,
68
+ metrics: metrics,
69
+ }
70
+ end
71
+
72
+ private
73
+
74
+ def validate_severity!(severity)
75
+ return if SEVERITY_LEVELS.include?(severity)
76
+
77
+ raise ArgumentError,
78
+ "Invalid severity: #{severity}. " \
79
+ "Must be one of: #{SEVERITY_LEVELS.join(', ')}"
80
+ end
81
+
82
+ def validate_category!(category)
83
+ return if CATEGORIES.include?(category)
84
+
85
+ raise ArgumentError,
86
+ "Invalid category: #{category}. " \
87
+ "Must be one of: #{CATEGORIES.join(', ')}"
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Models
5
+ # Model for parallel processing configuration
6
+ #
7
+ # Stores settings for parallel compression and extraction operations
8
+ # including thread count, queue size, and load balancing strategy.
9
+ #
10
+ # @example Create parallel options
11
+ # options = Omnizip::Models::ParallelOptions.new
12
+ # options.threads = 8
13
+ # options.queue_size = 100
14
+ # options.strategy = :dynamic
15
+ #
16
+ # @example Use with parallel compression
17
+ # Omnizip::Parallel.compress_directory('files/', 'backup.zip', options)
18
+ class ParallelOptions
19
+ # @return [Integer] Number of worker threads (default: auto-detect)
20
+ attr_accessor :threads
21
+
22
+ # @return [Integer] Maximum size of job queue (default: 1000)
23
+ attr_accessor :queue_size
24
+
25
+ # @return [Integer] Chunk size for chunked operations in bytes
26
+ attr_accessor :chunk_size
27
+
28
+ # @return [Symbol] Load balancing strategy (:dynamic or :static)
29
+ attr_accessor :strategy
30
+
31
+ # @return [Boolean] Enable verbose progress output
32
+ attr_accessor :verbose
33
+
34
+ # @return [Integer] Batch size for work queue polling
35
+ attr_accessor :batch_size
36
+
37
+ # Initialize parallel options with default values
38
+ def initialize
39
+ @threads = detect_cpu_count
40
+ @queue_size = 1000
41
+ @chunk_size = 64 * 1024 * 1024 # 64MB default
42
+ @strategy = :dynamic
43
+ @verbose = false
44
+ @batch_size = 10
45
+ end
46
+
47
+ # Validate options
48
+ #
49
+ # @raise [ArgumentError] if options are invalid
50
+ # @return [Boolean] true if valid
51
+ def validate!
52
+ raise ArgumentError, "threads must be > 0" if threads <= 0
53
+ raise ArgumentError, "queue_size must be > 0" if queue_size <= 0
54
+ raise ArgumentError, "chunk_size must be > 0" if chunk_size <= 0
55
+ raise ArgumentError, "strategy must be :dynamic or :static" unless %i[
56
+ dynamic static
57
+ ].include?(strategy)
58
+ raise ArgumentError, "batch_size must be > 0" if batch_size <= 0
59
+
60
+ true
61
+ end
62
+
63
+ # Create a copy of options
64
+ #
65
+ # @return [ParallelOptions] new instance with same values
66
+ def dup
67
+ copy = self.class.new
68
+ copy.threads = threads
69
+ copy.queue_size = queue_size
70
+ copy.chunk_size = chunk_size
71
+ copy.strategy = strategy
72
+ copy.verbose = verbose
73
+ copy.batch_size = batch_size
74
+ copy
75
+ end
76
+
77
+ # Convert to hash
78
+ #
79
+ # @return [Hash] options as hash
80
+ def to_h
81
+ {
82
+ threads: threads,
83
+ queue_size: queue_size,
84
+ chunk_size: chunk_size,
85
+ strategy: strategy,
86
+ verbose: verbose,
87
+ batch_size: batch_size,
88
+ }
89
+ end
90
+
91
+ private
92
+
93
+ # Detect number of available CPU cores
94
+ #
95
+ # @return [Integer] number of CPUs
96
+ def detect_cpu_count
97
+ require "etc"
98
+ Etc.nprocessors
99
+ rescue StandardError
100
+ 4 # fallback to 4 threads
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Models
5
+ # Represents the performance characteristics of a profiled operation
6
+ class PerformanceResult
7
+ attr_reader :operation_name, :total_time, :cpu_time, :wall_time,
8
+ :memory_allocated, :memory_retained, :object_allocations,
9
+ :gc_runs, :call_count, :timestamp
10
+
11
+ def initialize(
12
+ operation_name:,
13
+ total_time: nil,
14
+ cpu_time: nil,
15
+ wall_time: nil,
16
+ memory_allocated: nil,
17
+ memory_retained: nil,
18
+ object_allocations: nil,
19
+ gc_runs: nil,
20
+ call_count: nil,
21
+ timestamp: Time.now
22
+ )
23
+ @operation_name = operation_name
24
+ @total_time = total_time
25
+ @cpu_time = cpu_time
26
+ @wall_time = wall_time
27
+ @memory_allocated = memory_allocated
28
+ @memory_retained = memory_retained
29
+ @object_allocations = object_allocations
30
+ @gc_runs = gc_runs
31
+ @call_count = call_count
32
+ @timestamp = timestamp
33
+ end
34
+
35
+ def throughput_ops_per_second
36
+ return nil unless call_count && total_time&.positive?
37
+
38
+ call_count.to_f / total_time
39
+ end
40
+
41
+ def average_time_per_operation
42
+ return nil unless call_count && total_time && call_count.positive?
43
+
44
+ total_time / call_count.to_f
45
+ end
46
+
47
+ def memory_per_operation
48
+ return nil unless call_count && memory_allocated && call_count.positive?
49
+
50
+ memory_allocated / call_count.to_f
51
+ end
52
+
53
+ def gc_pressure
54
+ return nil unless gc_runs && total_time&.positive?
55
+
56
+ gc_runs.to_f / total_time
57
+ end
58
+
59
+ def to_h
60
+ {
61
+ operation_name: operation_name,
62
+ total_time: total_time,
63
+ cpu_time: cpu_time,
64
+ wall_time: wall_time,
65
+ memory_allocated: memory_allocated,
66
+ memory_retained: memory_retained,
67
+ object_allocations: object_allocations,
68
+ gc_runs: gc_runs,
69
+ call_count: call_count,
70
+ throughput_ops_per_second: throughput_ops_per_second,
71
+ average_time_per_operation: average_time_per_operation,
72
+ memory_per_operation: memory_per_operation,
73
+ gc_pressure: gc_pressure,
74
+ timestamp: timestamp.iso8601,
75
+ }
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Models
5
+ # Represents an aggregated profiling report with hot path analysis
6
+ class ProfileReport
7
+ attr_reader :profile_name, :results, :hot_paths, :bottlenecks,
8
+ :timestamp, :metadata
9
+
10
+ def initialize(
11
+ profile_name:,
12
+ results: [],
13
+ hot_paths: [],
14
+ bottlenecks: [],
15
+ timestamp: Time.now,
16
+ metadata: {}
17
+ )
18
+ @profile_name = profile_name
19
+ @results = results
20
+ @hot_paths = hot_paths
21
+ @bottlenecks = bottlenecks
22
+ @timestamp = timestamp
23
+ @metadata = metadata
24
+ end
25
+
26
+ def total_execution_time
27
+ results.filter_map(&:total_time).sum
28
+ end
29
+
30
+ def total_memory_allocated
31
+ results.filter_map(&:memory_allocated).sum
32
+ end
33
+
34
+ def total_gc_runs
35
+ results.filter_map(&:gc_runs).sum
36
+ end
37
+
38
+ def slowest_operations(limit: 5)
39
+ results.select(&:total_time)
40
+ .sort_by(&:total_time)
41
+ .reverse
42
+ .take(limit)
43
+ end
44
+
45
+ def memory_intensive_operations(limit: 5)
46
+ results.select(&:memory_allocated)
47
+ .sort_by(&:memory_allocated)
48
+ .reverse
49
+ .take(limit)
50
+ end
51
+
52
+ def add_result(result)
53
+ @results << result
54
+ end
55
+
56
+ def add_hot_path(hot_path)
57
+ @hot_paths << hot_path
58
+ end
59
+
60
+ def add_bottleneck(bottleneck)
61
+ @bottlenecks << bottleneck
62
+ end
63
+
64
+ def to_h
65
+ {
66
+ profile_name: profile_name,
67
+ timestamp: timestamp.iso8601,
68
+ summary: {
69
+ total_execution_time: total_execution_time,
70
+ total_memory_allocated: total_memory_allocated,
71
+ total_gc_runs: total_gc_runs,
72
+ operation_count: results.size,
73
+ },
74
+ results: results.map(&:to_h),
75
+ hot_paths: hot_paths,
76
+ bottlenecks: bottlenecks,
77
+ metadata: metadata,
78
+ }
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (C) 2025 Ribose Inc.
5
+ #
6
+
7
+ module Omnizip
8
+ module Models
9
+ # Model representing progress tracking options.
10
+ #
11
+ # This class encapsulates configuration for progress tracking,
12
+ # including reporter type, update interval, and display preferences.
13
+ class ProgressOptions
14
+ attr_accessor :reporter, :update_interval, :show_rate,
15
+ :show_eta, :show_files, :show_bytes
16
+
17
+ def initialize
18
+ @reporter = "auto"
19
+ @update_interval = 0.5
20
+ @show_rate = true
21
+ @show_eta = true
22
+ @show_files = true
23
+ @show_bytes = true
24
+ end
25
+
26
+ def to_h
27
+ {
28
+ reporter: @reporter,
29
+ update_interval: @update_interval,
30
+ show_rate: @show_rate,
31
+ show_eta: @show_eta,
32
+ show_files: @show_files,
33
+ show_bytes: @show_bytes,
34
+ }.compact
35
+ end
36
+ end
37
+ end
38
+ end