omnizip 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (511) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +32 -0
  4. data/.rubocop_todo.yml +754 -0
  5. data/COPYING +502 -0
  6. data/Gemfile +17 -0
  7. data/LICENSE +12 -0
  8. data/README.adoc +1045 -0
  9. data/Rakefile +12 -0
  10. data/benchmark/README.md +260 -0
  11. data/benchmark/benchmark_suite.rb +125 -0
  12. data/benchmark/compression_bench.rb +181 -0
  13. data/benchmark/filter_bench.rb +180 -0
  14. data/benchmark/models/benchmark_result.rb +59 -0
  15. data/benchmark/models/comparison_result.rb +69 -0
  16. data/benchmark/profile_suite.rb +167 -0
  17. data/benchmark/reporter.rb +150 -0
  18. data/benchmark/run_benchmarks.rb +66 -0
  19. data/benchmark/test_data.rb +137 -0
  20. data/config/formats/rar3_spec.yml +91 -0
  21. data/config/formats/rar5_spec.yml +102 -0
  22. data/docs/.github/workflows/docs.yml +142 -0
  23. data/docs/.gitignore +21 -0
  24. data/docs/.lychee.toml +67 -0
  25. data/docs/Gemfile +13 -0
  26. data/docs/RAR_WRITE_SUPPORT.md +26 -0
  27. data/docs/README.md +101 -0
  28. data/docs/_config.yml +112 -0
  29. data/docs/assets/logo.svg +1 -0
  30. data/docs/assets/omnizip-logo.pdf +1540 -11
  31. data/docs/comparison/feature-matrix.adoc +694 -0
  32. data/docs/comparison/index.adoc +113 -0
  33. data/docs/comparison/vs-7zip.adoc +309 -0
  34. data/docs/comparison/vs-peazip.adoc +77 -0
  35. data/docs/comparison/vs-rubyzip.adoc +342 -0
  36. data/docs/comparison/vs-winrar.adoc +100 -0
  37. data/docs/compatibility.adoc +579 -0
  38. data/docs/concepts/index.adoc +129 -0
  39. data/docs/developer/architecture.adoc +256 -0
  40. data/docs/developer/contributing.adoc +158 -0
  41. data/docs/developer/index.adoc +25 -0
  42. data/docs/developer/testing.adoc +212 -0
  43. data/docs/getting-started/basic-usage.adoc +271 -0
  44. data/docs/getting-started/index.adoc +42 -0
  45. data/docs/getting-started/installation.adoc +138 -0
  46. data/docs/getting-started/quick-start.adoc +185 -0
  47. data/docs/getting-started/your-first-archive.adoc +218 -0
  48. data/docs/guides/advanced-features/encryption.adoc +300 -0
  49. data/docs/guides/advanced-features/index.adoc +49 -0
  50. data/docs/guides/advanced-features/parallel-processing.adoc +246 -0
  51. data/docs/guides/advanced-features/progress-tracking.adoc +320 -0
  52. data/docs/guides/advanced-features/streaming.adoc +212 -0
  53. data/docs/guides/archive-formats/gzip-format.adoc +107 -0
  54. data/docs/guides/archive-formats/index.adoc +130 -0
  55. data/docs/guides/archive-formats/rar-format.adoc +104 -0
  56. data/docs/guides/archive-formats/rar5.adoc +521 -0
  57. data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
  58. data/docs/guides/archive-formats/tar-format.adoc +106 -0
  59. data/docs/guides/archive-formats/xz-format.adoc +118 -0
  60. data/docs/guides/archive-formats/zip-format.adoc +35 -0
  61. data/docs/guides/compression-algorithms/bzip2.adoc +113 -0
  62. data/docs/guides/compression-algorithms/deflate.adoc +319 -0
  63. data/docs/guides/compression-algorithms/index.adoc +190 -0
  64. data/docs/guides/compression-algorithms/lzma.adoc +398 -0
  65. data/docs/guides/compression-algorithms/lzma2.adoc +327 -0
  66. data/docs/guides/compression-algorithms/ppmd.adoc +316 -0
  67. data/docs/guides/compression-algorithms/zstandard.adoc +361 -0
  68. data/docs/guides/creating-archives.adoc +354 -0
  69. data/docs/guides/extracting-archives.adoc +53 -0
  70. data/docs/guides/format-conversion.adoc +64 -0
  71. data/docs/guides/index.adoc +49 -0
  72. data/docs/guides/migration-rubyzip.adoc +217 -0
  73. data/docs/guides/parity-archives.adoc +605 -0
  74. data/docs/guides/performance-tuning.adoc +88 -0
  75. data/docs/index.adoc +218 -0
  76. data/docs/lychee.toml +67 -0
  77. data/docs/reference/api/overview.adoc +188 -0
  78. data/docs/reference/cli/compress-command.adoc +114 -0
  79. data/docs/reference/cli/overview.adoc +140 -0
  80. data/docs/reference/index.adoc +26 -0
  81. data/docs/resources/faq.adoc +185 -0
  82. data/docs/resources/quick-reference.adoc +222 -0
  83. data/docs/troubleshooting/index.adoc +208 -0
  84. data/examples/api_comparison.rb +205 -0
  85. data/examples/deflate64_example.rb +96 -0
  86. data/examples/par2_demo.rb +121 -0
  87. data/examples/quick_start_native.rb +150 -0
  88. data/examples/quick_start_rubyzip.rb +115 -0
  89. data/examples/rubyzip_compatibility_demo.rb +194 -0
  90. data/exe/omnizip +27 -0
  91. data/lib/omnizip/algorithm.rb +130 -0
  92. data/lib/omnizip/algorithm_registry.rb +86 -0
  93. data/lib/omnizip/algorithms/.keep +0 -0
  94. data/lib/omnizip/algorithms/bzip2/bwt.rb +225 -0
  95. data/lib/omnizip/algorithms/bzip2/decoder.rb +193 -0
  96. data/lib/omnizip/algorithms/bzip2/encoder.rb +237 -0
  97. data/lib/omnizip/algorithms/bzip2/huffman.rb +206 -0
  98. data/lib/omnizip/algorithms/bzip2/mtf.rb +101 -0
  99. data/lib/omnizip/algorithms/bzip2/rle.rb +151 -0
  100. data/lib/omnizip/algorithms/bzip2.rb +130 -0
  101. data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
  102. data/lib/omnizip/algorithms/deflate/decoder.rb +38 -0
  103. data/lib/omnizip/algorithms/deflate/encoder.rb +46 -0
  104. data/lib/omnizip/algorithms/deflate.rb +128 -0
  105. data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
  106. data/lib/omnizip/algorithms/deflate64/decoder.rb +153 -0
  107. data/lib/omnizip/algorithms/deflate64/encoder.rb +98 -0
  108. data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +354 -0
  109. data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +142 -0
  110. data/lib/omnizip/algorithms/deflate64.rb +109 -0
  111. data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
  112. data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
  113. data/lib/omnizip/algorithms/lzma/decoder.rb +148 -0
  114. data/lib/omnizip/algorithms/lzma/dictionary.rb +69 -0
  115. data/lib/omnizip/algorithms/lzma/distance_coder.rb +415 -0
  116. data/lib/omnizip/algorithms/lzma/encoder.rb +142 -0
  117. data/lib/omnizip/algorithms/lzma/length_coder.rb +260 -0
  118. data/lib/omnizip/algorithms/lzma/literal_decoder.rb +320 -0
  119. data/lib/omnizip/algorithms/lzma/literal_encoder.rb +210 -0
  120. data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +341 -0
  121. data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +192 -0
  122. data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
  123. data/lib/omnizip/algorithms/lzma/match.rb +32 -0
  124. data/lib/omnizip/algorithms/lzma/match_finder.rb +205 -0
  125. data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
  126. data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +88 -0
  127. data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +130 -0
  128. data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
  129. data/lib/omnizip/algorithms/lzma/range_coder.rb +85 -0
  130. data/lib/omnizip/algorithms/lzma/range_decoder.rb +434 -0
  131. data/lib/omnizip/algorithms/lzma/range_encoder.rb +194 -0
  132. data/lib/omnizip/algorithms/lzma/state.rb +127 -0
  133. data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +325 -0
  134. data/lib/omnizip/algorithms/lzma/xz_encoder.rb +426 -0
  135. data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +645 -0
  136. data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +227 -0
  137. data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +169 -0
  138. data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +261 -0
  139. data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
  140. data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +331 -0
  141. data/lib/omnizip/algorithms/lzma/xz_state.rb +116 -0
  142. data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +2055 -0
  143. data/lib/omnizip/algorithms/lzma.rb +238 -0
  144. data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +182 -0
  145. data/lib/omnizip/algorithms/lzma2/constants.rb +41 -0
  146. data/lib/omnizip/algorithms/lzma2/encoder.rb +147 -0
  147. data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +161 -0
  148. data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
  149. data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +127 -0
  150. data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
  151. data/lib/omnizip/algorithms/lzma2.rb +141 -0
  152. data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
  153. data/lib/omnizip/algorithms/ppmd7/context.rb +154 -0
  154. data/lib/omnizip/algorithms/ppmd7/decoder.rb +126 -0
  155. data/lib/omnizip/algorithms/ppmd7/encoder.rb +163 -0
  156. data/lib/omnizip/algorithms/ppmd7/model.rb +248 -0
  157. data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
  158. data/lib/omnizip/algorithms/ppmd7.rb +116 -0
  159. data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
  160. data/lib/omnizip/algorithms/ppmd8/context.rb +34 -0
  161. data/lib/omnizip/algorithms/ppmd8/decoder.rb +107 -0
  162. data/lib/omnizip/algorithms/ppmd8/encoder.rb +138 -0
  163. data/lib/omnizip/algorithms/ppmd8/model.rb +250 -0
  164. data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
  165. data/lib/omnizip/algorithms/ppmd8.rb +82 -0
  166. data/lib/omnizip/algorithms/ppmd_base.rb +138 -0
  167. data/lib/omnizip/algorithms/sevenzip_lzma2.rb +123 -0
  168. data/lib/omnizip/algorithms/xz_lzma2.rb +118 -0
  169. data/lib/omnizip/algorithms/zstandard/constants.rb +25 -0
  170. data/lib/omnizip/algorithms/zstandard/decoder.rb +46 -0
  171. data/lib/omnizip/algorithms/zstandard/encoder.rb +51 -0
  172. data/lib/omnizip/algorithms/zstandard.rb +138 -0
  173. data/lib/omnizip/buffer/memory_archive.rb +251 -0
  174. data/lib/omnizip/buffer/memory_extractor.rb +224 -0
  175. data/lib/omnizip/buffer.rb +176 -0
  176. data/lib/omnizip/checksum_registry.rb +114 -0
  177. data/lib/omnizip/checksums/crc32.rb +100 -0
  178. data/lib/omnizip/checksums/crc64.rb +101 -0
  179. data/lib/omnizip/checksums/crc_base.rb +158 -0
  180. data/lib/omnizip/checksums/verifier.rb +131 -0
  181. data/lib/omnizip/chunked/memory_manager.rb +194 -0
  182. data/lib/omnizip/chunked/reader.rb +78 -0
  183. data/lib/omnizip/chunked/writer.rb +120 -0
  184. data/lib/omnizip/chunked.rb +129 -0
  185. data/lib/omnizip/cli/output_formatter.rb +104 -0
  186. data/lib/omnizip/cli.rb +572 -0
  187. data/lib/omnizip/commands/.keep +0 -0
  188. data/lib/omnizip/commands/archive_create_command.rb +427 -0
  189. data/lib/omnizip/commands/archive_extract_command.rb +272 -0
  190. data/lib/omnizip/commands/archive_list_command.rb +218 -0
  191. data/lib/omnizip/commands/archive_repair_command.rb +131 -0
  192. data/lib/omnizip/commands/archive_verify_command.rb +117 -0
  193. data/lib/omnizip/commands/compress_command.rb +117 -0
  194. data/lib/omnizip/commands/decompress_command.rb +120 -0
  195. data/lib/omnizip/commands/list_command.rb +53 -0
  196. data/lib/omnizip/commands/metadata_command.rb +153 -0
  197. data/lib/omnizip/commands/parity_create_command.rb +122 -0
  198. data/lib/omnizip/commands/parity_repair_command.rb +122 -0
  199. data/lib/omnizip/commands/parity_verify_command.rb +124 -0
  200. data/lib/omnizip/commands/profile_list_command.rb +56 -0
  201. data/lib/omnizip/commands/profile_show_command.rb +44 -0
  202. data/lib/omnizip/convenience.rb +359 -0
  203. data/lib/omnizip/converter/conversion_registry.rb +49 -0
  204. data/lib/omnizip/converter/conversion_strategy.rb +121 -0
  205. data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +97 -0
  206. data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +112 -0
  207. data/lib/omnizip/converter.rb +105 -0
  208. data/lib/omnizip/crypto/aes256/cipher.rb +100 -0
  209. data/lib/omnizip/crypto/aes256/constants.rb +28 -0
  210. data/lib/omnizip/crypto/aes256/key_derivation.rb +101 -0
  211. data/lib/omnizip/crypto/aes256.rb +102 -0
  212. data/lib/omnizip/error.rb +106 -0
  213. data/lib/omnizip/eta/exponential_smoothing_estimator.rb +98 -0
  214. data/lib/omnizip/eta/moving_average_estimator.rb +99 -0
  215. data/lib/omnizip/eta/rate_calculator.rb +104 -0
  216. data/lib/omnizip/eta/sample_history.rb +143 -0
  217. data/lib/omnizip/eta/time_estimator.rb +106 -0
  218. data/lib/omnizip/eta.rb +63 -0
  219. data/lib/omnizip/extraction/filter_chain.rb +177 -0
  220. data/lib/omnizip/extraction/glob_pattern.rb +140 -0
  221. data/lib/omnizip/extraction/pattern_matcher.rb +70 -0
  222. data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
  223. data/lib/omnizip/extraction/regex_pattern.rb +50 -0
  224. data/lib/omnizip/extraction/selective_extractor.rb +240 -0
  225. data/lib/omnizip/extraction.rb +111 -0
  226. data/lib/omnizip/file_type/mime_classifier.rb +144 -0
  227. data/lib/omnizip/file_type.rb +113 -0
  228. data/lib/omnizip/filter.rb +139 -0
  229. data/lib/omnizip/filter_pipeline.rb +108 -0
  230. data/lib/omnizip/filter_registry.rb +166 -0
  231. data/lib/omnizip/filters/bcj.rb +279 -0
  232. data/lib/omnizip/filters/bcj2/constants.rb +53 -0
  233. data/lib/omnizip/filters/bcj2/decoder.rb +200 -0
  234. data/lib/omnizip/filters/bcj2/encoder.rb +61 -0
  235. data/lib/omnizip/filters/bcj2/stream_data.rb +93 -0
  236. data/lib/omnizip/filters/bcj2.rb +99 -0
  237. data/lib/omnizip/filters/bcj_arm.rb +176 -0
  238. data/lib/omnizip/filters/bcj_arm64.rb +244 -0
  239. data/lib/omnizip/filters/bcj_ia64.rb +196 -0
  240. data/lib/omnizip/filters/bcj_ppc.rb +190 -0
  241. data/lib/omnizip/filters/bcj_sparc.rb +176 -0
  242. data/lib/omnizip/filters/bcj_x86.rb +193 -0
  243. data/lib/omnizip/filters/delta.rb +196 -0
  244. data/lib/omnizip/filters/filter_base.rb +72 -0
  245. data/lib/omnizip/filters/registry.rb +123 -0
  246. data/lib/omnizip/filters/xz_delta.rb +258 -0
  247. data/lib/omnizip/format_detector.rb +162 -0
  248. data/lib/omnizip/format_registry.rb +59 -0
  249. data/lib/omnizip/formats/.keep +0 -0
  250. data/lib/omnizip/formats/bzip2_file.rb +172 -0
  251. data/lib/omnizip/formats/cpio/constants.rb +55 -0
  252. data/lib/omnizip/formats/cpio/entry.rb +385 -0
  253. data/lib/omnizip/formats/cpio/reader.rb +196 -0
  254. data/lib/omnizip/formats/cpio/writer.rb +234 -0
  255. data/lib/omnizip/formats/cpio.rb +140 -0
  256. data/lib/omnizip/formats/format_spec_loader.rb +230 -0
  257. data/lib/omnizip/formats/gzip.rb +238 -0
  258. data/lib/omnizip/formats/iso/directory_builder.rb +297 -0
  259. data/lib/omnizip/formats/iso/directory_record.rb +152 -0
  260. data/lib/omnizip/formats/iso/joliet.rb +204 -0
  261. data/lib/omnizip/formats/iso/path_table.rb +125 -0
  262. data/lib/omnizip/formats/iso/reader.rb +197 -0
  263. data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
  264. data/lib/omnizip/formats/iso/volume_builder.rb +320 -0
  265. data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
  266. data/lib/omnizip/formats/iso/writer.rb +530 -0
  267. data/lib/omnizip/formats/iso.rb +140 -0
  268. data/lib/omnizip/formats/lzip.rb +175 -0
  269. data/lib/omnizip/formats/lzma_alone.rb +171 -0
  270. data/lib/omnizip/formats/rar/archive_repairer.rb +243 -0
  271. data/lib/omnizip/formats/rar/archive_verifier.rb +195 -0
  272. data/lib/omnizip/formats/rar/block_parser.rb +243 -0
  273. data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
  274. data/lib/omnizip/formats/rar/compression/dispatcher.rb +217 -0
  275. data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +216 -0
  276. data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +158 -0
  277. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
  278. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
  279. data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
  280. data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
  281. data/lib/omnizip/formats/rar/compression/ppmd/context.rb +105 -0
  282. data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +219 -0
  283. data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +262 -0
  284. data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
  285. data/lib/omnizip/formats/rar/constants.rb +82 -0
  286. data/lib/omnizip/formats/rar/decompressor.rb +238 -0
  287. data/lib/omnizip/formats/rar/external_writer.rb +312 -0
  288. data/lib/omnizip/formats/rar/header.rb +192 -0
  289. data/lib/omnizip/formats/rar/license_validator.rb +109 -0
  290. data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
  291. data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
  292. data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
  293. data/lib/omnizip/formats/rar/parity_handler.rb +292 -0
  294. data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +202 -0
  295. data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +578 -0
  296. data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
  297. data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
  298. data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +97 -0
  299. data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
  300. data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +166 -0
  301. data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
  302. data/lib/omnizip/formats/rar/rar5/header.rb +187 -0
  303. data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
  304. data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
  305. data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
  306. data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
  307. data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
  308. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +264 -0
  309. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
  310. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +194 -0
  311. data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +109 -0
  312. data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +142 -0
  313. data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
  314. data/lib/omnizip/formats/rar/rar5/vint.rb +65 -0
  315. data/lib/omnizip/formats/rar/rar5/writer.rb +466 -0
  316. data/lib/omnizip/formats/rar/rar_format_base.rb +241 -0
  317. data/lib/omnizip/formats/rar/reader.rb +366 -0
  318. data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
  319. data/lib/omnizip/formats/rar/volume_manager.rb +168 -0
  320. data/lib/omnizip/formats/rar/writer.rb +431 -0
  321. data/lib/omnizip/formats/rar.rb +205 -0
  322. data/lib/omnizip/formats/rar3/compressor.rb +73 -0
  323. data/lib/omnizip/formats/rar3/decompressor.rb +66 -0
  324. data/lib/omnizip/formats/rar3/reader.rb +386 -0
  325. data/lib/omnizip/formats/rar3/writer.rb +219 -0
  326. data/lib/omnizip/formats/rar5/compressor.rb +73 -0
  327. data/lib/omnizip/formats/rar5/decompressor.rb +66 -0
  328. data/lib/omnizip/formats/rar5/reader.rb +342 -0
  329. data/lib/omnizip/formats/rar5/writer.rb +214 -0
  330. data/lib/omnizip/formats/seven_zip/coder_chain.rb +150 -0
  331. data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
  332. data/lib/omnizip/formats/seven_zip/encoded_header.rb +114 -0
  333. data/lib/omnizip/formats/seven_zip/encrypted_header.rb +142 -0
  334. data/lib/omnizip/formats/seven_zip/file_collector.rb +144 -0
  335. data/lib/omnizip/formats/seven_zip/header.rb +106 -0
  336. data/lib/omnizip/formats/seven_zip/header_encryptor.rb +134 -0
  337. data/lib/omnizip/formats/seven_zip/header_writer.rb +466 -0
  338. data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
  339. data/lib/omnizip/formats/seven_zip/models/file_entry.rb +58 -0
  340. data/lib/omnizip/formats/seven_zip/models/folder.rb +69 -0
  341. data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
  342. data/lib/omnizip/formats/seven_zip/parser.rb +660 -0
  343. data/lib/omnizip/formats/seven_zip/reader.rb +458 -0
  344. data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +632 -0
  345. data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +315 -0
  346. data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
  347. data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +162 -0
  348. data/lib/omnizip/formats/seven_zip/writer.rb +740 -0
  349. data/lib/omnizip/formats/seven_zip.rb +93 -0
  350. data/lib/omnizip/formats/tar/constants.rb +73 -0
  351. data/lib/omnizip/formats/tar/entry.rb +94 -0
  352. data/lib/omnizip/formats/tar/header.rb +168 -0
  353. data/lib/omnizip/formats/tar/reader.rb +121 -0
  354. data/lib/omnizip/formats/tar/writer.rb +216 -0
  355. data/lib/omnizip/formats/tar.rb +84 -0
  356. data/lib/omnizip/formats/xz/reader.rb +116 -0
  357. data/lib/omnizip/formats/xz.rb +237 -0
  358. data/lib/omnizip/formats/xz_impl/block_decoder.rb +754 -0
  359. data/lib/omnizip/formats/xz_impl/block_encoder.rb +306 -0
  360. data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
  361. data/lib/omnizip/formats/xz_impl/block_header_parser.rb +186 -0
  362. data/lib/omnizip/formats/xz_impl/constants.rb +49 -0
  363. data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
  364. data/lib/omnizip/formats/xz_impl/index_encoder.rb +122 -0
  365. data/lib/omnizip/formats/xz_impl/stream_decoder.rb +468 -0
  366. data/lib/omnizip/formats/xz_impl/stream_encoder.rb +99 -0
  367. data/lib/omnizip/formats/xz_impl/stream_footer.rb +81 -0
  368. data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +117 -0
  369. data/lib/omnizip/formats/xz_impl/stream_header.rb +55 -0
  370. data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +108 -0
  371. data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
  372. data/lib/omnizip/formats/xz_impl/writer.rb +421 -0
  373. data/lib/omnizip/formats/zip/central_directory_header.rb +195 -0
  374. data/lib/omnizip/formats/zip/constants.rb +69 -0
  375. data/lib/omnizip/formats/zip/end_of_central_directory.rb +133 -0
  376. data/lib/omnizip/formats/zip/local_file_header.rb +138 -0
  377. data/lib/omnizip/formats/zip/reader.rb +250 -0
  378. data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
  379. data/lib/omnizip/formats/zip/writer.rb +375 -0
  380. data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +104 -0
  381. data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +66 -0
  382. data/lib/omnizip/formats/zip/zip64_extra_field.rb +114 -0
  383. data/lib/omnizip/formats/zip.rb +50 -0
  384. data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
  385. data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
  386. data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
  387. data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
  388. data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
  389. data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +421 -0
  390. data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +465 -0
  391. data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +288 -0
  392. data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +200 -0
  393. data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +197 -0
  394. data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +141 -0
  395. data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +519 -0
  396. data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +723 -0
  397. data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +750 -0
  398. data/lib/omnizip/io/buffered_input.rb +146 -0
  399. data/lib/omnizip/io/buffered_output.rb +105 -0
  400. data/lib/omnizip/io/stream_manager.rb +115 -0
  401. data/lib/omnizip/link_handler/hard_link.rb +79 -0
  402. data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
  403. data/lib/omnizip/link_handler.rb +124 -0
  404. data/lib/omnizip/metadata/archive_metadata.rb +114 -0
  405. data/lib/omnizip/metadata/entry_metadata.rb +146 -0
  406. data/lib/omnizip/metadata/metadata_editor.rb +171 -0
  407. data/lib/omnizip/metadata/metadata_registry.rb +64 -0
  408. data/lib/omnizip/metadata/metadata_validator.rb +99 -0
  409. data/lib/omnizip/metadata.rb +57 -0
  410. data/lib/omnizip/models/.keep +0 -0
  411. data/lib/omnizip/models/algorithm_metadata.rb +73 -0
  412. data/lib/omnizip/models/compression_options.rb +71 -0
  413. data/lib/omnizip/models/conversion_options.rb +87 -0
  414. data/lib/omnizip/models/conversion_result.rb +135 -0
  415. data/lib/omnizip/models/eta_result.rb +46 -0
  416. data/lib/omnizip/models/extraction_rule.rb +115 -0
  417. data/lib/omnizip/models/filter_chain.rb +144 -0
  418. data/lib/omnizip/models/filter_config.rb +183 -0
  419. data/lib/omnizip/models/match_result.rb +124 -0
  420. data/lib/omnizip/models/optimization_suggestion.rb +91 -0
  421. data/lib/omnizip/models/parallel_options.rb +104 -0
  422. data/lib/omnizip/models/performance_result.rb +79 -0
  423. data/lib/omnizip/models/profile_report.rb +82 -0
  424. data/lib/omnizip/models/progress_options.rb +38 -0
  425. data/lib/omnizip/models/split_options.rb +116 -0
  426. data/lib/omnizip/optimization_registry.rb +81 -0
  427. data/lib/omnizip/parallel/job_queue.rb +209 -0
  428. data/lib/omnizip/parallel/job_scheduler.rb +203 -0
  429. data/lib/omnizip/parallel/parallel_compressor.rb +347 -0
  430. data/lib/omnizip/parallel/parallel_extractor.rb +329 -0
  431. data/lib/omnizip/parallel/worker_pool.rb +223 -0
  432. data/lib/omnizip/parallel.rb +149 -0
  433. data/lib/omnizip/parity/chunked_block_processor.rb +196 -0
  434. data/lib/omnizip/parity/galois16.rb +145 -0
  435. data/lib/omnizip/parity/models/creator_packet.rb +73 -0
  436. data/lib/omnizip/parity/models/file_description_packet.rb +133 -0
  437. data/lib/omnizip/parity/models/ifsc_packet.rb +123 -0
  438. data/lib/omnizip/parity/models/main_packet.rb +128 -0
  439. data/lib/omnizip/parity/models/packet.rb +156 -0
  440. data/lib/omnizip/parity/models/packet_registry.rb +109 -0
  441. data/lib/omnizip/parity/models/recovery_slice_packet.rb +78 -0
  442. data/lib/omnizip/parity/par2_creator.rb +531 -0
  443. data/lib/omnizip/parity/par2_repairer.rb +407 -0
  444. data/lib/omnizip/parity/par2_verifier.rb +364 -0
  445. data/lib/omnizip/parity/par2cmdline_algorithm.rb +110 -0
  446. data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
  447. data/lib/omnizip/parity/reed_solomon_decoder.rb +266 -0
  448. data/lib/omnizip/parity/reed_solomon_encoder.rb +111 -0
  449. data/lib/omnizip/parity/reed_solomon_matrix.rb +342 -0
  450. data/lib/omnizip/parity.rb +186 -0
  451. data/lib/omnizip/password/encryption_registry.rb +65 -0
  452. data/lib/omnizip/password/encryption_strategy.rb +96 -0
  453. data/lib/omnizip/password/password_validator.rb +129 -0
  454. data/lib/omnizip/password/winzip_aes_strategy.rb +192 -0
  455. data/lib/omnizip/password/zip_crypto_strategy.rb +141 -0
  456. data/lib/omnizip/password.rb +87 -0
  457. data/lib/omnizip/pipe/stream_compressor.rb +124 -0
  458. data/lib/omnizip/pipe/stream_decompressor.rb +174 -0
  459. data/lib/omnizip/pipe.rb +121 -0
  460. data/lib/omnizip/platform/ntfs_streams.rb +201 -0
  461. data/lib/omnizip/platform.rb +189 -0
  462. data/lib/omnizip/profile/archive_profile.rb +39 -0
  463. data/lib/omnizip/profile/balanced_profile.rb +33 -0
  464. data/lib/omnizip/profile/binary_profile.rb +36 -0
  465. data/lib/omnizip/profile/compression_profile.rb +158 -0
  466. data/lib/omnizip/profile/custom_profile.rb +157 -0
  467. data/lib/omnizip/profile/fast_profile.rb +33 -0
  468. data/lib/omnizip/profile/maximum_profile.rb +33 -0
  469. data/lib/omnizip/profile/profile_detector.rb +110 -0
  470. data/lib/omnizip/profile/profile_registry.rb +161 -0
  471. data/lib/omnizip/profile/text_profile.rb +36 -0
  472. data/lib/omnizip/profile.rb +190 -0
  473. data/lib/omnizip/profiler/memory_profiler.rb +66 -0
  474. data/lib/omnizip/profiler/method_profiler.rb +49 -0
  475. data/lib/omnizip/profiler/report_generator.rb +169 -0
  476. data/lib/omnizip/profiler.rb +204 -0
  477. data/lib/omnizip/progress/callback_reporter.rb +36 -0
  478. data/lib/omnizip/progress/console_reporter.rb +62 -0
  479. data/lib/omnizip/progress/log_reporter.rb +91 -0
  480. data/lib/omnizip/progress/operation_progress.rb +118 -0
  481. data/lib/omnizip/progress/progress_bar.rb +156 -0
  482. data/lib/omnizip/progress/progress_reporter.rb +40 -0
  483. data/lib/omnizip/progress/progress_tracker.rb +190 -0
  484. data/lib/omnizip/progress/silent_reporter.rb +24 -0
  485. data/lib/omnizip/progress.rb +127 -0
  486. data/lib/omnizip/rubyzip_compat.rb +63 -0
  487. data/lib/omnizip/temp/safe_extract.rb +168 -0
  488. data/lib/omnizip/temp/temp_file.rb +124 -0
  489. data/lib/omnizip/temp/temp_file_pool.rb +109 -0
  490. data/lib/omnizip/temp.rb +181 -0
  491. data/lib/omnizip/version.rb +5 -0
  492. data/lib/omnizip/zip/entry.rb +156 -0
  493. data/lib/omnizip/zip/file.rb +485 -0
  494. data/lib/omnizip/zip/input_stream.rb +273 -0
  495. data/lib/omnizip/zip/output_stream.rb +324 -0
  496. data/lib/omnizip.rb +156 -0
  497. data/readme-docs/advanced-features.adoc +515 -0
  498. data/readme-docs/api-usage.adoc +444 -0
  499. data/readme-docs/architecture.adoc +449 -0
  500. data/readme-docs/archive-formats.adoc +479 -0
  501. data/readme-docs/cli-usage.adoc +222 -0
  502. data/readme-docs/compression-algorithms.adoc +442 -0
  503. data/readme-docs/compression-profiles.adoc +247 -0
  504. data/readme-docs/encryption-checksums.adoc +328 -0
  505. data/readme-docs/format-converter.adoc +325 -0
  506. data/readme-docs/installation.adoc +228 -0
  507. data/readme-docs/par2-archives.adoc +608 -0
  508. data/readme-docs/performance-profiler.adoc +389 -0
  509. data/readme-docs/preprocessing-filters.adoc +280 -0
  510. data/xz-file-format-1.2.1.txt +1174 -0
  511. metadata +617 -0
