omnizip 0.4.7-x86_64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (632) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +32 -0
  4. data/.rubocop_todo.yml +293 -0
  5. data/CHANGELOG.md +1647 -0
  6. data/CONTEXT.md +68 -0
  7. data/COPYING +502 -0
  8. data/Gemfile +19 -0
  9. data/LICENSE +12 -0
  10. data/README.adoc +1327 -0
  11. data/Rakefile +15 -0
  12. data/TODO.refactor/00-overview.md +67 -0
  13. data/TODO.refactor/01-registry-base-class.md +81 -0
  14. data/TODO.refactor/02-error-hierarchy.md +57 -0
  15. data/TODO.refactor/03-autoload-entry-point.md +69 -0
  16. data/TODO.refactor/04-filter-base-consolidation.md +49 -0
  17. data/TODO.refactor/05-send-private-methods.md +64 -0
  18. data/TODO.refactor/06-instance-variable-access.md +69 -0
  19. data/TODO.refactor/07-respond-to-replacement.md +237 -0
  20. data/TODO.refactor/08-spec-doubles.md +27 -0
  21. data/TODO.refactor/09-cli-shared-module.md +35 -0
  22. data/TODO.refactor/10-format-detector-ocp.md +34 -0
  23. data/TODO.refactor/11-convenience-decoupling.md +38 -0
  24. data/TODO.refactor/12-thread-safety.md +8 -0
  25. data/TODO.refactor/13-lutaml-model-migration.md +158 -0
  26. data/TODO.refactor/14-add-missing-specs.md +25 -0
  27. data/benchmark/README.md +260 -0
  28. data/benchmark/benchmark_suite.rb +125 -0
  29. data/benchmark/compression_bench.rb +181 -0
  30. data/benchmark/filter_bench.rb +180 -0
  31. data/benchmark/models/benchmark_result.rb +59 -0
  32. data/benchmark/models/comparison_result.rb +69 -0
  33. data/benchmark/profile_suite.rb +167 -0
  34. data/benchmark/reporter.rb +150 -0
  35. data/benchmark/run_benchmarks.rb +66 -0
  36. data/benchmark/test_data.rb +137 -0
  37. data/config/formats/rar3_spec.yml +92 -0
  38. data/config/formats/rar5_spec.yml +102 -0
  39. data/docs/.github/workflows/docs.yml +142 -0
  40. data/docs/.gitignore +21 -0
  41. data/docs/.lychee.toml +67 -0
  42. data/docs/Gemfile +13 -0
  43. data/docs/RAR_WRITE_SUPPORT.md +26 -0
  44. data/docs/README.md +101 -0
  45. data/docs/_config.yml +112 -0
  46. data/docs/assets/logo.svg +1 -0
  47. data/docs/assets/omnizip-logo.pdf +1540 -11
  48. data/docs/comparison/feature-matrix.adoc +694 -0
  49. data/docs/comparison/index.adoc +113 -0
  50. data/docs/comparison/vs-7zip.adoc +309 -0
  51. data/docs/comparison/vs-peazip.adoc +77 -0
  52. data/docs/comparison/vs-rubyzip.adoc +342 -0
  53. data/docs/comparison/vs-winrar.adoc +100 -0
  54. data/docs/compatibility.adoc +579 -0
  55. data/docs/concepts/index.adoc +129 -0
  56. data/docs/developer/architecture.adoc +256 -0
  57. data/docs/developer/contributing.adoc +158 -0
  58. data/docs/developer/index.adoc +25 -0
  59. data/docs/developer/testing.adoc +212 -0
  60. data/docs/getting-started/basic-usage.adoc +263 -0
  61. data/docs/getting-started/index.adoc +42 -0
  62. data/docs/getting-started/installation.adoc +138 -0
  63. data/docs/getting-started/quick-start.adoc +183 -0
  64. data/docs/getting-started/your-first-archive.adoc +219 -0
  65. data/docs/guides/advanced-features/encryption.adoc +277 -0
  66. data/docs/guides/advanced-features/index.adoc +59 -0
  67. data/docs/guides/advanced-features/parallel-processing.adoc +144 -0
  68. data/docs/guides/advanced-features/progress-tracking.adoc +124 -0
  69. data/docs/guides/advanced-features/streaming.adoc +142 -0
  70. data/docs/guides/archive-formats/gzip-format.adoc +105 -0
  71. data/docs/guides/archive-formats/index.adoc +160 -0
  72. data/docs/guides/archive-formats/ole-format.adoc +151 -0
  73. data/docs/guides/archive-formats/rar-format.adoc +104 -0
  74. data/docs/guides/archive-formats/rar5.adoc +521 -0
  75. data/docs/guides/archive-formats/rpm-format.adoc +108 -0
  76. data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
  77. data/docs/guides/archive-formats/tar-format.adoc +106 -0
  78. data/docs/guides/archive-formats/xz-format.adoc +118 -0
  79. data/docs/guides/archive-formats/zip-format.adoc +35 -0
  80. data/docs/guides/compression-algorithms/bzip2.adoc +114 -0
  81. data/docs/guides/compression-algorithms/deflate.adoc +313 -0
  82. data/docs/guides/compression-algorithms/index.adoc +190 -0
  83. data/docs/guides/compression-algorithms/lzma.adoc +394 -0
  84. data/docs/guides/compression-algorithms/lzma2.adoc +244 -0
  85. data/docs/guides/compression-algorithms/ppmd.adoc +313 -0
  86. data/docs/guides/compression-algorithms/zstandard.adoc +296 -0
  87. data/docs/guides/creating-archives.adoc +348 -0
  88. data/docs/guides/extracting-archives.adoc +53 -0
  89. data/docs/guides/format-conversion.adoc +64 -0
  90. data/docs/guides/index.adoc +49 -0
  91. data/docs/guides/migration-rubyzip.adoc +217 -0
  92. data/docs/guides/parity-archives.adoc +605 -0
  93. data/docs/guides/performance-tuning.adoc +88 -0
  94. data/docs/index.adoc +228 -0
  95. data/docs/lychee.toml +67 -0
  96. data/docs/reference/api/overview.adoc +187 -0
  97. data/docs/reference/cli/compress-command.adoc +114 -0
  98. data/docs/reference/cli/overview.adoc +140 -0
  99. data/docs/reference/index.adoc +26 -0
  100. data/docs/resources/faq.adoc +185 -0
  101. data/docs/resources/quick-reference.adoc +222 -0
  102. data/docs/rust-backend.md +0 -0
  103. data/docs/troubleshooting/index.adoc +207 -0
  104. data/docs/xar_format.md +216 -0
  105. data/examples/api_comparison.rb +205 -0
  106. data/examples/deflate64_example.rb +96 -0
  107. data/examples/par2_demo.rb +121 -0
  108. data/examples/quick_start_native.rb +150 -0
  109. data/examples/quick_start_rubyzip.rb +115 -0
  110. data/examples/rubyzip_compatibility_demo.rb +194 -0
  111. data/exe/omnizip +27 -0
  112. data/lib/omnizip/algorithm.rb +176 -0
  113. data/lib/omnizip/algorithm_registry.rb +65 -0
  114. data/lib/omnizip/algorithms/.keep +0 -0
  115. data/lib/omnizip/algorithms/bzip2/bwt.rb +236 -0
  116. data/lib/omnizip/algorithms/bzip2/bz2.rb +687 -0
  117. data/lib/omnizip/algorithms/bzip2/rle.rb +146 -0
  118. data/lib/omnizip/algorithms/bzip2.rb +108 -0
  119. data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
  120. data/lib/omnizip/algorithms/deflate/decoder.rb +37 -0
  121. data/lib/omnizip/algorithms/deflate/encoder.rb +45 -0
  122. data/lib/omnizip/algorithms/deflate.rb +135 -0
  123. data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
  124. data/lib/omnizip/algorithms/deflate64/decoder.rb +151 -0
  125. data/lib/omnizip/algorithms/deflate64/encoder.rb +95 -0
  126. data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +352 -0
  127. data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +140 -0
  128. data/lib/omnizip/algorithms/deflate64.rb +118 -0
  129. data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
  130. data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
  131. data/lib/omnizip/algorithms/lzma/decoder.rb +146 -0
  132. data/lib/omnizip/algorithms/lzma/dictionary.rb +70 -0
  133. data/lib/omnizip/algorithms/lzma/distance_coder.rb +326 -0
  134. data/lib/omnizip/algorithms/lzma/encoder.rb +139 -0
  135. data/lib/omnizip/algorithms/lzma/length_coder.rb +172 -0
  136. data/lib/omnizip/algorithms/lzma/literal_decoder.rb +204 -0
  137. data/lib/omnizip/algorithms/lzma/literal_encoder.rb +208 -0
  138. data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +368 -0
  139. data/lib/omnizip/algorithms/lzma/lzma1_encoder.rb +105 -0
  140. data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +194 -0
  141. data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
  142. data/lib/omnizip/algorithms/lzma/match.rb +32 -0
  143. data/lib/omnizip/algorithms/lzma/match_finder.rb +233 -0
  144. data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
  145. data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +84 -0
  146. data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +159 -0
  147. data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
  148. data/lib/omnizip/algorithms/lzma/range_coder.rb +82 -0
  149. data/lib/omnizip/algorithms/lzma/range_decoder.rb +274 -0
  150. data/lib/omnizip/algorithms/lzma/range_encoder.rb +202 -0
  151. data/lib/omnizip/algorithms/lzma/state.rb +127 -0
  152. data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +323 -0
  153. data/lib/omnizip/algorithms/lzma/xz_encoder.rb +420 -0
  154. data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +640 -0
  155. data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +224 -0
  156. data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +167 -0
  157. data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +258 -0
  158. data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
  159. data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +314 -0
  160. data/lib/omnizip/algorithms/lzma/xz_state.rb +108 -0
  161. data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +1311 -0
  162. data/lib/omnizip/algorithms/lzma.rb +266 -0
  163. data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +180 -0
  164. data/lib/omnizip/algorithms/lzma2/constants.rb +38 -0
  165. data/lib/omnizip/algorithms/lzma2/encoder.rb +145 -0
  166. data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +165 -0
  167. data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
  168. data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +122 -0
  169. data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
  170. data/lib/omnizip/algorithms/lzma2.rb +133 -0
  171. data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
  172. data/lib/omnizip/algorithms/ppmd7/context.rb +151 -0
  173. data/lib/omnizip/algorithms/ppmd7/decoder.rb +127 -0
  174. data/lib/omnizip/algorithms/ppmd7/encoder.rb +153 -0
  175. data/lib/omnizip/algorithms/ppmd7/model.rb +245 -0
  176. data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
  177. data/lib/omnizip/algorithms/ppmd7.rb +146 -0
  178. data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
  179. data/lib/omnizip/algorithms/ppmd8/context.rb +32 -0
  180. data/lib/omnizip/algorithms/ppmd8/decoder.rb +104 -0
  181. data/lib/omnizip/algorithms/ppmd8/encoder.rb +135 -0
  182. data/lib/omnizip/algorithms/ppmd8/model.rb +246 -0
  183. data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
  184. data/lib/omnizip/algorithms/ppmd8.rb +122 -0
  185. data/lib/omnizip/algorithms/ppmd_base.rb +142 -0
  186. data/lib/omnizip/algorithms/registration.rb +28 -0
  187. data/lib/omnizip/algorithms/zstandard/constants.rb +158 -0
  188. data/lib/omnizip/algorithms/zstandard/decoder.rb +249 -0
  189. data/lib/omnizip/algorithms/zstandard/dictionary.rb +73 -0
  190. data/lib/omnizip/algorithms/zstandard/encoder.rb +294 -0
  191. data/lib/omnizip/algorithms/zstandard/frame/block.rb +143 -0
  192. data/lib/omnizip/algorithms/zstandard/frame/header.rb +233 -0
  193. data/lib/omnizip/algorithms/zstandard/frame.rb +33 -0
  194. data/lib/omnizip/algorithms/zstandard/fse/bitstream.rb +183 -0
  195. data/lib/omnizip/algorithms/zstandard/fse/encoder.rb +534 -0
  196. data/lib/omnizip/algorithms/zstandard/fse/interleaved.rb +92 -0
  197. data/lib/omnizip/algorithms/zstandard/fse/table.rb +188 -0
  198. data/lib/omnizip/algorithms/zstandard/fse/table_description.rb +203 -0
  199. data/lib/omnizip/algorithms/zstandard/fse.rb +53 -0
  200. data/lib/omnizip/algorithms/zstandard/huffman.rb +276 -0
  201. data/lib/omnizip/algorithms/zstandard/huffman_encoder.rb +327 -0
  202. data/lib/omnizip/algorithms/zstandard/ldm.rb +121 -0
  203. data/lib/omnizip/algorithms/zstandard/literals.rb +241 -0
  204. data/lib/omnizip/algorithms/zstandard/literals_encoder.rb +96 -0
  205. data/lib/omnizip/algorithms/zstandard/match_finder.rb +483 -0
  206. data/lib/omnizip/algorithms/zstandard/sequences.rb +350 -0
  207. data/lib/omnizip/algorithms/zstandard/sequences_encoder.rb +333 -0
  208. data/lib/omnizip/algorithms/zstandard/xxhash.rb +159 -0
  209. data/lib/omnizip/algorithms/zstandard.rb +210 -0
  210. data/lib/omnizip/algorithms.rb +35 -0
  211. data/lib/omnizip/archive/builder.rb +48 -0
  212. data/lib/omnizip/archive/reader_session.rb +67 -0
  213. data/lib/omnizip/archive.rb +86 -0
  214. data/lib/omnizip/archive_handler.rb +82 -0
  215. data/lib/omnizip/archive_handlers/cpio_handler.rb +47 -0
  216. data/lib/omnizip/archive_handlers/iso_handler.rb +54 -0
  217. data/lib/omnizip/archive_handlers/ole_handler.rb +37 -0
  218. data/lib/omnizip/archive_handlers/rar_handler.rb +96 -0
  219. data/lib/omnizip/archive_handlers/rpm_handler.rb +45 -0
  220. data/lib/omnizip/archive_handlers/seven_zip_handler.rb +89 -0
  221. data/lib/omnizip/archive_handlers/tar_handler.rb +75 -0
  222. data/lib/omnizip/archive_handlers/xar_handler.rb +49 -0
  223. data/lib/omnizip/archive_handlers/zip_handler.rb +115 -0
  224. data/lib/omnizip/archive_handlers.rb +18 -0
  225. data/lib/omnizip/backends.rb +160 -0
  226. data/lib/omnizip/buffer/memory_archive.rb +246 -0
  227. data/lib/omnizip/buffer/memory_extractor.rb +234 -0
  228. data/lib/omnizip/buffer/seven_zip_bridge.rb +171 -0
  229. data/lib/omnizip/buffer.rb +187 -0
  230. data/lib/omnizip/checksum_registry.rb +41 -0
  231. data/lib/omnizip/checksums/crc32.rb +101 -0
  232. data/lib/omnizip/checksums/crc64.rb +102 -0
  233. data/lib/omnizip/checksums/crc_base.rb +158 -0
  234. data/lib/omnizip/checksums/registration.rb +16 -0
  235. data/lib/omnizip/checksums/verifier.rb +130 -0
  236. data/lib/omnizip/checksums.rb +11 -0
  237. data/lib/omnizip/chunked/memory_manager.rb +194 -0
  238. data/lib/omnizip/chunked/reader.rb +78 -0
  239. data/lib/omnizip/chunked/writer.rb +123 -0
  240. data/lib/omnizip/chunked.rb +123 -0
  241. data/lib/omnizip/cli/output_formatter.rb +112 -0
  242. data/lib/omnizip/cli.rb +604 -0
  243. data/lib/omnizip/commands/.keep +0 -0
  244. data/lib/omnizip/commands/archive_create_command.rb +245 -0
  245. data/lib/omnizip/commands/archive_extract_command.rb +231 -0
  246. data/lib/omnizip/commands/archive_list_command.rb +204 -0
  247. data/lib/omnizip/commands/archive_repair_command.rb +129 -0
  248. data/lib/omnizip/commands/archive_verify_command.rb +115 -0
  249. data/lib/omnizip/commands/compress_command.rb +115 -0
  250. data/lib/omnizip/commands/decompress_command.rb +149 -0
  251. data/lib/omnizip/commands/list_command.rb +51 -0
  252. data/lib/omnizip/commands/metadata_command.rb +215 -0
  253. data/lib/omnizip/commands/parity_create_command.rb +114 -0
  254. data/lib/omnizip/commands/parity_repair_command.rb +120 -0
  255. data/lib/omnizip/commands/parity_verify_command.rb +122 -0
  256. data/lib/omnizip/commands/profile_list_command.rb +54 -0
  257. data/lib/omnizip/commands/profile_show_command.rb +44 -0
  258. data/lib/omnizip/commands.rb +21 -0
  259. data/lib/omnizip/convenience.rb +389 -0
  260. data/lib/omnizip/converter/conversion_registry.rb +50 -0
  261. data/lib/omnizip/converter/conversion_strategy.rb +108 -0
  262. data/lib/omnizip/converter/extract_repack_strategy.rb +51 -0
  263. data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +43 -0
  264. data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +54 -0
  265. data/lib/omnizip/converter.rb +124 -0
  266. data/lib/omnizip/crypto/aes256/cipher.rb +104 -0
  267. data/lib/omnizip/crypto/aes256/constants.rb +28 -0
  268. data/lib/omnizip/crypto/aes256/key_derivation.rb +100 -0
  269. data/lib/omnizip/crypto/aes256.rb +102 -0
  270. data/lib/omnizip/crypto.rb +11 -0
  271. data/lib/omnizip/entry.rb +44 -0
  272. data/lib/omnizip/error.rb +110 -0
  273. data/lib/omnizip/eta/exponential_smoothing_estimator.rb +95 -0
  274. data/lib/omnizip/eta/moving_average_estimator.rb +96 -0
  275. data/lib/omnizip/eta/rate_calculator.rb +104 -0
  276. data/lib/omnizip/eta/sample_history.rb +143 -0
  277. data/lib/omnizip/eta/time_estimator.rb +106 -0
  278. data/lib/omnizip/eta.rb +68 -0
  279. data/lib/omnizip/extraction/filter_chain.rb +179 -0
  280. data/lib/omnizip/extraction/glob_pattern.rb +140 -0
  281. data/lib/omnizip/extraction/pattern_matcher.rb +66 -0
  282. data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
  283. data/lib/omnizip/extraction/regex_pattern.rb +50 -0
  284. data/lib/omnizip/extraction/selective_extractor.rb +247 -0
  285. data/lib/omnizip/extraction.rb +115 -0
  286. data/lib/omnizip/file_type/mime_classifier.rb +144 -0
  287. data/lib/omnizip/file_type.rb +117 -0
  288. data/lib/omnizip/filter.rb +141 -0
  289. data/lib/omnizip/filter_pipeline.rb +108 -0
  290. data/lib/omnizip/filter_registry.rb +113 -0
  291. data/lib/omnizip/filters/bcj.rb +277 -0
  292. data/lib/omnizip/filters/bcj2/constants.rb +53 -0
  293. data/lib/omnizip/filters/bcj2/decoder.rb +263 -0
  294. data/lib/omnizip/filters/bcj2/encoder.rb +58 -0
  295. data/lib/omnizip/filters/bcj2/stream_data.rb +91 -0
  296. data/lib/omnizip/filters/bcj2.rb +93 -0
  297. data/lib/omnizip/filters/bcj_arm.rb +174 -0
  298. data/lib/omnizip/filters/bcj_arm64.rb +242 -0
  299. data/lib/omnizip/filters/bcj_ia64.rb +194 -0
  300. data/lib/omnizip/filters/bcj_ppc.rb +188 -0
  301. data/lib/omnizip/filters/bcj_sparc.rb +174 -0
  302. data/lib/omnizip/filters/bcj_x86.rb +191 -0
  303. data/lib/omnizip/filters/delta.rb +195 -0
  304. data/lib/omnizip/filters/xz_delta.rb +258 -0
  305. data/lib/omnizip/filters.rb +20 -0
  306. data/lib/omnizip/format_detector.rb +166 -0
  307. data/lib/omnizip/formats/.keep +0 -0
  308. data/lib/omnizip/formats/bzip2_file.rb +159 -0
  309. data/lib/omnizip/formats/cpio/bounded_io.rb +66 -0
  310. data/lib/omnizip/formats/cpio/constants.rb +55 -0
  311. data/lib/omnizip/formats/cpio/entry.rb +389 -0
  312. data/lib/omnizip/formats/cpio/reader.rb +194 -0
  313. data/lib/omnizip/formats/cpio/writer.rb +232 -0
  314. data/lib/omnizip/formats/cpio.rb +132 -0
  315. data/lib/omnizip/formats/format_spec_loader.rb +228 -0
  316. data/lib/omnizip/formats/gzip.rb +236 -0
  317. data/lib/omnizip/formats/iso/directory_builder.rb +321 -0
  318. data/lib/omnizip/formats/iso/directory_record.rb +162 -0
  319. data/lib/omnizip/formats/iso/joliet.rb +204 -0
  320. data/lib/omnizip/formats/iso/path_table.rb +125 -0
  321. data/lib/omnizip/formats/iso/reader.rb +194 -0
  322. data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
  323. data/lib/omnizip/formats/iso/volume_builder.rb +319 -0
  324. data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
  325. data/lib/omnizip/formats/iso/writer.rb +543 -0
  326. data/lib/omnizip/formats/iso.rb +133 -0
  327. data/lib/omnizip/formats/lzip.rb +161 -0
  328. data/lib/omnizip/formats/lzma_alone.rb +149 -0
  329. data/lib/omnizip/formats/msi/cab_extractor.rb +181 -0
  330. data/lib/omnizip/formats/msi/constants.rb +157 -0
  331. data/lib/omnizip/formats/msi/directory_resolver.rb +188 -0
  332. data/lib/omnizip/formats/msi/entry.rb +134 -0
  333. data/lib/omnizip/formats/msi/reader.rb +301 -0
  334. data/lib/omnizip/formats/msi/string_pool.rb +246 -0
  335. data/lib/omnizip/formats/msi/table_parser.rb +244 -0
  336. data/lib/omnizip/formats/msi.rb +73 -0
  337. data/lib/omnizip/formats/ole/allocation_table.rb +263 -0
  338. data/lib/omnizip/formats/ole/constants.rb +61 -0
  339. data/lib/omnizip/formats/ole/dirent.rb +439 -0
  340. data/lib/omnizip/formats/ole/header.rb +199 -0
  341. data/lib/omnizip/formats/ole/ranges_io.rb +347 -0
  342. data/lib/omnizip/formats/ole/storage.rb +482 -0
  343. data/lib/omnizip/formats/ole/types/variant.rb +338 -0
  344. data/lib/omnizip/formats/ole.rb +143 -0
  345. data/lib/omnizip/formats/rar/archive_repairer.rb +240 -0
  346. data/lib/omnizip/formats/rar/archive_verifier.rb +192 -0
  347. data/lib/omnizip/formats/rar/block_parser.rb +282 -0
  348. data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
  349. data/lib/omnizip/formats/rar/compression/dispatcher.rb +210 -0
  350. data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +212 -0
  351. data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +154 -0
  352. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
  353. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
  354. data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
  355. data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
  356. data/lib/omnizip/formats/rar/compression/lz77_huffman.rb +25 -0
  357. data/lib/omnizip/formats/rar/compression/ppmd/context.rb +103 -0
  358. data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +238 -0
  359. data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +250 -0
  360. data/lib/omnizip/formats/rar/compression/ppmd.rb +16 -0
  361. data/lib/omnizip/formats/rar/compression.rb +17 -0
  362. data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
  363. data/lib/omnizip/formats/rar/constants.rb +88 -0
  364. data/lib/omnizip/formats/rar/decompressor.rb +316 -0
  365. data/lib/omnizip/formats/rar/external_writer.rb +311 -0
  366. data/lib/omnizip/formats/rar/header.rb +209 -0
  367. data/lib/omnizip/formats/rar/license_validator.rb +111 -0
  368. data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
  369. data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
  370. data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
  371. data/lib/omnizip/formats/rar/models.rb +14 -0
  372. data/lib/omnizip/formats/rar/parity_handler.rb +299 -0
  373. data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +200 -0
  374. data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +584 -0
  375. data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
  376. data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
  377. data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +96 -0
  378. data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
  379. data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +162 -0
  380. data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
  381. data/lib/omnizip/formats/rar/rar5/header.rb +208 -0
  382. data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
  383. data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
  384. data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
  385. data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
  386. data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
  387. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +260 -0
  388. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
  389. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +176 -0
  390. data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +108 -0
  391. data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +139 -0
  392. data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
  393. data/lib/omnizip/formats/rar/rar5/vint.rb +53 -0
  394. data/lib/omnizip/formats/rar/rar5/writer.rb +540 -0
  395. data/lib/omnizip/formats/rar/rar_format_base.rb +239 -0
  396. data/lib/omnizip/formats/rar/reader.rb +377 -0
  397. data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
  398. data/lib/omnizip/formats/rar/volume_manager.rb +166 -0
  399. data/lib/omnizip/formats/rar/writer.rb +437 -0
  400. data/lib/omnizip/formats/rar.rb +193 -0
  401. data/lib/omnizip/formats/rar3/compressor.rb +71 -0
  402. data/lib/omnizip/formats/rar3/decompressor.rb +64 -0
  403. data/lib/omnizip/formats/rar3/reader.rb +107 -0
  404. data/lib/omnizip/formats/rar3/writer.rb +220 -0
  405. data/lib/omnizip/formats/rar3.rb +15 -0
  406. data/lib/omnizip/formats/rar5/compressor.rb +71 -0
  407. data/lib/omnizip/formats/rar5/decompressor.rb +64 -0
  408. data/lib/omnizip/formats/rar5/reader.rb +130 -0
  409. data/lib/omnizip/formats/rar5/writer.rb +65 -0
  410. data/lib/omnizip/formats/rar5.rb +15 -0
  411. data/lib/omnizip/formats/rpm/constants.rb +58 -0
  412. data/lib/omnizip/formats/rpm/entry.rb +106 -0
  413. data/lib/omnizip/formats/rpm/header.rb +106 -0
  414. data/lib/omnizip/formats/rpm/lead.rb +132 -0
  415. data/lib/omnizip/formats/rpm/tag.rb +228 -0
  416. data/lib/omnizip/formats/rpm/writer.rb +652 -0
  417. data/lib/omnizip/formats/rpm.rb +458 -0
  418. data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +274 -0
  419. data/lib/omnizip/formats/seven_zip/coder_chain.rb +169 -0
  420. data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
  421. data/lib/omnizip/formats/seven_zip/encoded_header.rb +110 -0
  422. data/lib/omnizip/formats/seven_zip/encrypted_header.rb +139 -0
  423. data/lib/omnizip/formats/seven_zip/file_collector.rb +143 -0
  424. data/lib/omnizip/formats/seven_zip/header.rb +102 -0
  425. data/lib/omnizip/formats/seven_zip/header_encryptor.rb +132 -0
  426. data/lib/omnizip/formats/seven_zip/header_writer.rb +425 -0
  427. data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
  428. data/lib/omnizip/formats/seven_zip/models/file_entry.rb +65 -0
  429. data/lib/omnizip/formats/seven_zip/models/folder.rb +67 -0
  430. data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
  431. data/lib/omnizip/formats/seven_zip/models.rb +20 -0
  432. data/lib/omnizip/formats/seven_zip/parser.rb +671 -0
  433. data/lib/omnizip/formats/seven_zip/reader.rb +626 -0
  434. data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +611 -0
  435. data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +308 -0
  436. data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
  437. data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +166 -0
  438. data/lib/omnizip/formats/seven_zip/writer.rb +801 -0
  439. data/lib/omnizip/formats/seven_zip.rb +179 -0
  440. data/lib/omnizip/formats/tar/constants.rb +73 -0
  441. data/lib/omnizip/formats/tar/entry.rb +98 -0
  442. data/lib/omnizip/formats/tar/header.rb +206 -0
  443. data/lib/omnizip/formats/tar/reader.rb +119 -0
  444. data/lib/omnizip/formats/tar/writer.rb +212 -0
  445. data/lib/omnizip/formats/tar.rb +74 -0
  446. data/lib/omnizip/formats/xar/constants.rb +119 -0
  447. data/lib/omnizip/formats/xar/entry.rb +268 -0
  448. data/lib/omnizip/formats/xar/header.rb +223 -0
  449. data/lib/omnizip/formats/xar/reader.rb +400 -0
  450. data/lib/omnizip/formats/xar/toc.rb +570 -0
  451. data/lib/omnizip/formats/xar/writer.rb +461 -0
  452. data/lib/omnizip/formats/xar.rb +145 -0
  453. data/lib/omnizip/formats/xz/reader.rb +121 -0
  454. data/lib/omnizip/formats/xz/writer.rb +416 -0
  455. data/lib/omnizip/formats/xz.rb +210 -0
  456. data/lib/omnizip/formats/xz_const.rb +49 -0
  457. data/lib/omnizip/formats/xz_impl/block_decoder.rb +761 -0
  458. data/lib/omnizip/formats/xz_impl/block_encoder.rb +304 -0
  459. data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
  460. data/lib/omnizip/formats/xz_impl/block_header_parser.rb +182 -0
  461. data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
  462. data/lib/omnizip/formats/xz_impl/index_encoder.rb +120 -0
  463. data/lib/omnizip/formats/xz_impl/stream_decoder.rb +470 -0
  464. data/lib/omnizip/formats/xz_impl/stream_encoder.rb +95 -0
  465. data/lib/omnizip/formats/xz_impl/stream_footer.rb +79 -0
  466. data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +115 -0
  467. data/lib/omnizip/formats/xz_impl/stream_header.rb +53 -0
  468. data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +106 -0
  469. data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
  470. data/lib/omnizip/formats/xz_impl.rb +52 -0
  471. data/lib/omnizip/formats/zip/central_directory_header.rb +223 -0
  472. data/lib/omnizip/formats/zip/constants.rb +69 -0
  473. data/lib/omnizip/formats/zip/end_of_central_directory.rb +132 -0
  474. data/lib/omnizip/formats/zip/local_file_header.rb +136 -0
  475. data/lib/omnizip/formats/zip/reader.rb +376 -0
  476. data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
  477. data/lib/omnizip/formats/zip/writer.rb +489 -0
  478. data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +102 -0
  479. data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +64 -0
  480. data/lib/omnizip/formats/zip/zip64_extra_field.rb +112 -0
  481. data/lib/omnizip/formats/zip.rb +50 -0
  482. data/lib/omnizip/formats.rb +29 -0
  483. data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
  484. data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
  485. data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
  486. data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
  487. data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
  488. data/lib/omnizip/implementations/base.rb +19 -0
  489. data/lib/omnizip/implementations/rust/archive.rb +93 -0
  490. data/lib/omnizip/implementations/rust/library.rb +221 -0
  491. data/lib/omnizip/implementations/rust.rb +26 -0
  492. data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +428 -0
  493. data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +456 -0
  494. data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +285 -0
  495. data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +197 -0
  496. data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +194 -0
  497. data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +139 -0
  498. data/lib/omnizip/implementations/seven_zip/lzma.rb +21 -0
  499. data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +56 -0
  500. data/lib/omnizip/implementations/seven_zip/lzma2.rb +12 -0
  501. data/lib/omnizip/implementations/seven_zip.rb +11 -0
  502. data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +547 -0
  503. data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +748 -0
  504. data/lib/omnizip/implementations/xz_utils/lzma2.rb +13 -0
  505. data/lib/omnizip/implementations/xz_utils.rb +10 -0
  506. data/lib/omnizip/implementations.rb +25 -0
  507. data/lib/omnizip/io/buffered_input.rb +147 -0
  508. data/lib/omnizip/io/buffered_output.rb +106 -0
  509. data/lib/omnizip/io/source.rb +143 -0
  510. data/lib/omnizip/io/stream_manager.rb +117 -0
  511. data/lib/omnizip/io.rb +15 -0
  512. data/lib/omnizip/link_handler/hard_link.rb +79 -0
  513. data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
  514. data/lib/omnizip/link_handler.rb +129 -0
  515. data/lib/omnizip/metadata/archive_metadata.rb +114 -0
  516. data/lib/omnizip/metadata/entry_metadata.rb +153 -0
  517. data/lib/omnizip/metadata/metadata_editor.rb +169 -0
  518. data/lib/omnizip/metadata/metadata_registry.rb +71 -0
  519. data/lib/omnizip/metadata/metadata_validator.rb +101 -0
  520. data/lib/omnizip/metadata.rb +58 -0
  521. data/lib/omnizip/models/.keep +0 -0
  522. data/lib/omnizip/models/algorithm_metadata.rb +41 -0
  523. data/lib/omnizip/models/attribute_apply.rb +40 -0
  524. data/lib/omnizip/models/compression_options.rb +53 -0
  525. data/lib/omnizip/models/conversion_options.rb +79 -0
  526. data/lib/omnizip/models/conversion_result.rb +141 -0
  527. data/lib/omnizip/models/eta_result.rb +45 -0
  528. data/lib/omnizip/models/extraction_rule.rb +115 -0
  529. data/lib/omnizip/models/filter_chain.rb +142 -0
  530. data/lib/omnizip/models/filter_config.rb +148 -0
  531. data/lib/omnizip/models/match_result.rb +141 -0
  532. data/lib/omnizip/models/optimization_suggestion.rb +95 -0
  533. data/lib/omnizip/models/parallel_options.rb +116 -0
  534. data/lib/omnizip/models/performance_result.rb +85 -0
  535. data/lib/omnizip/models/profile_report.rb +116 -0
  536. data/lib/omnizip/models/progress_options.rb +39 -0
  537. data/lib/omnizip/models/split_options.rb +116 -0
  538. data/lib/omnizip/optimization_registry.rb +45 -0
  539. data/lib/omnizip/parallel/engine.rb +52 -0
  540. data/lib/omnizip/parallel/job_queue.rb +209 -0
  541. data/lib/omnizip/parallel/job_scheduler.rb +225 -0
  542. data/lib/omnizip/parallel/parallel_compressor.rb +326 -0
  543. data/lib/omnizip/parallel/parallel_extractor.rb +238 -0
  544. data/lib/omnizip/parallel/thread_pool.rb +60 -0
  545. data/lib/omnizip/parallel/worker_pool.rb +227 -0
  546. data/lib/omnizip/parallel.rb +156 -0
  547. data/lib/omnizip/parity/chunked_block_processor.rb +194 -0
  548. data/lib/omnizip/parity/galois16.rb +145 -0
  549. data/lib/omnizip/parity/models/creator_packet.rb +71 -0
  550. data/lib/omnizip/parity/models/file_description_packet.rb +131 -0
  551. data/lib/omnizip/parity/models/ifsc_packet.rb +111 -0
  552. data/lib/omnizip/parity/models/main_packet.rb +126 -0
  553. data/lib/omnizip/parity/models/packet.rb +156 -0
  554. data/lib/omnizip/parity/models/packet_registry.rb +102 -0
  555. data/lib/omnizip/parity/models/recovery_slice_packet.rb +76 -0
  556. data/lib/omnizip/parity/models.rb +27 -0
  557. data/lib/omnizip/parity/par2_creator.rb +496 -0
  558. data/lib/omnizip/parity/par2_repairer.rb +409 -0
  559. data/lib/omnizip/parity/par2_verifier.rb +373 -0
  560. data/lib/omnizip/parity/par2cmdline_algorithm.rb +108 -0
  561. data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
  562. data/lib/omnizip/parity/reed_solomon_decoder.rb +263 -0
  563. data/lib/omnizip/parity/reed_solomon_encoder.rb +108 -0
  564. data/lib/omnizip/parity/reed_solomon_matrix.rb +339 -0
  565. data/lib/omnizip/parity.rb +207 -0
  566. data/lib/omnizip/password/encryption_registry.rb +26 -0
  567. data/lib/omnizip/password/encryption_strategy.rb +96 -0
  568. data/lib/omnizip/password/password_validator.rb +129 -0
  569. data/lib/omnizip/password/winzip_aes_strategy.rb +190 -0
  570. data/lib/omnizip/password/zip_crypto_strategy.rb +135 -0
  571. data/lib/omnizip/password.rb +88 -0
  572. data/lib/omnizip/pipe/stream_compressor.rb +124 -0
  573. data/lib/omnizip/pipe/stream_decompressor.rb +173 -0
  574. data/lib/omnizip/pipe.rb +120 -0
  575. data/lib/omnizip/platform/ntfs_streams.rb +200 -0
  576. data/lib/omnizip/platform.rb +189 -0
  577. data/lib/omnizip/profile/archive_profile.rb +36 -0
  578. data/lib/omnizip/profile/balanced_profile.rb +31 -0
  579. data/lib/omnizip/profile/binary_profile.rb +33 -0
  580. data/lib/omnizip/profile/compression_profile.rb +157 -0
  581. data/lib/omnizip/profile/custom_profile.rb +155 -0
  582. data/lib/omnizip/profile/fast_profile.rb +31 -0
  583. data/lib/omnizip/profile/maximum_profile.rb +31 -0
  584. data/lib/omnizip/profile/profile_detector.rb +108 -0
  585. data/lib/omnizip/profile/profile_registry.rb +160 -0
  586. data/lib/omnizip/profile/text_profile.rb +33 -0
  587. data/lib/omnizip/profile.rb +261 -0
  588. data/lib/omnizip/profiler/memory_profiler.rb +66 -0
  589. data/lib/omnizip/profiler/method_profiler.rb +49 -0
  590. data/lib/omnizip/profiler/report_generator.rb +158 -0
  591. data/lib/omnizip/profiler.rb +192 -0
  592. data/lib/omnizip/progress/callback_reporter.rb +34 -0
  593. data/lib/omnizip/progress/console_reporter.rb +59 -0
  594. data/lib/omnizip/progress/log_reporter.rb +89 -0
  595. data/lib/omnizip/progress/operation_progress.rb +118 -0
  596. data/lib/omnizip/progress/progress_bar.rb +156 -0
  597. data/lib/omnizip/progress/progress_reporter.rb +40 -0
  598. data/lib/omnizip/progress/progress_tracker.rb +215 -0
  599. data/lib/omnizip/progress/silent_reporter.rb +22 -0
  600. data/lib/omnizip/progress.rb +131 -0
  601. data/lib/omnizip/registry.rb +111 -0
  602. data/lib/omnizip/rubyzip_compat.rb +61 -0
  603. data/lib/omnizip/temp/safe_extract.rb +124 -0
  604. data/lib/omnizip/temp/temp_file.rb +123 -0
  605. data/lib/omnizip/temp/temp_file_pool.rb +109 -0
  606. data/lib/omnizip/temp.rb +184 -0
  607. data/lib/omnizip/version.rb +5 -0
  608. data/lib/omnizip/zip/entry.rb +160 -0
  609. data/lib/omnizip/zip/file.rb +485 -0
  610. data/lib/omnizip/zip/input_stream.rb +270 -0
  611. data/lib/omnizip/zip/output_stream.rb +320 -0
  612. data/lib/omnizip/zip.rb +23 -0
  613. data/lib/omnizip.rb +157 -0
  614. data/lib/tasks/msi_test_files.rake +66 -0
  615. data/lib/tasks/platform_gems.rake +147 -0
  616. data/lib/tasks/rust_backend.rake +48 -0
  617. data/readme-docs/advanced-features.adoc +514 -0
  618. data/readme-docs/api-usage.adoc +445 -0
  619. data/readme-docs/architecture.adoc +450 -0
  620. data/readme-docs/archive-formats.adoc +479 -0
  621. data/readme-docs/cli-usage.adoc +222 -0
  622. data/readme-docs/compression-algorithms.adoc +446 -0
  623. data/readme-docs/compression-profiles.adoc +247 -0
  624. data/readme-docs/encryption-checksums.adoc +328 -0
  625. data/readme-docs/format-converter.adoc +316 -0
  626. data/readme-docs/installation.adoc +228 -0
  627. data/readme-docs/par2-archives.adoc +608 -0
  628. data/readme-docs/performance-profiler.adoc +389 -0
  629. data/readme-docs/preprocessing-filters.adoc +280 -0
  630. data/vendor/libomnizip_ffi.so +0 -0
  631. data/xz-file-format-1.2.1.txt +1174 -0
  632. metadata +768 -0
