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
data/README.adoc ADDED
@@ -0,0 +1,1045 @@
1
+ = Omnizip
2
+
3
+ https://github.com/metanorma/omnizip[image:https://img.shields.io/github/stars/metanorma/omnizip.svg?style=social[GitHub Stars]]
4
+ https://github.com/metanorma/omnizip[image:https://img.shields.io/github/forks/metanorma/omnizip.svg?style=social[GitHub Forks]]
5
+ image:https://img.shields.io/github/license/metanorma/omnizip.svg[License]
6
+ image:https://img.shields.io/github/actions/workflow/status/metanorma/omnizip/test.yml?branch=main[Build Status]
7
+ image:https://img.shields.io/gem/v/omnizip.svg[RubyGems Version]
8
+
9
+ == Purpose
10
+
11
+ Omnizip is a comprehensive pure Ruby implementation of compression algorithms and archive formats. Built on an extensible, registry-based architecture with clean object-oriented design, Omnizip provides full-featured compression capabilities without external dependencies.
12
+
13
+ This implementation supports multiple compression algorithms (LZMA, LZMA2, BZip2, PPMd7/8, Deflate, Deflate64, Zstandard), preprocessing filters (BCJ variants, Delta), encryption (AES-256), and complete support for multiple archive formats (.7z, ZIP, RAR, TAR, ISO, CPIO, GZIP, XZ, BZIP2).
14
+
15
+ It provides both a command-line interface and a programmatic Ruby API, making it ideal for applications requiring portable, dependency-free compression without relying on system-level libraries or external binaries.
16
+
17
+ **Pure Ruby Implementation:** Works on all Ruby platforms (MRI, JRuby, TruffleRuby) with zero external dependencies. Performance is 10-60x slower than native implementations, which is an acceptable trade-off for maximum portability.
18
+
19
+ == Features
20
+
21
+ === Compression Algorithms
22
+
23
+ * **LZMA/LZMA2** - High compression ratio with dictionary-based encoding
24
+ * **BZip2** - Burrows-Wheeler Transform compression
25
+ * **PPMd7/PPMd8** - Prediction by Partial Matching for text
26
+ * **Deflate/Deflate64** - ZIP-compatible compression (32KB/64KB windows)
27
+ * **Zstandard** - Modern fast compression
28
+
29
+ See link:readme-docs/compression-algorithms.adoc[Compression Algorithms Guide] for detailed information.
30
+
31
+ ==== SDK-Compatible LZMA Mode (v0.2.0)
32
+
33
+ Omnizip now provides SDK-compatible LZMA encoding and decoding for full XZ/LZMA tool compatibility.
34
+
35
+ **Usage:**
36
+
37
+ [source,ruby]
38
+ ----
39
+ require 'omnizip'
40
+
41
+ # SDK-compatible encoding
42
+ File.open('output.lzma', 'wb') do |f|
43
+ encoder = Omnizip::Algorithms::LZMA::Encoder.new(f, sdk_compatible: true)
44
+ encoder.encode_stream("Hello, World!")
45
+ end
46
+
47
+ # SDK-compatible decoding
48
+ output = StringIO.new
49
+ File.open('output.lzma', 'rb') do |f|
50
+ decoder = Omnizip::Algorithms::LZMA::Decoder.new(f, sdk_compatible: true)
51
+ decoder.decode_stream(output)
52
+ end
53
+ ----
54
+
55
+ **Configuration:**
56
+
57
+ [source,ruby]
58
+ ----
59
+ encoder = Omnizip::Algorithms::LZMA::Encoder.new(output,
60
+ sdk_compatible: true, # Enable SDK mode
61
+ lc: 3, # Literal context bits (0-8, default: 3)
62
+ lp: 0, # Literal position bits (0-4, default: 0)
63
+ pb: 2, # Position bits (0-4, default: 2)
64
+ dict_size: 65536, # Dictionary size in bytes (default: 64KB)
65
+ level: 5 # Compression level (0-9, default: 5)
66
+ )
67
+ ----
68
+
69
+ **Compatibility:**
70
+
71
+ SDK-compatible mode produces output that can be decoded by:
72
+
73
+ * XZ Utils (`xz` command-line tool)
74
+ * LZMA Utils (`lzma` command-line tool)
75
+ * 7-Zip
76
+ * Any LZMA SDK-based application
77
+
78
+ And can decode files created by these tools.
79
+
80
+ **Performance:**
81
+
82
+ Pure Ruby implementation is 10-60x slower than native, an acceptable trade-off for maximum portability across all Ruby platforms (MRI, JRuby, TruffleRuby).
83
+
84
+ ==== XZ Format Support (v0.3.0)
85
+
86
+ Omnizip provides complete XZ container format (`.xz`) support with LZMA2 compression and decompression. The implementation is based on a port of the XZ Utils liblzma LZMA2 encoder and decoder, achieving full bidirectional compatibility with XZ Utils.
87
+
88
+ **Status**: ✅ **Full Support** - Bidirectional XZ Utils compatibility achieved
89
+
90
+ **Test Results**: 265/265 tests passing (100%)
91
+ * ✅ XZ Official Test Suite: 31/31 tests passing (100%)
92
+ * ✅ XZ Utils Reference Tests: 64/64 tests passing (100%)
93
+ * ✅ XZ Utils Test Suite: 111/111 tests passing (100%)
94
+ * ✅ XZ Filter Support: 30/30 tests passing (100%)
95
+ * ✅ XZ Encoding Compatibility: 7/7 tests passing (100%)
96
+
97
+ **What Works**:
98
+
99
+ * ✅ XZ container format (Stream Header, Stream Footer, Index)
100
+ * ✅ LZMA2 encoder and decoder (fully functional, XZ Utils compatible)
101
+ * ✅ Block headers with VLI encoding and correct padding
102
+ * ✅ All integrity checks: CRC32, CRC64, SHA256, None
103
+ * ✅ Multi-block support (encoding and decoding)
104
+ * ✅ Decoding all official XZ test fixtures
105
+ * ✅ Encoding produces files that XZ Utils can decode (bidirectional compatibility)
106
+ * ✅ ARM64 BCJ filter (both start_offset=0 and non-zero values)
107
+ * ✅ All BCJ filters (x86, PowerPC, IA-64, ARM, ARM Thumb, SPARC, RISC-V)
108
+ * ✅ Delta filter (single and multiple filter chains)
109
+ * ✅ Empty files and single-byte files
110
+ * ✅ Large files (>100 bytes)
111
+
112
+ **Usage**:
113
+
114
+ [source,ruby]
115
+ ----
116
+ require 'omnizip'
117
+
118
+ # Compress to XZ format
119
+ compressed = Omnizip::Formats::Xz.compress("Hello, World!")
120
+ File.write('output.xz', compressed)
121
+
122
+ # Decompress from XZ format
123
+ compressed_data = File.read('output.xz')
124
+ decompressed = Omnizip::Formats::Xz.decompress(compressed_data)
125
+
126
+ # Or use the Reader API
127
+ reader = Omnizip::Formats::Xz::Reader.new('file.xz')
128
+ data = reader.read
129
+ ----
130
+
131
+ **Advanced Options**:
132
+
133
+ [source,ruby]
134
+ ----
135
+ # Configure checksum type
136
+ compressed = Omnizip::Formats::Xz.compress(data, check_type: :crc64)
137
+ # Options: :crc32 (default), :crc64, :sha256, :none
138
+
139
+ # Using Builder API for multi-part data
140
+ compressed = Omnizip::Formats::Xz.create do |builder|
141
+ builder.add_data("Part 1")
142
+ builder.add_data("Part 2")
143
+ builder.add_data("Part 3")
144
+ end
145
+ ----
146
+
147
+ **Compatibility**:
148
+
149
+ * ✅ **Bidirectional Compatibility**: Files created by Omnizip can be decoded by XZ Utils, and vice versa
150
+ * All official XZ test fixtures (22 good-*.xz files) decode successfully
151
+ * All compression levels supported
152
+ * All checksum types supported (CRC32, CRC64, SHA256, None)
153
+ * All BCJ filters working (x86, ARM, ARM64, PowerPC, IA-64, SPARC, RISC-V)
154
+ * Delta filter working with single and multiple filter chains
155
+ * Multi-block streams fully supported
156
+ * ARM64 BCJ with non-zero start_offset works correctly
157
+
158
+ **Testing**:
159
+
160
+ All XZ test suites pass (265/265, 100%):
161
+
162
+ * ✅ Decoding official files: 31/31 tests passing
163
+ * ✅ Structure validation: All tests passing
164
+ * ✅ LZMA2 encoder and decoder: Fully functional
165
+ * ✅ Encoding compatibility: 7/7 tests passing (Omnizip → XZ Utils)
166
+ * ✅ Filter support: 30/30 tests passing (BCJ, Delta)
167
+
168
+ **Performance**:
169
+
170
+ Pure Ruby implementation is 10-30x slower than native XZ Utils, which is an acceptable trade-off for maximum portability across all Ruby platforms (MRI, JRuby, TruffleRuby).
171
+
172
+ **Architecture**:
173
+
174
+ The XZ implementation follows clean object-oriented design with separation of concerns:
175
+
176
+ * `Formats::Xz::Reader` - Public API for reading XZ files
177
+ * `Formats::XzImpl::StreamDecoder` - Orchestrates stream decoding
178
+ * `Formats::XzImpl::StreamEncoder` - Handles stream-level encoding
179
+ * `Formats::XzImpl::BlockDecoder` - Decodes blocks with LZMA2 integration
180
+ * `Formats::XzImpl::BlockEncoder` - Encodes blocks with LZMA2
181
+ * `Formats::XzImpl::VLI` - Variable-length integer codec
182
+ * `Formats::XzImpl::StreamHeaderParser` - Stream header parsing
183
+ * `Formats::XzImpl::StreamFooterParser` - Stream footer parsing
184
+ * `Formats::XzImpl::BlockHeaderParser` - Block header parsing
185
+ * `Formats::XzImpl::IndexDecoder` - Index metadata parsing
186
+ * `Checksums::Verifier` - Checksum verification utilities
187
+
188
+ ==== 7-Zip Format Support (v0.3.0)
189
+
190
+ Omnizip provides complete 7-Zip container format (`.7z`) support with multiple compression algorithms and encryption. The implementation is based on the 7-Zip format specification.
191
+
192
+ **Status**: ✅ **Full Support** - Complete 7-Zip compatibility achieved
193
+
194
+ **Test Results**: 50/50 tests passing (100%)
195
+ * ✅ 7-Zip Official Test Suite: 50/50 tests passing (100%)
196
+ * ✅ Archive creation and extraction: All tests passing
197
+ * ✅ Solid compression: Fully functional
198
+ * ✅ Multi-volume archives: Fully functional
199
+ * ✅ Header encryption: Fully functional
200
+
201
+ **What Works**:
202
+
203
+ * ✅ 7-Zip container format (headers, metadata, structure)
204
+ * ✅ Multiple compression algorithms (LZMA, LZMA2, DEFLATE, PPMD, BZip2)
205
+ * ✅ Solid compression for improved ratios
206
+ * ✅ Multi-volume split archives
207
+ * ✅ Password protection (AES-256)
208
+ * ✅ File attributes and timestamps
209
+ * ✅ Archive creation and extraction
210
+ * ✅ Directory structures
211
+
212
+ **Usage**:
213
+
214
+ [source,ruby]
215
+ ----
216
+ require 'omnizip'
217
+
218
+ # Create 7z archive
219
+ Omnizip::Formats::SevenZip::Writer.create('archive.7z') do |sz|
220
+ sz.add_file('document.pdf')
221
+ sz.add_directory('photos/')
222
+ end
223
+
224
+ # Extract 7z archive
225
+ Omnizip::Formats::SevenZip::Reader.open('archive.7z') do |sz|
226
+ sz.extract_all('output/')
227
+ end
228
+
229
+ # List contents
230
+ Omnizip::Formats::SevenZip::Reader.open('archive.7z') do |sz|
231
+ sz.entries.each do |entry|
232
+ puts "#{entry.name}: #{entry.size} bytes"
233
+ end
234
+ end
235
+ ----
236
+
237
+ **Advanced Options**:
238
+
239
+ [source,ruby]
240
+ ----
241
+ # With compression options
242
+ Omnizip::Formats::SevenZip::Writer.create('archive.7z',
243
+ algorithm: :lzma2,
244
+ level: 9,
245
+ solid: true
246
+ ) do |sz|
247
+ sz.add_directory('data/')
248
+ end
249
+
250
+ # With password encryption
251
+ Omnizip::Formats::SevenZip::Writer.create('secure.7z',
252
+ password: 'secret123',
253
+ encrypt_header: true
254
+ ) do |sz|
255
+ sz.add_file('confidential.doc')
256
+ end
257
+ ----
258
+
259
+ **Compatibility**:
260
+
261
+ * ✅ **Full 7-Zip compatibility**: Archives created by Omnizip can be opened by 7-Zip
262
+ * ✅ **7-Zip format specification**: Follows the official 7z format specification
263
+ * ✅ **All compression methods**: LZMA, LZMA2, DEFLATE, PPMD, BZip2
264
+ * ✅ **Solid compression**: For improved compression ratios on similar files
265
+ * ✅ **Multi-volume**: Split archives across multiple files
266
+ * ✅ **Encryption**: AES-256 password protection
267
+
268
+ **Testing**:
269
+
270
+ All 7-Zip test suites pass (50/50, 100%):
271
+
272
+ * ✅ Archive creation: All tests passing
273
+ * ✅ Archive extraction: All tests passing
274
+ * ✅ Solid compression: All tests passing
275
+ * ✅ Multi-volume: All tests passing
276
+ * ✅ Header encryption: All tests passing
277
+ * ✅ File attributes: All tests passing
278
+
279
+ **Performance**:
280
+
281
+ Pure Ruby implementation is 10-60x slower than native 7-Zip, which is an acceptable trade-off for maximum portability across all Ruby platforms (MRI, JRuby, TruffleRuby).
282
+
283
+ === Preprocessing Filters
284
+
285
+ * **BCJ Filters** - Branch-Call-Jump filters for executables (x86, ARM, ARM64, PPC, SPARC, IA-64)
286
+ * **BCJ2** - Advanced 4-stream x86 filter
287
+ * **Delta** - Delta encoding for multimedia/databases
288
+
289
+ See link:readme-docs/preprocessing-filters.adoc[Preprocessing Filters Guide] for details.
290
+
291
+ === Archive Formats
292
+
293
+ * **.7z** - Full read/write with solid compression, multi-volume support
294
+ * **ZIP** - Full read/write with ZIP64, WinZip AES encryption
295
+ * **RAR4** - Full read support with all compression methods, write support with STORE, FASTEST, NORMAL (v0.3.0)
296
+ * **RAR5** - Full read/write support with STORE and LZMA compression, multi-volume, solid archives (v0.3.0)
297
+ * **TAR** - Full read/write with POSIX extensions
298
+ * **ISO 9660** - Full read/write with Rock Ridge/Joliet
299
+ * **CPIO** - Full read/write (newc, CRC formats)
300
+ * **GZIP/XZ/BZIP2** - Single file compression formats
301
+
302
+ See link:readme-docs/archive-formats.adoc[Archive Formats Documentation] for complete details.
303
+
304
+ === PAR2 Parity Archives
305
+
306
+ Full support for PAR2 (Parity Archive Volume 2) error correction using Reed-Solomon codes over GF(2^16):
307
+
308
+ * Detect data corruption at block level using MD5 checksums
309
+ * Verify file integrity without unpacking
310
+ * Repair corrupted or missing files automatically
311
+ * Protect multiple files in a single archive set
312
+ * Configurable redundancy from 0-100%
313
+ * Full par2cmdline compatibility (v0.2.0)
314
+
315
+ See link:readme-docs/par2-archives.adoc[PAR2 Parity Archives Guide] for comprehensive documentation.
316
+
317
+ === Advanced Features
318
+
319
+ * **Compression Profiles** - Smart algorithm selection based on file type
320
+ * **Format Converter** - Convert between ZIP and 7z formats
321
+ * **Performance Profiler** - Identify bottlenecks and optimize
322
+ * **Progress Tracking** - Real-time progress with ETA calculation
323
+ * **Selective Extraction** - Glob, regex, and predicate-based extraction
324
+ * **Parallel Processing** - Multi-threaded compression using Ractors
325
+ * **Encryption** - AES-256 password protection with SHA-256 key derivation
326
+ * **Checksums** - CRC32/CRC64 integrity verification
327
+ * **Enumerable Collections** - All archive and result classes support Ruby's Enumerable interface
328
+
329
+ See link:readme-docs/advanced-features.adoc[Advanced Features Guide] for details.
330
+
331
+ === Test Coverage (v0.3.0)
332
+
333
+ Omnizip maintains comprehensive test coverage:
334
+
335
+ * **Total Tests**: 3406 examples
336
+ * **Pass Rate**: 100% (0 failures)
337
+ * **Pending**: 5 tests (PPMd and Zstandard deferred to v0.4.0)
338
+ * **Coverage**: All compression algorithms, archive formats, and features
339
+ * **Integration**: Full round-trip verification for all formats
340
+ * **Reference Tests**: libarchive RAR4/RAR5 compatibility verified (103 test files)
341
+
342
+ == Quick Start
343
+
344
+ === Installation
345
+
346
+ [source,sh]
347
+ ----
348
+ # Via Bundler
349
+ gem 'omnizip'
350
+
351
+ # Via gem command
352
+ gem install omnizip
353
+ ----
354
+
355
+ See link:readme-docs/installation.adoc[Installation Guide] for complete instructions.
356
+
357
+ === Command Line
358
+
359
+ [source,sh]
360
+ ----
361
+ # Compress a file
362
+ omnizip compress input.txt output.lzma --level 9
363
+
364
+ # Create a .7z archive
365
+ omnizip archive create backup.7z documents/ photos/
366
+
367
+ # Extract an archive
368
+ omnizip archive extract backup.7z output/
369
+
370
+ # List archive contents
371
+ omnizip archive list backup.7z
372
+ ----
373
+
374
+ See link:readme-docs/cli-usage.adoc[CLI Usage Guide] for all commands and options.
375
+
376
+ === Ruby API
377
+
378
+ ==== Simple Convenience Methods
379
+
380
+ [source,ruby]
381
+ ----
382
+ require 'omnizip'
383
+
384
+ # One-liners for common operations
385
+ Omnizip.compress_file('input.txt', 'output.zip')
386
+ Omnizip.extract_archive('archive.zip', 'output/')
387
+ Omnizip.list_archive('archive.zip')
388
+ ----
389
+
390
+ ==== Rubyzip Compatibility Mode
391
+
392
+ [source,ruby]
393
+ ----
394
+ require 'omnizip/rubyzip_compat'
395
+
396
+ # Drop-in replacement for rubyzip
397
+ Zip::File.open('archive.zip', create: true) do |zip|
398
+ zip.add('file.txt') { 'Content' }
399
+ end
400
+
401
+ Zip::File.open('archive.zip') do |zip|
402
+ content = zip.read('file.txt')
403
+ end
404
+ ----
405
+
406
+ ==== Native Omnizip API
407
+
408
+ [source,ruby]
409
+ ----
410
+ require 'omnizip'
411
+
412
+ # Full control with algorithm registry
413
+ algorithm = Omnizip::AlgorithmRegistry.get(:lzma2).new(level: 9)
414
+ File.open('input.txt', 'rb') do |input|
415
+ File.open('output.lzma', 'wb') do |output|
416
+ algorithm.compress(input, output)
417
+ end
418
+ end
419
+
420
+ # .7z archive operations
421
+ writer = Omnizip::Formats::SevenZip::Writer.new('archive.7z')
422
+ writer.add_file('document.pdf')
423
+ writer.close
424
+ ----
425
+
426
+ ==== RAR Archives
427
+
428
+ ==== RAR4 Archives (v0.3.0)
429
+
430
+ Omnizip v0.3.0 provides complete RAR4 archive support with full read capabilities and write support for three compression methods:
431
+
432
+ ====== Reading RAR4 Archives
433
+
434
+ [source,ruby]
435
+ ----
436
+ require 'omnizip'
437
+
438
+ # Read RAR4 archive with native decompression
439
+ reader = Omnizip::Formats::Rar3::Reader.new
440
+ File.open('archive.rar', 'rb') do |io|
441
+ entries = reader.read_archive(io)
442
+
443
+ # List files with metadata
444
+ entries.each do |entry|
445
+ puts "#{entry.name}: #{entry.uncompressed_size} bytes (#{entry.compressed_size} compressed)"
446
+ puts " Method: #{entry.compression_method}"
447
+ puts " Modified: #{entry.modified_time}"
448
+ puts " Directory: #{entry.is_directory}"
449
+ end
450
+ end
451
+ ----
452
+
453
+ **RAR4 Reader Features:**
454
+
455
+ * ✅ All compression methods: STORE, FASTEST, FAST, NORMAL, GOOD, BEST
456
+ * ✅ Proper block header parsing (FILE blocks, archive headers)
457
+ * ✅ Minimal archive support (archives without archive header)
458
+ * ✅ Unicode filename support
459
+ * ✅ Symlink detection and handling
460
+ * ✅ Multi-volume archive detection
461
+ * ✅ Graceful error handling for truncated/malformed files
462
+ * ✅ libarchive compatibility (52 test files verified)
463
+
464
+ ====== Writing RAR4 Archives
465
+
466
+ [source,ruby]
467
+ ----
468
+ require 'omnizip'
469
+
470
+ # Create RAR4 archive with default compression (NORMAL)
471
+ writer = Omnizip::Formats::Rar::Writer.new('archive.rar')
472
+ writer.add_file('document.txt')
473
+ writer.add_file('image.png')
474
+ writer.add_directory('photos/')
475
+ writer.write
476
+ writer.close
477
+
478
+ # Or use block syntax
479
+ Omnizip::Formats::Rar::Writer.new('archive.rar') do |rar|
480
+ rar.add_file('document.txt')
481
+ rar.add_directory('photos/')
482
+ end
483
+
484
+ # Select compression method
485
+ writer = Omnizip::Formats::Rar::Writer.new('archive.rar',
486
+ compression_method: :normal # or :store, :fastest
487
+ )
488
+ writer.add_file('large_file.bin')
489
+ writer.write
490
+ ----
491
+
492
+ ====== RAR4 Compression Methods
493
+
494
+ [cols="2,2,2,4",options="header"]
495
+ |===
496
+ |Method |Speed |Ratio |Status
497
+ |`:store` |Instant |1.0x |✅ Fully working
498
+ |`:fastest` |Very Fast |2-3x |✅ Fully working
499
+ |`:normal` |Fast |3-5x |✅ Fully working (default)
500
+ |`:best` |Slow |5-10x |⚠️ Known issues (v0.3.1)
501
+ |===
502
+
503
+ ===== RAR5 Archives (v0.3.0)
504
+
505
+ Full read/write support for RAR5 archives with STORE and LZMA compression, including optional fields (mtime, CRC32).
506
+
507
+ ====== Reading RAR5 Archives
508
+
509
+ [source,ruby]
510
+ ----
511
+ require 'omnizip/formats/rar5/reader'
512
+
513
+ # Read RAR5 archive
514
+ reader = Omnizip::Formats::Rar5::Reader.new
515
+ File.open('archive.rar', 'rb') do |io|
516
+ entries = reader.read_archive(io)
517
+
518
+ # List files with metadata
519
+ entries.each do |entry|
520
+ puts "#{entry.name}: #{entry.uncompressed_size} bytes"
521
+ puts " Method: #{entry.compression_method}"
522
+ puts " CRC32: #{entry.crc32.to_s(16)}"
523
+ puts " Modified: #{entry.modified_time}"
524
+ end
525
+ end
526
+ ----
527
+
528
+ **RAR5 Reader Features:**
529
+
530
+ * ✅ All compression methods: STORE, LZSS (methods 0-5)
531
+ * ✅ Solid archive support
532
+ * ✅ Unicode filenames (UTF-8)
533
+ * ✅ Symlink and hardlink support
534
+ * ✅ Multi-file archives
535
+ * ✅ VInt (variable-length integer) parsing
536
+ * ✅ Proper header tracking with bounds checking
537
+ * ✅ Graceful error handling for truncated/invalid files
538
+ * ✅ libarchive compatibility (51 test files verified)
539
+
540
+ ====== Writing RAR5 Archives
541
+
542
+ [source,ruby]
543
+ ----
544
+ require 'omnizip/formats/rar/rar5/writer'
545
+
546
+ # Create RAR5 archive with STORE compression (default)
547
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('archive.rar')
548
+ writer.add_file('document.txt')
549
+ writer.add_file('image.png')
550
+ writer.write
551
+
552
+ # LZMA compression with level selection
553
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('archive.rar',
554
+ compression: :lzma,
555
+ level: 5 # 1=fastest, 3=normal, 5=best
556
+ )
557
+ writer.add_file('data.json')
558
+ writer.write
559
+
560
+ # Auto-select compression based on file size
561
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('archive.rar',
562
+ compression: :auto, # < 1KB → STORE, ≥ 1KB → LZMA
563
+ level: 3
564
+ )
565
+ writer.add_file('small.txt')
566
+ writer.add_file('large.dat')
567
+ writer.write
568
+ ----
569
+
570
+ ====== RAR5 Compression Methods
571
+
572
+ [cols="2,2,3,3",options="header"]
573
+ |===
574
+ |Method |Level |Dictionary |Status
575
+ |`:store` |0 |None |✅ Uncompressed passthrough
576
+ |`:lzma` |1 |256 KB |✅ LZMA fastest
577
+ |`:lzma` |2 |1 MB |✅ LZMA fast
578
+ |`:lzma` |3 |4 MB |✅ LZMA normal (default)
579
+ |`:lzma` |4 |8 MB |✅ LZMA good
580
+ |`:lzma` |5 |16 MB |✅ LZMA best
581
+ |===
582
+
583
+ ====== RAR5 Features
584
+
585
+ **Implemented (v0.3.0):**
586
+
587
+ * ✅ **STORE compression** - Uncompressed storage (method 0)
588
+ * ✅ **LZMA compression** - 5 compression levels (methods 1-5) - *SDK-compatible encoder*
589
+ * ✅ **Auto compression** - Smart selection based on file size
590
+ * ✅ **Multi-volume archives** - Split archives across multiple volumes
591
+ * ✅ **Solid compression** - 10-30% better compression for similar files
592
+ * ✅ **AES-256 encryption** - Password protection with PBKDF2-HMAC-SHA256
593
+ * ✅ **PAR2 recovery records** - Error correction with Reed-Solomon codes
594
+ * ✅ **Optional fields** - Modification time (mtime), CRC32 checksums
595
+ * ✅ **Pure Ruby** - Zero external dependencies
596
+ * ✅ **LZMA SDK compatibility** - Encoder produces byte-for-byte identical output to reference implementation
597
+ * ✅ **Full reader support** - All compression methods, solid archives, unicode, symlinks
598
+
599
+ **CRC32 Limitation:**
600
+
601
+ * ⚠️ **CRC32 checksums** - Only compatible with STORE compression
602
+ - When LZMA compression is used, CRC32 is automatically disabled
603
+ - This is a RAR5 format limitation, not an implementation issue
604
+ - Use BLAKE2sp (always enabled) for compressed file integrity
605
+
606
+ ====== RAR5 Optional Fields
607
+
608
+ RAR5 supports optional metadata fields for enhanced archive information:
609
+
610
+ [source,ruby]
611
+ ----
612
+ require 'omnizip/formats/rar/rar5/writer'
613
+
614
+ # Include modification time in archive
615
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('archive.rar',
616
+ include_mtime: true # Preserves file modification timestamps
617
+ )
618
+ writer.add_file('document.txt')
619
+ writer.write
620
+
621
+ # Include CRC32 checksums (STORE compression only)
622
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('archive.rar',
623
+ compression: :store,
624
+ include_crc32: true # Only works with STORE compression
625
+ )
626
+ writer.add_file('data.bin')
627
+ writer.write
628
+
629
+ # IMPORTANT: CRC32 with LZMA is automatically disabled
630
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('archive.rar',
631
+ compression: :lzma,
632
+ level: 5,
633
+ include_crc32: true # Will be auto-disabled, no error
634
+ )
635
+ writer.add_file('document.txt')
636
+ writer.write
637
+ # CRC32 will be silently disabled - archive uses BLAKE2sp only
638
+ ----
639
+
640
+ **CRC32 Limitation Explained:**
641
+
642
+ RAR5's optional CRC32 field is incompatible with compression algorithms. The RAR5 format specification requires that when compression is used (LZMA, LZMA2), only the BLAKE2sp checksum (always present in the main file header) should be used for integrity verification. The optional CRC32 field is designed for uncompressed (STORE) files only.
643
+
644
+ When you request `include_crc32: true` with LZMA compression, Omnizip automatically disables CRC32 to ensure format compliance and compatibility with official unrar tools.
645
+
646
+ ====== RAR5 Multi-Volume Archives
647
+
648
+ Create split archives when file size exceeds volume limit. Volumes are automatically created and numbered according to the chosen naming pattern.
649
+
650
+ [source,ruby]
651
+ ----
652
+ require 'omnizip/formats/rar/rar5/writer'
653
+
654
+ # Create multi-volume archive with default settings
655
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('archive.rar',
656
+ multi_volume: true,
657
+ volume_size: '10M' # Human-readable size
658
+ )
659
+ writer.add_directory('data/')
660
+ volumes = writer.write # Returns array of volume paths
661
+ # => ['archive.part1.rar', 'archive.part2.rar', ...]
662
+
663
+ # Custom volume naming pattern
664
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('backup.rar',
665
+ multi_volume: true,
666
+ volume_size: '100M',
667
+ volume_naming: 'volume' # backup.volume1.rar, backup.volume2.rar
668
+ )
669
+ writer.add_directory('large_dataset/')
670
+ volumes = writer.write
671
+
672
+ # Numeric naming pattern
673
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('data.rar',
674
+ multi_volume: true,
675
+ volume_size: '50M',
676
+ volume_naming: 'numeric' # data.001.rar, data.002.rar
677
+ )
678
+ writer.add_file('huge_file.bin')
679
+ volumes = writer.write
680
+ ----
681
+
682
+ **Volume Naming Patterns:**
683
+
684
+ * `part` (default): archive.part1.rar, archive.part2.rar, ...
685
+ * `volume`: archive.volume1.rar, archive.volume2.rar, ...
686
+ * `numeric`: archive.001.rar, archive.002.rar, ...
687
+
688
+ **Human-Readable Sizes:**
689
+
690
+ * Bytes: `1024`, `2048`
691
+ * Kilobytes: `10K`, `100KB`
692
+ * Megabytes: `10M`, `100MB`
693
+ * Gigabytes: `1G`, `5GB`
694
+
695
+ **Minimum volume size:** 64 KB (65,536 bytes)
696
+
697
+ ====== RAR5 Solid Compression
698
+
699
+ Compress multiple files with a shared dictionary for significantly better compression ratios. Ideal for similar files such as source code, logs, or document collections.
700
+
701
+ [source,ruby]
702
+ ----
703
+ require 'omnizip/formats/rar/rar5/writer'
704
+
705
+ # Enable solid compression (default: 10-30% better ratio)
706
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('archive.rar',
707
+ compression: :lzma,
708
+ level: 5,
709
+ solid: true # Enable solid mode
710
+ )
711
+ writer.add_directory('project/')
712
+ writer.write
713
+
714
+ # Combine with high compression level
715
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('backup.rar',
716
+ compression: :lzma,
717
+ level: 5, # Best compression
718
+ solid: true # Shared dictionary
719
+ )
720
+ writer.add_file('log1.txt')
721
+ writer.add_file('log2.txt')
722
+ writer.add_file('log3.txt')
723
+ writer.write
724
+ ----
725
+
726
+ **Benefits:**
727
+
728
+ * 10-30% better compression ratios for similar files
729
+ * Larger LZMA dictionaries (16-64 MB vs 1-16 MB)
730
+ * Particularly effective for:
731
+ - Source code repositories
732
+ - Log files and text documents
733
+ - Similar structured data
734
+
735
+ **Trade-offs:**
736
+
737
+ * Cannot extract individual files without decompressing entire solid block
738
+ * Corruption in one file may affect subsequent files in the block
739
+ * Slightly longer extraction time for single files
740
+ * Best for archiving complete collections
741
+
742
+ ====== RAR5 AES-256 Encryption
743
+
744
+ Protect archives with industry-standard AES-256-CBC encryption and PBKDF2-HMAC-SHA256 key derivation.
745
+
746
+ [source,ruby]
747
+ ----
748
+ require 'omnizip/formats/rar/rar5/writer'
749
+
750
+ # Basic password protection
751
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('archive.rar',
752
+ compression: :lzma,
753
+ password: 'SecurePassword123!'
754
+ )
755
+ writer.add_file('confidential.pdf')
756
+ writer.write
757
+
758
+ # Custom key derivation iterations
759
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('secure.rar',
760
+ compression: :lzma,
761
+ level: 5,
762
+ password: 'VerySecurePassword2025!',
763
+ kdf_iterations: 524_288 # Higher = more secure, slower
764
+ )
765
+ writer.add_directory('sensitive_data/')
766
+ writer.write
767
+
768
+ # Minimum security (faster but less secure)
769
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('quick.rar',
770
+ password: 'FastPassword',
771
+ kdf_iterations: 65_536 # Minimum allowed
772
+ )
773
+ writer.add_file('temp.txt')
774
+ writer.write
775
+ ----
776
+
777
+ **Security Features:**
778
+
779
+ * **AES-256-CBC encryption** with PKCS#7 padding
780
+ * **PBKDF2-HMAC-SHA256** key derivation function
781
+ * **Configurable KDF iterations:**
782
+ - Minimum: 65,536 (2^16) - fast but less secure
783
+ - Default: 262,144 (2^18) - balanced security/performance
784
+ - Maximum: 1,048,576 (2^20) - maximum security
785
+ * **Per-file IV generation** for enhanced security
786
+ * **Password verification** before decryption attempts
787
+
788
+ **Performance Impact:**
789
+
790
+ * Encryption overhead: < 2x slower than unencrypted
791
+ * KDF computation time varies with iteration count:
792
+ - 65,536 iterations: ~50-100ms
793
+ - 262,144 iterations: ~200-400ms
794
+ - 1,048,576 iterations: ~800-1600ms
795
+
796
+ ====== RAR5 PAR2 Recovery Records
797
+
798
+ Generate PAR2 parity files for archive recovery and error correction using Reed-Solomon codes.
799
+
800
+ [source,ruby]
801
+ ----
802
+ require 'omnizip/formats/rar/rar5/writer'
803
+
804
+ # Enable recovery with default 5% redundancy
805
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('archive.rar',
806
+ compression: :lzma,
807
+ recovery: true
808
+ )
809
+ writer.add_directory('important_data/')
810
+ files = writer.write
811
+ # => ['archive.rar', 'archive.par2', 'archive.vol00+01.par2', ...]
812
+
813
+ # Custom redundancy percentage
814
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('backup.rar',
815
+ compression: :lzma,
816
+ level: 5,
817
+ recovery: true,
818
+ recovery_percent: 10 # 10% redundancy (can recover up to 10% data loss)
819
+ )
820
+ writer.add_file('critical.db')
821
+ files = writer.write
822
+
823
+ # Maximum redundancy for critical data
824
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('critical.rar',
825
+ compression: :lzma,
826
+ recovery: true,
827
+ recovery_percent: 50 # 50% redundancy (maximum protection)
828
+ )
829
+ writer.add_directory('mission_critical/')
830
+ files = writer.write
831
+ ----
832
+
833
+ **Recovery Capabilities:**
834
+
835
+ * **Detect corruption** at block level
836
+ * **Repair damaged archives** automatically
837
+ * **Recover from partial data loss** up to redundancy percentage
838
+ * **Works with all features:**
839
+ - Multi-volume archives
840
+ - Solid compression
841
+ - Encrypted archives
842
+ * **Reed-Solomon error correction** over GF(2^16)
843
+
844
+ **Redundancy Guidelines:**
845
+
846
+ * 5% (default): Suitable for general backups
847
+ * 10%: Recommended for important data
848
+ * 20-30%: High-value data requiring extra protection
849
+ * 50-100%: Critical data with maximum recovery needs
850
+
851
+ **PAR2 File Size:**
852
+
853
+ PAR2 files add approximately the redundancy percentage to total archive size. For example, a 100MB archive with 10% redundancy will generate ~10MB of PAR2 files.
854
+
855
+ ====== RAR5 Combined Features
856
+
857
+ All RAR5 features can be used together for comprehensive archive protection:
858
+
859
+ [source,ruby]
860
+ ----
861
+ require 'omnizip/formats/rar/rar5/writer'
862
+
863
+ # Complete feature demonstration
864
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('complete.rar',
865
+ # Compression
866
+ compression: :lzma,
867
+ level: 5, # Best compression
868
+ solid: true, # Shared dictionary for better ratios
869
+
870
+ # Security
871
+ password: 'SecureBackup2025!',
872
+ kdf_iterations: 524_288, # Enhanced security
873
+
874
+ # Multi-volume
875
+ multi_volume: true,
876
+ volume_size: '100M',
877
+ volume_naming: 'part',
878
+
879
+ # Recovery
880
+ recovery: true,
881
+ recovery_percent: 10,
882
+
883
+ # Optional fields
884
+ include_mtime: true
885
+ )
886
+
887
+ writer.add_directory('/critical/data')
888
+ files = writer.write
889
+ # => ['complete.part1.rar', 'complete.part2.rar', ...,
890
+ # 'complete.par2', 'complete.vol00+01.par2', ...]
891
+ ----
892
+
893
+ **Best Practices:**
894
+
895
+ 1. **Solid + LZMA level 5** for maximum compression on similar files
896
+ 2. **10-20% PAR2** for important data protection
897
+ 3. **262,144 KDF iterations** for balanced security/performance
898
+ 4. **Multi-volume** for large archives or optical media
899
+ 5. **Always include mtime** to preserve file timestamps
900
+
901
+ **Example: Secure Backup Archive**
902
+
903
+ [source,ruby]
904
+ ----
905
+ # Production-ready backup configuration
906
+ writer = Omnizip::Formats::Rar::Rar5::Writer.new('backup_2025-12-24.rar',
907
+ compression: :lzma,
908
+ level: 5,
909
+ solid: true, # 10-30% better compression
910
+ password: ENV['BACKUP_PASSWORD'] || 'DefaultSecure123!',
911
+ kdf_iterations: 262_144, # Balanced security
912
+ multi_volume: true,
913
+ volume_size: '4G', # DVD-sized volumes
914
+ recovery: true,
915
+ recovery_percent: 15, # 15% redundancy
916
+ include_mtime: true
917
+ )
918
+
919
+ writer.add_directory('/home/user/documents')
920
+ writer.add_directory('/home/user/projects')
921
+ files = writer.write
922
+
923
+ puts "Backup created: #{files.size} files"
924
+ puts "Total size: #{files.sum { |f| File.size(f) } / 1024 / 1024}MB"
925
+ ----
926
+
927
+ **Important:**
928
+ - Ensure you have set the `BACKUP_PASSWORD` environment variable before running the secure backup example.
929
+ - This example assumes a Linux/Unix environment; file paths may need adjustments for Windows.
930
+
931
+ **Security Note:**
932
+ - Use a strong, complex password for `BACKUP_PASSWORD`.
933
+ - Consider using a password manager to store and retrieve your backup password securely.
934
+ - If using this code in production, review the security implications and adjust as needed.
935
+
936
+ **Performance Note:**
937
+ - Encryption and KDF computations can be CPU-intensive.
938
+ - The `kdf_iterations` value affects security; higher values are more secure but slower.
939
+ - The `volume_naming` option can impact the efficiency and naming of multi-volume archives.
940
+
941
+ **Error Handling:**
942
+ - Enhance this example by adding error handling for file operations and encryption failures.
943
+
944
+ Dresses your ruby file as README.md (see https://guides.github.com/features/mastering-markdown/).
945
+
946
+ == Documentation
947
+
948
+ === Core Documentation
949
+
950
+ * **link:readme-docs/installation.adoc[Installation Guide]** - Setup and system requirements
951
+ * **link:readme-docs/cli-usage.adoc[CLI Usage]** - Command-line interface reference
952
+ * **link:readme-docs/api-usage.adoc[Library API]** - Programmatic Ruby API guide
953
+ * **link:readme-docs/compression-algorithms.adoc[Compression Algorithms]** - LZMA, BZip2, PPMd, Deflate, Zstandard
954
+ * **link:readme-docs/preprocessing-filters.adoc[Preprocessing Filters]** - BCJ, BCJ2, Delta filters
955
+ * **link:readme-docs/encryption-checksums.adoc[Encryption & Checksums]** - AES-256, CRC32/CRC64
956
+ * **link:readme-docs/architecture.adoc[Architecture]** - System design, patterns, extensibility
957
+
958
+ === Format Documentation
959
+
960
+ * **link:readme-docs/archive-formats.adoc[Archive Formats]** - .7z, ZIP, RAR, TAR, ISO, CPIO
961
+ * **link:readme-docs/par2-archives.adoc[PAR2 Parity Archives]** - Error correction and repair
962
+
963
+ === Advanced Topics
964
+
965
+ * **link:readme-docs/compression-profiles.adoc[Compression Profiles]** - Smart algorithm selection
966
+ * **link:readme-docs/format-converter.adoc[Format Converter]** - Convert between formats
967
+ * **link:readme-docs/performance-profiler.adoc[Performance Profiler]** - Benchmarking and optimization
968
+ * **link:readme-docs/advanced-features.adoc[Advanced Features]** - Progress, ETA, parallel processing
969
+
970
+ === Additional Resources
971
+
972
+ * link:old-docs/MIGRATION_GUIDE.md[Migration from Rubyzip]
973
+ * link:old-docs/COMPATIBILITY_MATRIX.md[Compatibility Matrix]
974
+ * link:old-docs/BASELINE.md[Performance Baseline]
975
+ * link:old-docs/CONTRIBUTING.md[Contributing Guidelines]
976
+
977
+ == Development
978
+
979
+ === Running Tests
980
+
981
+ [source,sh]
982
+ ----
983
+ # Run all tests
984
+ bundle exec rspec
985
+
986
+ # Run specific test file
987
+ bundle exec rspec spec/omnizip/algorithms/lzma_spec.rb
988
+
989
+ # Run with documentation format
990
+ bundle exec rspec --format documentation
991
+ ----
992
+
993
+ === Running Linters
994
+
995
+ [source,sh]
996
+ ----
997
+ # Run RuboCop
998
+ bundle exec rubocop
999
+
1000
+ # Auto-correct offenses
1001
+ bundle exec rubocop -A
1002
+
1003
+ # Generate config for new offenses
1004
+ bundle exec rubocop -A --auto-gen-config
1005
+ ----
1006
+
1007
+ === Performance Benchmarks
1008
+
1009
+ [source,sh]
1010
+ ----
1011
+ # Run performance benchmarks
1012
+ ruby benchmark/run_benchmarks.rb
1013
+
1014
+ # View baseline results
1015
+ cat benchmark/results/v1.0_baseline.txt
1016
+ ----
1017
+
1018
+ == Contributing
1019
+
1020
+ Contributions are welcome! Please read link:old-docs/CONTRIBUTING.md[CONTRIBUTING.md] for details on our code of conduct, development process, and how to submit pull requests.
1021
+
1022
+ **Quick start:**
1023
+
1024
+ . Fork the repository
1025
+ . Create your feature branch (`git checkout -b feature/my-new-feature`)
1026
+ . Make your changes and add tests
1027
+ . Run the test suite (`bundle exec rspec`)
1028
+ . Run RuboCop (`bundle exec rubocop -A`)
1029
+ . Commit your changes with semantic commit messages
1030
+ . Push to the branch (`git push origin feature/my-new-feature`)
1031
+ . Create a new Pull Request
1032
+
1033
+ == Acknowledgments
1034
+
1035
+ Omnizip is a completely independent, clean-room implementation of compression algorithms and archive formats. The compression algorithms (LZMA, LZMA2, BZip2, PPMd, Deflate64, etc.) are implemented from publicly available specifications and mathematical descriptions.
1036
+
1037
+ Archive formats (7z, ZIP, RAR, TAR, ISO, CPIO) are implemented based on their public format specifications. Similar to libarchive's independent implementations, Omnizip provides open-source, unencumbered implementations of these formats.
1038
+
1039
+ IMPORTANT: Compression algorithms themselves are mathematical concepts and cannot be patented. Omnizip's implementations are original work based on algorithm specifications, not derivative of any existing codebase.
1040
+
1041
+ == Copyright and License
1042
+
1043
+ Copyright 2025 https://www.ribose.com[Ribose Inc.]
1044
+
1045
+ See the link:COPYING[COPYING] file and link:LICENSE[LICENSE] file for the complete text of the licenses.