@@ -0,0 +1,608 @@
1
+ = PAR2 Parity Archives
2
+ :toc:
3
+ :toclevels: 3
4
+
5
+ == Purpose
6
+
7
+ PAR2 (Parity Archive 2) provides error correction and repair capabilities for archives using Reed-Solomon error correction codes. Protect your data against corruption during transfer or storage.
8
+
9
+ == Features
10
+
11
+ * **Error Detection** - Verify file integrity with MD5 checksums
12
+ * **Error Correction** - Recover corrupted or missing blocks
13
+ * **Configurable Redundancy** - Choose protection level (0-100%)
14
+ * **Multi-file Support** - Protect multiple files with single PAR2 set
15
+ * **Block-level Recovery** - Efficient partial repairs
16
+ * **Progress Tracking** - Real-time feedback during operations
17
+
18
+ == Quick Start
19
+
20
+ === Protect a File
21
+
22
+ [source,ruby]
23
+ ----
24
+ # Create PAR2 protection with 5% redundancy
25
+ Omnizip::Parity.create('important.zip', redundancy: 5)
26
+ # Creates: important.par2, important.vol00+01.par2, etc.
27
+ ----
28
+
29
+ === Verify Integrity
30
+
31
+ [source,ruby]
32
+ ----
33
+ # Check if files are intact
34
+ result = Omnizip::Parity.verify('important.par2')
35
+
36
+ if result.all_ok?
37
+ puts "All files intact"
38
+ elsif result.repairable?
39
+ puts "Damage detected but can be repaired"
40
+ else
41
+ puts "Damage exceeds recovery capacity"
42
+ end
43
+ ----
44
+
45
+ === Repair Damage
46
+
47
+ [source,ruby]
48
+ ----
49
+ # Automatically repair damaged files
50
+ result = Omnizip::Parity.repair('important.par2')
51
+
52
+ if result.success?
53
+ puts "Recovered: #{result.recovered_files.join(', ')}"
54
+ else
55
+ puts "Repair failed: #{result.error_message}"
56
+ end
57
+ ----
58
+
59
+ == Creating PAR2 Protection
60
+
61
+ === Basic Creation
62
+
63
+ [source,ruby]
64
+ ----
65
+ # Protect single file
66
+ Omnizip::Parity.create('backup.7z', redundancy: 10)
67
+
68
+ # Protect multiple files with pattern
69
+ Omnizip::Parity.create('data/*.dat', redundancy: 15)
70
+
71
+ # Custom block size
72
+ Omnizip::Parity.create('large.zip',
73
+ redundancy: 10,
74
+ block_size: 32768 # 32KB blocks
75
+ )
76
+ ----
77
+
78
+ === With Progress Tracking
79
+
80
+ [source,ruby]
81
+ ----
82
+ # Track PAR2 creation progress
83
+ Omnizip::Parity.create('archive.7z',
84
+ redundancy: 10,
85
+ progress: ->(pct, msg) do
86
+ puts "[#{pct}%] #{msg}"
87
+ end
88
+ )
89
+
90
+ # Output:
91
+ # [0%] Initializing PAR2 creation
92
+ # [10%] Generating recovery blocks (this may take a while)
93
+ # [60%] Writing recovery volume files
94
+ # [90%] Finalizing recovery volumes
95
+ # [100%] PAR2 creation complete
96
+ ----
97
+
98
+ === Custom Output Location
99
+
100
+ [source,ruby]
101
+ ----
102
+ # Save PAR2 files to different directory
103
+ Omnizip::Parity.create('data/backup.zip',
104
+ redundancy: 10,
105
+ output_dir: 'recovery/'
106
+ )
107
+ # Creates: recovery/backup.par2, recovery/backup.vol*.par2
108
+ ----
109
+
110
+ == Verifying Files
111
+
112
+ === Basic Verification
113
+
114
+ [source,ruby]
115
+ ----
116
+ result = Omnizip::Parity.verify('backup.par2')
117
+
118
+ # Check overall status
119
+ result.all_ok? # => true if no damage
120
+ result.repairable? # => true if can be repaired
121
+
122
+ # Detailed information
123
+ result.damaged_files # => ['file1.txt']
124
+ result.damaged_blocks # => [5, 12, 18]
125
+ result.missing_files # => []
126
+ result.total_blocks # => 100
127
+ result.recovery_blocks # => 10
128
+ result.damage_count # => 3
129
+ ----
130
+
131
+ === Verification Details
132
+
133
+ [source,ruby]
134
+ ----
135
+ result = Omnizip::Parity.verify('backup.par2')
136
+
137
+ if result.damaged_files.any?
138
+ puts "Damaged files:"
139
+ result.damaged_files.each { |f| puts " - #{f}" }
140
+ puts "\nDamaged blocks: #{result.damaged_blocks.size}"
141
+ end
142
+
143
+ if result.missing_files.any?
144
+ puts "Missing files:"
145
+ result.missing_files.each { |f| puts " - #{f}" }
146
+ end
147
+
148
+ if result.repairable?
149
+ puts "\n✓ Can repair with #{result.recovery_blocks} recovery blocks"
150
+ else
151
+ puts "\n✗ Cannot repair: need #{result.damage_count} blocks, " \
152
+ "have #{result.recovery_blocks}"
153
+ end
154
+ ----
155
+
156
+ == Repairing Files
157
+
158
+ === Basic Repair
159
+
160
+ [source,ruby]
161
+ ----
162
+ # Repair damaged files in place
163
+ result = Omnizip::Parity.repair('backup.par2')
164
+
165
+ if result.success?
166
+ puts "Successfully recovered:"
167
+ result.recovered_files.each { |f| puts " - #{f}" }
168
+ puts "Recovered #{result.recovered_blocks} blocks"
169
+ else
170
+ puts "Repair failed: #{result.error_message}"
171
+
172
+ if result.has_unrecoverable?
173
+ puts "Unrecoverable files:"
174
+ result.unrecoverable.each { |f| puts " - #{f}" }
175
+ end
176
+ end
177
+ ----
178
+
179
+ === Repair with Progress
180
+
181
+ [source,ruby]
182
+ ----
183
+ # Track repair progress
184
+ result = Omnizip::Parity.repair('large.par2',
185
+ progress: ->(pct, msg) do
186
+ puts "[#{pct}%] #{msg}"
187
+ end
188
+ )
189
+
190
+ # Output:
191
+ # [0%] Verifying files
192
+ # [10%] Loading recovery blocks
193
+ # [30%] Calculating repairs
194
+ # [50%] Recovering damaged blocks
195
+ # [80%] Writing repaired files
196
+ # [100%] Repair complete
197
+ ----
198
+
199
+ === Repair to Different Location
200
+
201
+ [source,ruby]
202
+ ----
203
+ # Repair files to separate directory
204
+ result = Omnizip::Parity.repair('backup.par2',
205
+ output_dir: 'repaired/'
206
+ )
207
+
208
+ # Original damaged files remain untouched
209
+ # Repaired files written to repaired/
210
+ ----
211
+
212
+ == Checking Protection Status
213
+
214
+ === Quick Check
215
+
216
+ [source,ruby]
217
+ ----
218
+ # Check if file has PAR2 protection
219
+ if Omnizip::Parity.protected?('backup.zip')
220
+ puts "File is protected by PAR2"
221
+ else
222
+ puts "No PAR2 protection found"
223
+ end
224
+ ----
225
+
226
+ === Detailed Information
227
+
228
+ [source,ruby]
229
+ ----
230
+ # Get PAR2 protection details
231
+ info = Omnizip::Parity.info('backup.zip')
232
+
233
+ if info
234
+ puts "PAR2 Protection Information:"
235
+ puts " PAR2 file: #{info[:par2_file]}"
236
+ puts " Block size: #{info[:block_size]} bytes"
237
+ puts " Total blocks: #{info[:total_blocks]}"
238
+ puts " Recovery blocks: #{info[:recovery_blocks]}"
239
+ puts " Redundancy: #{info[:redundancy]}%"
240
+ puts " Protected files: #{info[:file_count]}"
241
+ else
242
+ puts "No PAR2 protection found"
243
+ end
244
+ ----
245
+
246
+ == Best Practices
247
+
248
+ === Redundancy Guidelines
249
+
250
+ [cols="20,30,50",options="header"]
251
+ |===
252
+ |Redundancy |Speed |Use Case
253
+
254
+ |**5%**
255
+ |Fast
256
+ |Minimal protection, quick creation
257
+
258
+ |**10%**
259
+ |Good
260
+ |Balanced protection (recommended)
261
+
262
+ |**15-20%**
263
+ |Slower
264
+ |High redundancy for critical data
265
+
266
+ |**25%+**
267
+ |Slowest
268
+ |Maximum protection, important archives
269
+ |===
270
+
271
+ === Block Size Guidelines
272
+
273
+ [cols="20,30,50",options="header"]
274
+ |===
275
+ |Block Size |File Size |Notes
276
+
277
+ |**16KB**
278
+ |< 100MB
279
+ |Default, good for most files
280
+
281
+ |**32KB**
282
+ |100MB - 1GB
283
+ |Better for medium files
284
+
285
+ |**64KB**
286
+ |> 1GB
287
+ |Optimal for very large files
288
+ |===
289
+
290
+ === Recommended Workflows
291
+
292
+ ==== Workflow 1: Backup with Protection
293
+
294
+ [source,ruby]
295
+ ----
296
+ def protected_backup(files, archive_path)
297
+ # Step 1: Create compressed archive
298
+ Omnizip::Formats::SevenZip::Writer.new(archive_path,
299
+ algorithm: :lzma2,
300
+ level: 9
301
+ ) do |zip|
302
+ files.each { |f| zip.add_file(f) }
303
+ end
304
+
305
+ # Step 2: Add PAR2 protection
306
+ Omnizip::Parity.create(archive_path,
307
+ redundancy: 10,
308
+ progress: ->(pct, msg) { puts "#{pct}%: #{msg}" }
309
+ )
310
+
311
+ puts "✓ Backup created with 10% PAR2 protection"
312
+ end
313
+
314
+ files = Dir.glob('important_data/**/*').select { |f| File.file?(f) }
315
+ protected_backup(files, 'backup.7z')
316
+ ----
317
+
318
+ ==== Workflow 2: Verify Before Extract
319
+
320
+ [source,ruby]
321
+ ----
322
+ def safe_extract(archive_path, output_dir)
323
+ par2_file = archive_path.sub(/\.\w+$/, '.par2')
324
+
325
+ # Check if PAR2 protection exists
326
+ if File.exist?(par2_file)
327
+ puts "Verifying archive integrity..."
328
+ result = Omnizip::Parity.verify(par2_file)
329
+
330
+ unless result.all_ok?
331
+ if result.repairable?
332
+ puts "Archive damaged, attempting repair..."
333
+ repair_result = Omnizip::Parity.repair(par2_file)
334
+
335
+ unless repair_result.success?
336
+ raise "Repair failed: #{repair_result.error_message}"
337
+ end
338
+
339
+ puts "✓ Archive repaired successfully"
340
+ else
341
+ raise "Archive is corrupted beyond repair"
342
+ end
343
+ else
344
+ puts "✓ Archive integrity verified"
345
+ end
346
+ end
347
+
348
+ # Extract archive
349
+ Omnizip::Formats::SevenZip::Reader.new(archive_path) do |zip|
350
+ zip.extract_all(output_dir)
351
+ end
352
+
353
+ puts "✓ Extraction complete"
354
+ end
355
+
356
+ safe_extract('backup.7z', 'restored/')
357
+ ----
358
+
359
+ ==== Workflow 3: Incremental Backups
360
+
361
+ [source,ruby]
362
+ ----
363
+ def incremental_backup_with_parity(source_dir, backup_dir)
364
+ timestamp = Time.now.strftime('%Y%m%d_%H%M%S')
365
+ archive_name = "backup_#{timestamp}.7z"
366
+ archive_path = File.join(backup_dir, archive_name)
367
+
368
+ FileUtils.mkdir_p(backup_dir)
369
+
370
+ # Create archive
371
+ puts "Creating archive: #{archive_name}"
372
+ Omnizip::Formats::SevenZip::Writer.new(archive_path,
373
+ algorithm: :lzma2,
374
+ level: 7
375
+ ) do |zip|
376
+ Dir.glob("#{source_dir}/**/*").each do |file|
377
+ next if File.directory?(file)
378
+ relative_path = file.sub("#{source_dir}/", '')
379
+ zip.add_file(file, archive_path: relative_path)
380
+ end
381
+ end
382
+
383
+ # Add PAR2 protection
384
+ puts "Adding PAR2 protection..."
385
+ Omnizip::Parity.create(archive_path,
386
+ redundancy: 10,
387
+ output_dir: backup_dir
388
+ )
389
+
390
+ # Verify immediately
391
+ par2_file = File.join(backup_dir, "#{archive_name.sub('.7z', '')}.par2")
392
+ verify_result = Omnizip::Parity.verify(par2_file)
393
+
394
+ if verify_result.all_ok?
395
+ puts "✓ Backup complete and verified"
396
+ else
397
+ puts "⚠️ Warning: Verification failed immediately after creation!"
398
+ end
399
+ end
400
+
401
+ incremental_backup_with_parity('my_project/', 'backups/')
402
+ ----
403
+
404
+ == Error Recovery Examples
405
+
406
+ === Example 1: Automatic Corruption Detection
407
+
408
+ [source,ruby]
409
+ ----
410
+ def monitor_archive_health(archive_path)
411
+ return unless Omnizip::Parity.protected?(archive_path)
412
+
413
+ par2_file = archive_path.sub(/\.\w+$/, '.par2')
414
+ result = Omnizip::Parity.verify(par2_file)
415
+
416
+ status = if result.all_ok?
417
+ "✓ HEALTHY"
418
+ elsif result.repairable?
419
+ "⚠️ DAMAGED (repairable)"
420
+ else
421
+ "✗ CORRUPTED (unrecoverable)"
422
+ end
423
+
424
+ puts "#{File.basename(archive_path)}: #{status}"
425
+
426
+ if result.damaged_blocks.any?
427
+ puts " Damaged blocks: #{result.damaged_blocks.size}"
428
+ puts " Recovery blocks: #{result.recovery_blocks}"
429
+ end
430
+ end
431
+
432
+ # Monitor all archives in backup directory
433
+ Dir.glob('backups/*.{7z,zip}').each do |archive|
434
+ monitor_archive_health(archive)
435
+ end
436
+ ----
437
+
438
+ === Example 2: Batch Repair
439
+
440
+ [source,ruby]
441
+ ----
442
+ def batch_repair_archives(backup_dir)
443
+ par2_files = Dir.glob("#{backup_dir}/*.par2")
444
+
445
+ results = {
446
+ verified: [],
447
+ repaired: [],
448
+ failed: []
449
+ }
450
+
451
+ par2_files.each do |par2_file|
452
+ archive_name = File.basename(par2_file, '.par2')
453
+
454
+ result = Omnizip::Parity.verify(par2_file)
455
+
456
+ if result.all_ok?
457
+ results[:verified] << archive_name
458
+ elsif result.repairable?
459
+ repair_result = Omnizip::Parity.repair(par2_file)
460
+
461
+ if repair_result.success?
462
+ results[:repaired] << archive_name
463
+ else
464
+ results[:failed] << archive_name
465
+ end
466
+ else
467
+ results[:failed] << archive_name
468
+ end
469
+ end
470
+
471
+ # Print summary
472
+ puts "\n=== Repair Summary ==="
473
+ puts "Verified OK: #{results[:verified].size}"
474
+ puts "Repaired: #{results[:repaired].size}"
475
+ puts "Failed: #{results[:failed].size}"
476
+
477
+ results[:repaired].each { |name| puts " ✓ #{name}" }
478
+ results[:failed].each { |name| puts " ✗ #{name}" }
479
+ end
480
+
481
+ batch_repair_archives('backups/')
482
+ ----
483
+
484
+ == Technical Details
485
+
486
+ === PAR2 File Structure
487
+
488
+ PAR2 creates multiple files:
489
+
490
+ [source]
491
+ ----
492
+ backup.par2 # Index file with file descriptions
493
+ backup.vol00+01.par2 # 1 recovery block
494
+ backup.vol01+02.par2 # 2 recovery blocks
495
+ backup.vol03+04.par2 # 4 recovery blocks
496
+ backup.vol07+08.par2 # 8 recovery blocks
497
+ ----
498
+
499
+ Volume distribution follows powers of 2 for efficient recovery.
500
+
501
+ === Reed-Solomon Error Correction
502
+
503
+ PAR2 uses Reed-Solomon codes over GF(2^16):
504
+
505
+ * **Systematic Codes** - Data blocks stored unchanged
506
+ * **Parity Blocks** - Generated using Galois field mathematics
507
+ * **Erasure Decoding** - Recover up to N missing blocks with N parity blocks
508
+ * **Error Detection** - Identify corrupted blocks via MD5 checksums
509
+
510
+ === Block-level Processing
511
+
512
+ Files are divided into fixed-size blocks:
513
+
514
+ [source]
515
+ ----
516
+ File (160KB) with 16KB blocks:
517
+ ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
518
+ │ B0 │ B1 │ B2 │ B3 │ B4 │ B5 │ B6 │ B7 │ B8 │ B9 │
519
+ └─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
520
+ ↓ Reed-Solomon Encoding
521
+ ┌─────┬─────┐
522
+ │ P0 │ P1 │ ← Parity blocks (10% redundancy = 1 block)
523
+ └─────┴─────┘
524
+
525
+ Can recover any 1 missing or corrupted block
526
+ ----
527
+
528
+ === Performance Characteristics
529
+
530
+ [cols="30,30,40",options="header"]
531
+ |===
532
+ |Operation |Speed |Notes
533
+
534
+ |**Create 5%**
535
+ |Moderate
536
+ |~2-3 minutes per GB
537
+
538
+ |**Create 10%**
539
+ |Slow
540
+ |~4-6 minutes per GB
541
+
542
+ |**Create 20%**
543
+ |Very Slow
544
+ |~10-15 minutes per GB
545
+
546
+ |**Verify**
547
+ |Fast
548
+ |~30 seconds per GB
549
+
550
+ |**Repair**
551
+ |Moderate
552
+ |Depends on damage extent
553
+ |===
554
+
555
+ ## Command-Line Usage
556
+
557
+ === Create PAR2
558
+
559
+ [source,bash]
560
+ ----
561
+ # Create with default 5% redundancy
562
+ $ omnizip parity create backup.7z
563
+
564
+ # Custom redundancy
565
+ $ omnizip parity create --redundancy 10 backup.7z
566
+
567
+ # Multiple files
568
+ $ omnizip parity create --redundancy 5 data/*.dat
569
+
570
+ # With custom block size
571
+ $ omnizip parity create --block-size 32768 large.zip
572
+ ----
573
+
574
+ === Verify PAR2
575
+
576
+ [source,bash]
577
+ ----
578
+ # Verify archive integrity
579
+ $ omnizip parity verify backup.par2
580
+
581
+ # Output:
582
+ # Verifying backup.par2...
583
+ # ✓ All files intact
584
+ # Total blocks: 100
585
+ # Recovery blocks available: 10
586
+ ----
587
+
588
+ === Repair with PAR2
589
+
590
+ [source,bash]
591
+ ----
592
+ # Repair damaged files
593
+ $ omnizip parity repair backup.par2
594
+
595
+ # Output:
596
+ # Repairing backup.par2...
597
+ # Loading recovery blocks...
598
+ # Recovering damaged blocks...
599
+ # ✓ Repair successful
600
+ # Recovered files: backup.7z
601
+ # Recovered blocks: 3
602
+ ----
603
+
604
+ == See Also
605
+
606
+ * link:archive-formats.adoc[Archive Formats]
607
+ * link:advanced-features.adoc[Advanced Features]
608
+ * link:../README.adoc[Main README]