@@ -0,0 +1,85 @@
1
+ # frozen_string: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Omnizip
6
+ module Models
7
+ # Represents the performance characteristics of a profiled operation.
8
+ #
9
+ # Serialized via lutaml-model — no hand-rolled +to_h+ / +to_json+.
10
+ # The derived-rate keys serialize the calculation methods; attribute
11
+ # names differ from the keys so generated readers do not shadow them.
12
+ class PerformanceResult < Lutaml::Model::Serializable
13
+ attribute :operation_name, :string
14
+ attribute :total_time, :double
15
+ attribute :cpu_time, :double
16
+ attribute :wall_time, :double
17
+ attribute :memory_allocated, :integer
18
+ attribute :memory_retained, :integer
19
+ attribute :object_allocations, :integer
20
+ attribute :gc_runs, :integer
21
+ attribute :call_count, :integer
22
+ attribute :timestamp, :date_time, default: -> { Time.now }
23
+
24
+ attribute :throughput, :double, method: :throughput_ops_per_second
25
+ attribute :average_time, :double, method: :average_time_per_operation
26
+ attribute :memory_per_op, :double, method: :memory_per_operation
27
+ attribute :pressure, :double, method: :gc_pressure
28
+
29
+ key_value do
30
+ map "operation_name", to: :operation_name,
31
+ render_default: true, render_nil: true
32
+ map "total_time", to: :total_time,
33
+ render_default: true, render_nil: true
34
+ map "cpu_time", to: :cpu_time,
35
+ render_default: true, render_nil: true
36
+ map "wall_time", to: :wall_time,
37
+ render_default: true, render_nil: true
38
+ map "memory_allocated", to: :memory_allocated,
39
+ render_default: true, render_nil: true
40
+ map "memory_retained", to: :memory_retained,
41
+ render_default: true, render_nil: true
42
+ map "object_allocations", to: :object_allocations,
43
+ render_default: true, render_nil: true
44
+ map "gc_runs", to: :gc_runs,
45
+ render_default: true, render_nil: true
46
+ map "call_count", to: :call_count,
47
+ render_default: true, render_nil: true
48
+ map "throughput_ops_per_second", to: :throughput,
49
+ render_default: true, render_nil: true
50
+ map "average_time_per_operation", to: :average_time,
51
+ render_default: true, render_nil: true
52
+ map "memory_per_operation", to: :memory_per_op,
53
+ render_default: true, render_nil: true
54
+ map "gc_pressure", to: :pressure,
55
+ render_default: true, render_nil: true
56
+ map "timestamp", to: :timestamp,
57
+ render_default: true, render_nil: true
58
+ end
59
+
60
+ def throughput_ops_per_second
61
+ return nil unless call_count && total_time&.positive?
62
+
63
+ call_count.to_f / total_time
64
+ end
65
+
66
+ def average_time_per_operation
67
+ return nil unless call_count && total_time && call_count.positive?
68
+
69
+ total_time / call_count.to_f
70
+ end
71
+
72
+ def memory_per_operation
73
+ return nil unless call_count && memory_allocated && call_count.positive?
74
+
75
+ memory_allocated / call_count.to_f
76
+ end
77
+
78
+ def gc_pressure
79
+ return nil unless gc_runs && total_time&.positive?
80
+
81
+ gc_runs.to_f / total_time
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Omnizip
6
+ module Models
7
+ # Aggregated profiling report with hot path analysis.
8
+ #
9
+ # Serialized via lutaml-model — no hand-rolled +to_h+ / +to_json+.
10
+ # The +summary+ key serializes a nested Summary model built from
11
+ # the report's aggregates; hot paths and bottlenecks are the
12
+ # analyzer-supplied hashes.
13
+ class ProfileReport < Lutaml::Model::Serializable
14
+ # Aggregate block of {ProfileReport#to_hash}.
15
+ class Summary < Lutaml::Model::Serializable
16
+ attribute :total_execution_time, :double, default: 0.0
17
+ attribute :total_memory_allocated, :integer, default: 0
18
+ attribute :total_gc_runs, :integer, default: 0
19
+ attribute :operation_count, :integer, default: 0
20
+
21
+ key_value do
22
+ map "total_execution_time", to: :total_execution_time,
23
+ render_default: true, render_nil: true
24
+ map "total_memory_allocated", to: :total_memory_allocated,
25
+ render_default: true, render_nil: true
26
+ map "total_gc_runs", to: :total_gc_runs,
27
+ render_default: true, render_nil: true
28
+ map "operation_count", to: :operation_count,
29
+ render_default: true, render_nil: true
30
+ end
31
+ end
32
+
33
+ attribute :profile_name, :string
34
+ attribute :results, PerformanceResult, collection: true, default: []
35
+ attribute :hot_paths, :hash, collection: true, default: []
36
+ attribute :bottlenecks, :hash, collection: true, default: []
37
+ attribute :timestamp, :date_time, default: -> { Time.now }
38
+ attribute :metadata, :hash, default: {}
39
+ attribute :summary, Summary, method: :build_summary
40
+
41
+ key_value do
42
+ map "profile_name", to: :profile_name,
43
+ render_default: true, render_nil: true
44
+ map "timestamp", to: :timestamp,
45
+ render_default: true, render_nil: true
46
+ map "summary", to: :summary,
47
+ render_default: true, render_nil: true
48
+ map "results", to: :results,
49
+ render_default: true, render_nil: true
50
+ map "hot_paths", to: :hot_paths,
51
+ render_default: true, render_nil: true
52
+ map "bottlenecks", to: :bottlenecks,
53
+ render_default: true, render_nil: true
54
+ map "metadata", to: :metadata,
55
+ render_default: true, render_nil: true
56
+ end
57
+
58
+ # lutaml-model 0.8.x does not render empty-collection defaults,
59
+ # so they are assigned explicitly to keep every key present.
60
+ def initialize(attrs = {})
61
+ super({ results: [], hot_paths: [], bottlenecks: [],
62
+ metadata: {} }.merge(attrs))
63
+ end
64
+
65
+ def total_execution_time
66
+ results.filter_map(&:total_time).sum
67
+ end
68
+
69
+ def total_memory_allocated
70
+ results.filter_map(&:memory_allocated).sum
71
+ end
72
+
73
+ def total_gc_runs
74
+ results.filter_map(&:gc_runs).sum
75
+ end
76
+
77
+ def slowest_operations(limit: 5)
78
+ results.select(&:total_time)
79
+ .sort_by(&:total_time)
80
+ .reverse
81
+ .take(limit)
82
+ end
83
+
84
+ def memory_intensive_operations(limit: 5)
85
+ results.select(&:memory_allocated)
86
+ .sort_by(&:memory_allocated)
87
+ .reverse
88
+ .take(limit)
89
+ end
90
+
91
+ def add_result(result)
92
+ results << result
93
+ end
94
+
95
+ def add_hot_path(hot_path)
96
+ hot_paths << hot_path
97
+ end
98
+
99
+ def add_bottleneck(bottleneck)
100
+ bottlenecks << bottleneck
101
+ end
102
+
103
+ # Serialized aggregate block.
104
+ #
105
+ # @return [Summary]
106
+ def build_summary
107
+ Summary.new(
108
+ total_execution_time: total_execution_time,
109
+ total_memory_allocated: total_memory_allocated,
110
+ total_gc_runs: total_gc_runs,
111
+ operation_count: results.size,
112
+ )
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (C) 2025 Ribose Inc.
5
+ #
6
+
7
+ require "lutaml/model"
8
+
9
+ module Omnizip
10
+ module Models
11
+ # Model representing progress tracking options.
12
+ #
13
+ # This class encapsulates configuration for progress tracking,
14
+ # including reporter type, update interval, and display preferences.
15
+ #
16
+ # Serialized via lutaml-model — no hand-rolled +to_h+ / +to_json+.
17
+ #
18
+ # +render_nil+ is deliberately absent: the previous +to_h+ ended in
19
+ # +.compact+, so an explicitly-nil value was dropped. +render_default+
20
+ # alone keeps that nil-dropping behaviour.
21
+ class ProgressOptions < Lutaml::Model::Serializable
22
+ attribute :reporter, :string, default: "auto"
23
+ attribute :update_interval, :float, default: 0.5
24
+ attribute :show_rate, :boolean, default: true
25
+ attribute :show_eta, :boolean, default: true
26
+ attribute :show_files, :boolean, default: true
27
+ attribute :show_bytes, :boolean, default: true
28
+
29
+ key_value do
30
+ map "reporter", to: :reporter, render_default: true
31
+ map "update_interval", to: :update_interval, render_default: true
32
+ map "show_rate", to: :show_rate, render_default: true
33
+ map "show_eta", to: :show_eta, render_default: true
34
+ map "show_files", to: :show_files, render_default: true
35
+ map "show_bytes", to: :show_bytes, render_default: true
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Models
5
+ # Configuration for split archive (multi-volume) creation
6
+ # Defines how archives should be split into volumes
7
+ class SplitOptions
8
+ attr_accessor :volume_size, :naming_pattern, :span_strategy
9
+
10
+ # Naming pattern types
11
+ NAMING_NUMERIC = :numeric # .001, .002, .003
12
+ NAMING_ALPHA = :alpha # .aa, .ab, .ac
13
+
14
+ # Span strategies
15
+ STRATEGY_FIRST_FIT = :first_fit # Fill volumes sequentially
16
+ STRATEGY_BALANCED = :balanced # Balance files across volumes
17
+
18
+ # Default volume size (100 MB)
19
+ DEFAULT_VOLUME_SIZE = 100 * 1024 * 1024
20
+
21
+ # Initialize with default options
22
+ def initialize
23
+ @volume_size = DEFAULT_VOLUME_SIZE
24
+ @naming_pattern = NAMING_NUMERIC
25
+ @span_strategy = STRATEGY_FIRST_FIT
26
+ end
27
+
28
+ # Parse volume size from string (e.g., "100M", "4.7G")
29
+ #
30
+ # @param size_str [String] Size string with unit
31
+ # @return [Integer] Size in bytes
32
+ def self.parse_volume_size(size_str)
33
+ return size_str if size_str.is_a?(Integer)
34
+
35
+ size_str = size_str.to_s.strip.upcase
36
+ multiplier = case size_str
37
+ when /(\d+(?:\.\d+)?)\s*K(?:B)?$/
38
+ 1024
39
+ when /(\d+(?:\.\d+)?)\s*M(?:B)?$/
40
+ 1024 * 1024
41
+ when /(\d+(?:\.\d+)?)\s*G(?:B)?$/
42
+ 1024 * 1024 * 1024
43
+ when /(\d+(?:\.\d+)?)\s*T(?:B)?$/
44
+ 1024 * 1024 * 1024 * 1024
45
+ else
46
+ return size_str.to_i
47
+ end
48
+
49
+ (Regexp.last_match(1).to_f * multiplier).to_i
50
+ end
51
+
52
+ # Generate volume filename
53
+ #
54
+ # @param base_path [String] Base archive path (e.g., "backup.7z.001")
55
+ # @param volume_number [Integer] Volume number (1-based)
56
+ # @return [String] Volume filename
57
+ def volume_filename(base_path, volume_number)
58
+ # Extract base and extension
59
+ base = base_path.sub(/\.\d{3}$/, "")
60
+ base = base.sub(/\.[a-z]{2,}$/, "") if @naming_pattern == NAMING_ALPHA
61
+
62
+ case @naming_pattern
63
+ when NAMING_NUMERIC
64
+ format("%s.%03d", base, volume_number)
65
+ when NAMING_ALPHA
66
+ format("%s.%s", base, alpha_suffix(volume_number))
67
+ else
68
+ format("%s.%03d", base, volume_number)
69
+ end
70
+ end
71
+
72
+ # Validate options
73
+ #
74
+ # @raise [ArgumentError] if options are invalid
75
+ def validate!
76
+ raise ArgumentError, "volume_size must be positive" unless
77
+ @volume_size.positive?
78
+
79
+ valid_patterns = [NAMING_NUMERIC, NAMING_ALPHA]
80
+ unless valid_patterns.include?(@naming_pattern)
81
+ raise ArgumentError,
82
+ "naming_pattern must be one of #{valid_patterns.inspect}"
83
+ end
84
+
85
+ valid_strategies = [STRATEGY_FIRST_FIT, STRATEGY_BALANCED]
86
+ unless valid_strategies.include?(@span_strategy)
87
+ raise ArgumentError,
88
+ "span_strategy must be one of #{valid_strategies.inspect}"
89
+ end
90
+
91
+ true
92
+ end
93
+
94
+ private
95
+
96
+ # Generate alpha suffix for volume number
97
+ #
98
+ # @param volume_number [Integer] Volume number (1-based)
99
+ # @return [String] Alpha suffix (aa, ab, ..., az, ba, ..., zz, aaa, ...)
100
+ def alpha_suffix(volume_number)
101
+ # Convert 1 -> aa, 2 -> ab, ..., 26 -> az, 27 -> ba, etc.
102
+ num = volume_number - 1 # Convert to 0-based
103
+
104
+ # For two-character format (minimum):
105
+ # Second character cycles through a-z (rightmost, least significant)
106
+ second = ("a".ord + (num % 26)).chr
107
+
108
+ # First character represents which group of 26 we're in
109
+ first_index = num / 26
110
+ first = ("a".ord + first_index).chr
111
+
112
+ first + second
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ class OptimizationRegistry < Omnizip::Registry
5
+ class << self
6
+ def not_found_error_class
7
+ Omnizip::OptimizationNotFoundError
8
+ end
9
+
10
+ def label
11
+ "Optimization strategy"
12
+ end
13
+
14
+ def apply(name, target, **options)
15
+ get(name).new(**options).optimize(target)
16
+ end
17
+
18
+ def metadata(name)
19
+ get(name).metadata
20
+ end
21
+ end
22
+
23
+ class Strategy
24
+ attr_reader :options
25
+
26
+ def initialize(**options)
27
+ @options = options
28
+ end
29
+
30
+ def optimize(_target)
31
+ raise NotImplementedError,
32
+ "#{self.class} must implement #optimize"
33
+ end
34
+
35
+ def self.metadata
36
+ {
37
+ name: name,
38
+ description: "No description provided",
39
+ category: :general,
40
+ impact: :unknown,
41
+ }
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fractor"
4
+
5
+ module Omnizip
6
+ module Parallel
7
+ # Engine owns the Fractor worker-pool dance: build the pool, submit
8
+ # a batch of work, run it to completion, return successful and
9
+ # failed results. Callers (ParallelCompressor, ParallelExtractor,
10
+ # future operations) supply the worker class and the work items;
11
+ # Engine handles the threading.
12
+ #
13
+ # This is the deep module behind the parallel API: the threading
14
+ # shape is identical across every consumer, so it lives here once.
15
+ # Domain-specific concerns (which file to read, which archive to
16
+ # open, what stats to track) stay with the caller.
17
+ class Engine
18
+ # @param worker_class [Class] a +Fractor::Worker+ subclass whose
19
+ # +#process(work)+ turns one work item into a result.
20
+ # @param threads [Integer] worker count.
21
+ def initialize(worker_class:, threads:)
22
+ @worker_class = worker_class
23
+ @threads = threads
24
+ end
25
+
26
+ # Run +work_items+ through the pool and yield each successful
27
+ # +Fractor::WorkResult+ to the caller-supplied block.
28
+ #
29
+ # @param work_items [Array<Fractor::Work>] batch to submit.
30
+ # @yieldparam result [Fractor::WorkResult] a successful result.
31
+ # @return [Array<Fractor::WorkResult>] the failed results, for
32
+ # the caller to decide how to surface.
33
+ def run(work_items)
34
+ pool = WorkerPool.new(
35
+ worker_class: @worker_class,
36
+ num_workers: @threads,
37
+ continuous: false,
38
+ )
39
+ pool.start
40
+ begin
41
+ pool.submit_batch(work_items)
42
+ pool.run
43
+
44
+ pool.successful_results.each { |r| yield r if block_given? }
45
+ pool.failed_results
46
+ ensure
47
+ pool.shutdown
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,209 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Parallel
5
+ # Thread-safe job queue for parallel compression/extraction
6
+ #
7
+ # Manages a queue of compression or extraction jobs with priority support.
8
+ # Jobs are ordered by priority (large files first for better load balancing).
9
+ #
10
+ # @example Create and use job queue
11
+ # queue = Omnizip::Parallel::JobQueue.new(max_size: 100)
12
+ # queue.push(file: 'large.dat', size: 1_000_000, priority: :high)
13
+ # job = queue.pop
14
+ #
15
+ # @example Size-based priority
16
+ # queue.push_with_size(file: 'file.txt', size: 1024)
17
+ class JobQueue
18
+ # Job structure for queue items
19
+ Job = Struct.new(:file, :data, :size, :priority, :metadata,
20
+ keyword_init: true) do
21
+ def <=>(other)
22
+ # Higher priority first, then larger files first
23
+ priority_order = { high: 0, normal: 1, low: 2 }
24
+ priority_cmp = (priority_order[priority] || 1) <=> (priority_order[other.priority] || 1)
25
+ return priority_cmp unless priority_cmp.zero?
26
+
27
+ # If same priority, larger files first
28
+ -(size <=> other.size)
29
+ end
30
+ end
31
+
32
+ # @return [Integer] maximum queue size
33
+ attr_reader :max_size
34
+
35
+ # @return [Integer] current queue size
36
+ attr_reader :size
37
+
38
+ # Initialize job queue
39
+ #
40
+ # @param max_size [Integer] maximum number of jobs in queue
41
+ def initialize(max_size: 1000)
42
+ @max_size = max_size
43
+ @queue = []
44
+ @mutex = Mutex.new
45
+ @cond = ConditionVariable.new
46
+ @closed = false
47
+ @size = 0
48
+ end
49
+
50
+ # Push a job onto the queue
51
+ #
52
+ # @param file [String] file path
53
+ # @param data [Object] job data
54
+ # @param size [Integer] file size in bytes
55
+ # @param priority [Symbol] job priority (:high, :normal, :low)
56
+ # @param metadata [Hash] additional metadata
57
+ # @raise [ClosedQueueError] if queue is closed
58
+ # @return [Job] the created job
59
+ def push(file:, data: nil, size: 0, priority: :normal, metadata: {})
60
+ @mutex.synchronize do
61
+ raise ClosedQueueError, "Queue is closed" if @closed
62
+
63
+ # Wait if queue is full
64
+ @cond.wait(@mutex) while @size >= @max_size && !@closed
65
+
66
+ raise ClosedQueueError, "Queue is closed" if @closed
67
+
68
+ job = Job.new(
69
+ file: file,
70
+ data: data,
71
+ size: size,
72
+ priority: priority,
73
+ metadata: metadata,
74
+ )
75
+
76
+ @queue << job
77
+ @size += 1
78
+
79
+ # Keep queue sorted by priority
80
+ @queue.sort!
81
+
82
+ @cond.signal
83
+ job
84
+ end
85
+ end
86
+
87
+ # Push a job with automatic priority based on file size
88
+ #
89
+ # @param file [String] file path
90
+ # @param size [Integer] file size in bytes
91
+ # @param data [Object] job data
92
+ # @param metadata [Hash] additional metadata
93
+ # @return [Job] the created job
94
+ def push_with_size(file:, size:, data: nil, metadata: {})
95
+ # Determine priority based on size
96
+ # Large files (>10MB) get high priority for better load balancing
97
+ priority = if size > 10 * 1024 * 1024
98
+ :high
99
+ elsif size > 1024 * 1024
100
+ :normal
101
+ else
102
+ :low
103
+ end
104
+
105
+ push(file: file, data: data, size: size, priority: priority,
106
+ metadata: metadata)
107
+ end
108
+
109
+ # Pop a job from the queue
110
+ #
111
+ # @param timeout [Numeric, nil] timeout in seconds, nil for no timeout
112
+ # @return [Job, nil] job or nil if timeout or closed
113
+ def pop(timeout: nil)
114
+ @mutex.synchronize do
115
+ if timeout
116
+ deadline = Time.now + timeout
117
+ while @queue.empty? && !@closed
118
+ remaining = deadline - Time.now
119
+ return nil if remaining <= 0
120
+
121
+ @cond.wait(@mutex, remaining)
122
+ end
123
+ else
124
+ @cond.wait(@mutex) while @queue.empty? && !@closed
125
+ end
126
+
127
+ return nil if @queue.empty?
128
+
129
+ job = @queue.shift
130
+ @size -= 1
131
+ @cond.signal # Signal waiting pushers
132
+ job
133
+ end
134
+ end
135
+
136
+ # Pop multiple jobs in batch
137
+ #
138
+ # @param count [Integer] maximum number of jobs to pop
139
+ # @param timeout [Numeric, nil] timeout in seconds
140
+ # @return [Array<Job>] array of jobs (may be empty)
141
+ def pop_batch(count, timeout: nil)
142
+ jobs = []
143
+ count.times do
144
+ job = pop(timeout: timeout)
145
+ break unless job
146
+
147
+ jobs << job
148
+ end
149
+ jobs
150
+ end
151
+
152
+ # Check if queue is empty
153
+ #
154
+ # @return [Boolean] true if empty
155
+ def empty?
156
+ @mutex.synchronize { @queue.empty? }
157
+ end
158
+
159
+ # Check if queue is closed
160
+ #
161
+ # @return [Boolean] true if closed
162
+ def closed?
163
+ @mutex.synchronize { @closed }
164
+ end
165
+
166
+ # Close the queue
167
+ #
168
+ # No more jobs can be pushed after closing.
169
+ # Pending pops will return nil.
170
+ def close
171
+ @mutex.synchronize do
172
+ @closed = true
173
+ @cond.broadcast # Wake up all waiting threads
174
+ end
175
+ end
176
+
177
+ # Clear all jobs from queue
178
+ #
179
+ # @return [Integer] number of jobs cleared
180
+ def clear
181
+ @mutex.synchronize do
182
+ count = @queue.size
183
+ @queue.clear
184
+ @size = 0
185
+ @cond.broadcast
186
+ count
187
+ end
188
+ end
189
+
190
+ # Get queue statistics
191
+ #
192
+ # @return [Hash] statistics hash
193
+ def stats
194
+ @mutex.synchronize do
195
+ {
196
+ size: @size,
197
+ max_size: @max_size,
198
+ closed: @closed,
199
+ utilization: @max_size.zero? ? 0.0 : @size.to_f / @max_size,
200
+ priority_counts: @queue.group_by(&:priority).transform_values(&:count),
201
+ }
202
+ end
203
+ end
204
+ end
205
+
206
+ # Exception raised when trying to push to a closed queue
207
+ class ClosedQueueError < StandardError; end
208
+ end
209
+ end