omnizip 0.4.7-arm-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (632) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +32 -0
  4. data/.rubocop_todo.yml +293 -0
  5. data/CHANGELOG.md +1647 -0
  6. data/CONTEXT.md +68 -0
  7. data/COPYING +502 -0
  8. data/Gemfile +19 -0
  9. data/LICENSE +12 -0
  10. data/README.adoc +1327 -0
  11. data/Rakefile +15 -0
  12. data/TODO.refactor/00-overview.md +67 -0
  13. data/TODO.refactor/01-registry-base-class.md +81 -0
  14. data/TODO.refactor/02-error-hierarchy.md +57 -0
  15. data/TODO.refactor/03-autoload-entry-point.md +69 -0
  16. data/TODO.refactor/04-filter-base-consolidation.md +49 -0
  17. data/TODO.refactor/05-send-private-methods.md +64 -0
  18. data/TODO.refactor/06-instance-variable-access.md +69 -0
  19. data/TODO.refactor/07-respond-to-replacement.md +237 -0
  20. data/TODO.refactor/08-spec-doubles.md +27 -0
  21. data/TODO.refactor/09-cli-shared-module.md +35 -0
  22. data/TODO.refactor/10-format-detector-ocp.md +34 -0
  23. data/TODO.refactor/11-convenience-decoupling.md +38 -0
  24. data/TODO.refactor/12-thread-safety.md +8 -0
  25. data/TODO.refactor/13-lutaml-model-migration.md +158 -0
  26. data/TODO.refactor/14-add-missing-specs.md +25 -0
  27. data/benchmark/README.md +260 -0
  28. data/benchmark/benchmark_suite.rb +125 -0
  29. data/benchmark/compression_bench.rb +181 -0
  30. data/benchmark/filter_bench.rb +180 -0
  31. data/benchmark/models/benchmark_result.rb +59 -0
  32. data/benchmark/models/comparison_result.rb +69 -0
  33. data/benchmark/profile_suite.rb +167 -0
  34. data/benchmark/reporter.rb +150 -0
  35. data/benchmark/run_benchmarks.rb +66 -0
  36. data/benchmark/test_data.rb +137 -0
  37. data/config/formats/rar3_spec.yml +92 -0
  38. data/config/formats/rar5_spec.yml +102 -0
  39. data/docs/.github/workflows/docs.yml +142 -0
  40. data/docs/.gitignore +21 -0
  41. data/docs/.lychee.toml +67 -0
  42. data/docs/Gemfile +13 -0
  43. data/docs/RAR_WRITE_SUPPORT.md +26 -0
  44. data/docs/README.md +101 -0
  45. data/docs/_config.yml +112 -0
  46. data/docs/assets/logo.svg +1 -0
  47. data/docs/assets/omnizip-logo.pdf +1540 -11
  48. data/docs/comparison/feature-matrix.adoc +694 -0
  49. data/docs/comparison/index.adoc +113 -0
  50. data/docs/comparison/vs-7zip.adoc +309 -0
  51. data/docs/comparison/vs-peazip.adoc +77 -0
  52. data/docs/comparison/vs-rubyzip.adoc +342 -0
  53. data/docs/comparison/vs-winrar.adoc +100 -0
  54. data/docs/compatibility.adoc +579 -0
  55. data/docs/concepts/index.adoc +129 -0
  56. data/docs/developer/architecture.adoc +256 -0
  57. data/docs/developer/contributing.adoc +158 -0
  58. data/docs/developer/index.adoc +25 -0
  59. data/docs/developer/testing.adoc +212 -0
  60. data/docs/getting-started/basic-usage.adoc +263 -0
  61. data/docs/getting-started/index.adoc +42 -0
  62. data/docs/getting-started/installation.adoc +138 -0
  63. data/docs/getting-started/quick-start.adoc +183 -0
  64. data/docs/getting-started/your-first-archive.adoc +219 -0
  65. data/docs/guides/advanced-features/encryption.adoc +277 -0
  66. data/docs/guides/advanced-features/index.adoc +59 -0
  67. data/docs/guides/advanced-features/parallel-processing.adoc +144 -0
  68. data/docs/guides/advanced-features/progress-tracking.adoc +124 -0
  69. data/docs/guides/advanced-features/streaming.adoc +142 -0
  70. data/docs/guides/archive-formats/gzip-format.adoc +105 -0
  71. data/docs/guides/archive-formats/index.adoc +160 -0
  72. data/docs/guides/archive-formats/ole-format.adoc +151 -0
  73. data/docs/guides/archive-formats/rar-format.adoc +104 -0
  74. data/docs/guides/archive-formats/rar5.adoc +521 -0
  75. data/docs/guides/archive-formats/rpm-format.adoc +108 -0
  76. data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
  77. data/docs/guides/archive-formats/tar-format.adoc +106 -0
  78. data/docs/guides/archive-formats/xz-format.adoc +118 -0
  79. data/docs/guides/archive-formats/zip-format.adoc +35 -0
  80. data/docs/guides/compression-algorithms/bzip2.adoc +114 -0
  81. data/docs/guides/compression-algorithms/deflate.adoc +313 -0
  82. data/docs/guides/compression-algorithms/index.adoc +190 -0
  83. data/docs/guides/compression-algorithms/lzma.adoc +394 -0
  84. data/docs/guides/compression-algorithms/lzma2.adoc +244 -0
  85. data/docs/guides/compression-algorithms/ppmd.adoc +313 -0
  86. data/docs/guides/compression-algorithms/zstandard.adoc +296 -0
  87. data/docs/guides/creating-archives.adoc +348 -0
  88. data/docs/guides/extracting-archives.adoc +53 -0
  89. data/docs/guides/format-conversion.adoc +64 -0
  90. data/docs/guides/index.adoc +49 -0
  91. data/docs/guides/migration-rubyzip.adoc +217 -0
  92. data/docs/guides/parity-archives.adoc +605 -0
  93. data/docs/guides/performance-tuning.adoc +88 -0
  94. data/docs/index.adoc +228 -0
  95. data/docs/lychee.toml +67 -0
  96. data/docs/reference/api/overview.adoc +187 -0
  97. data/docs/reference/cli/compress-command.adoc +114 -0
  98. data/docs/reference/cli/overview.adoc +140 -0
  99. data/docs/reference/index.adoc +26 -0
  100. data/docs/resources/faq.adoc +185 -0
  101. data/docs/resources/quick-reference.adoc +222 -0
  102. data/docs/rust-backend.md +0 -0
  103. data/docs/troubleshooting/index.adoc +207 -0
  104. data/docs/xar_format.md +216 -0
  105. data/examples/api_comparison.rb +205 -0
  106. data/examples/deflate64_example.rb +96 -0
  107. data/examples/par2_demo.rb +121 -0
  108. data/examples/quick_start_native.rb +150 -0
  109. data/examples/quick_start_rubyzip.rb +115 -0
  110. data/examples/rubyzip_compatibility_demo.rb +194 -0
  111. data/exe/omnizip +27 -0
  112. data/lib/omnizip/algorithm.rb +176 -0
  113. data/lib/omnizip/algorithm_registry.rb +65 -0
  114. data/lib/omnizip/algorithms/.keep +0 -0
  115. data/lib/omnizip/algorithms/bzip2/bwt.rb +236 -0
  116. data/lib/omnizip/algorithms/bzip2/bz2.rb +687 -0
  117. data/lib/omnizip/algorithms/bzip2/rle.rb +146 -0
  118. data/lib/omnizip/algorithms/bzip2.rb +108 -0
  119. data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
  120. data/lib/omnizip/algorithms/deflate/decoder.rb +37 -0
  121. data/lib/omnizip/algorithms/deflate/encoder.rb +45 -0
  122. data/lib/omnizip/algorithms/deflate.rb +135 -0
  123. data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
  124. data/lib/omnizip/algorithms/deflate64/decoder.rb +151 -0
  125. data/lib/omnizip/algorithms/deflate64/encoder.rb +95 -0
  126. data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +352 -0
  127. data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +140 -0
  128. data/lib/omnizip/algorithms/deflate64.rb +118 -0
  129. data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
  130. data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
  131. data/lib/omnizip/algorithms/lzma/decoder.rb +146 -0
  132. data/lib/omnizip/algorithms/lzma/dictionary.rb +70 -0
  133. data/lib/omnizip/algorithms/lzma/distance_coder.rb +326 -0
  134. data/lib/omnizip/algorithms/lzma/encoder.rb +139 -0
  135. data/lib/omnizip/algorithms/lzma/length_coder.rb +172 -0
  136. data/lib/omnizip/algorithms/lzma/literal_decoder.rb +204 -0
  137. data/lib/omnizip/algorithms/lzma/literal_encoder.rb +208 -0
  138. data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +368 -0
  139. data/lib/omnizip/algorithms/lzma/lzma1_encoder.rb +105 -0
  140. data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +194 -0
  141. data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
  142. data/lib/omnizip/algorithms/lzma/match.rb +32 -0
  143. data/lib/omnizip/algorithms/lzma/match_finder.rb +233 -0
  144. data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
  145. data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +84 -0
  146. data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +159 -0
  147. data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
  148. data/lib/omnizip/algorithms/lzma/range_coder.rb +82 -0
  149. data/lib/omnizip/algorithms/lzma/range_decoder.rb +274 -0
  150. data/lib/omnizip/algorithms/lzma/range_encoder.rb +202 -0
  151. data/lib/omnizip/algorithms/lzma/state.rb +127 -0
  152. data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +323 -0
  153. data/lib/omnizip/algorithms/lzma/xz_encoder.rb +420 -0
  154. data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +640 -0
  155. data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +224 -0
  156. data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +167 -0
  157. data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +258 -0
  158. data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
  159. data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +314 -0
  160. data/lib/omnizip/algorithms/lzma/xz_state.rb +108 -0
  161. data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +1311 -0
  162. data/lib/omnizip/algorithms/lzma.rb +266 -0
  163. data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +180 -0
  164. data/lib/omnizip/algorithms/lzma2/constants.rb +38 -0
  165. data/lib/omnizip/algorithms/lzma2/encoder.rb +145 -0
  166. data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +165 -0
  167. data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
  168. data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +122 -0
  169. data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
  170. data/lib/omnizip/algorithms/lzma2.rb +133 -0
  171. data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
  172. data/lib/omnizip/algorithms/ppmd7/context.rb +151 -0
  173. data/lib/omnizip/algorithms/ppmd7/decoder.rb +127 -0
  174. data/lib/omnizip/algorithms/ppmd7/encoder.rb +153 -0
  175. data/lib/omnizip/algorithms/ppmd7/model.rb +245 -0
  176. data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
  177. data/lib/omnizip/algorithms/ppmd7.rb +146 -0
  178. data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
  179. data/lib/omnizip/algorithms/ppmd8/context.rb +32 -0
  180. data/lib/omnizip/algorithms/ppmd8/decoder.rb +104 -0
  181. data/lib/omnizip/algorithms/ppmd8/encoder.rb +135 -0
  182. data/lib/omnizip/algorithms/ppmd8/model.rb +246 -0
  183. data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
  184. data/lib/omnizip/algorithms/ppmd8.rb +122 -0
  185. data/lib/omnizip/algorithms/ppmd_base.rb +142 -0
  186. data/lib/omnizip/algorithms/registration.rb +28 -0
  187. data/lib/omnizip/algorithms/zstandard/constants.rb +158 -0
  188. data/lib/omnizip/algorithms/zstandard/decoder.rb +249 -0
  189. data/lib/omnizip/algorithms/zstandard/dictionary.rb +73 -0
  190. data/lib/omnizip/algorithms/zstandard/encoder.rb +294 -0
  191. data/lib/omnizip/algorithms/zstandard/frame/block.rb +143 -0
  192. data/lib/omnizip/algorithms/zstandard/frame/header.rb +233 -0
  193. data/lib/omnizip/algorithms/zstandard/frame.rb +33 -0
  194. data/lib/omnizip/algorithms/zstandard/fse/bitstream.rb +183 -0
  195. data/lib/omnizip/algorithms/zstandard/fse/encoder.rb +534 -0
  196. data/lib/omnizip/algorithms/zstandard/fse/interleaved.rb +92 -0
  197. data/lib/omnizip/algorithms/zstandard/fse/table.rb +188 -0
  198. data/lib/omnizip/algorithms/zstandard/fse/table_description.rb +203 -0
  199. data/lib/omnizip/algorithms/zstandard/fse.rb +53 -0
  200. data/lib/omnizip/algorithms/zstandard/huffman.rb +276 -0
  201. data/lib/omnizip/algorithms/zstandard/huffman_encoder.rb +327 -0
  202. data/lib/omnizip/algorithms/zstandard/ldm.rb +121 -0
  203. data/lib/omnizip/algorithms/zstandard/literals.rb +241 -0
  204. data/lib/omnizip/algorithms/zstandard/literals_encoder.rb +96 -0
  205. data/lib/omnizip/algorithms/zstandard/match_finder.rb +483 -0
  206. data/lib/omnizip/algorithms/zstandard/sequences.rb +350 -0
  207. data/lib/omnizip/algorithms/zstandard/sequences_encoder.rb +333 -0
  208. data/lib/omnizip/algorithms/zstandard/xxhash.rb +159 -0
  209. data/lib/omnizip/algorithms/zstandard.rb +210 -0
  210. data/lib/omnizip/algorithms.rb +35 -0
  211. data/lib/omnizip/archive/builder.rb +48 -0
  212. data/lib/omnizip/archive/reader_session.rb +67 -0
  213. data/lib/omnizip/archive.rb +86 -0
  214. data/lib/omnizip/archive_handler.rb +82 -0
  215. data/lib/omnizip/archive_handlers/cpio_handler.rb +47 -0
  216. data/lib/omnizip/archive_handlers/iso_handler.rb +54 -0
  217. data/lib/omnizip/archive_handlers/ole_handler.rb +37 -0
  218. data/lib/omnizip/archive_handlers/rar_handler.rb +96 -0
  219. data/lib/omnizip/archive_handlers/rpm_handler.rb +45 -0
  220. data/lib/omnizip/archive_handlers/seven_zip_handler.rb +89 -0
  221. data/lib/omnizip/archive_handlers/tar_handler.rb +75 -0
  222. data/lib/omnizip/archive_handlers/xar_handler.rb +49 -0
  223. data/lib/omnizip/archive_handlers/zip_handler.rb +115 -0
  224. data/lib/omnizip/archive_handlers.rb +18 -0
  225. data/lib/omnizip/backends.rb +160 -0
  226. data/lib/omnizip/buffer/memory_archive.rb +246 -0
  227. data/lib/omnizip/buffer/memory_extractor.rb +234 -0
  228. data/lib/omnizip/buffer/seven_zip_bridge.rb +171 -0
  229. data/lib/omnizip/buffer.rb +187 -0
  230. data/lib/omnizip/checksum_registry.rb +41 -0
  231. data/lib/omnizip/checksums/crc32.rb +101 -0
  232. data/lib/omnizip/checksums/crc64.rb +102 -0
  233. data/lib/omnizip/checksums/crc_base.rb +158 -0
  234. data/lib/omnizip/checksums/registration.rb +16 -0
  235. data/lib/omnizip/checksums/verifier.rb +130 -0
  236. data/lib/omnizip/checksums.rb +11 -0
  237. data/lib/omnizip/chunked/memory_manager.rb +194 -0
  238. data/lib/omnizip/chunked/reader.rb +78 -0
  239. data/lib/omnizip/chunked/writer.rb +123 -0
  240. data/lib/omnizip/chunked.rb +123 -0
  241. data/lib/omnizip/cli/output_formatter.rb +112 -0
  242. data/lib/omnizip/cli.rb +604 -0
  243. data/lib/omnizip/commands/.keep +0 -0
  244. data/lib/omnizip/commands/archive_create_command.rb +245 -0
  245. data/lib/omnizip/commands/archive_extract_command.rb +231 -0
  246. data/lib/omnizip/commands/archive_list_command.rb +204 -0
  247. data/lib/omnizip/commands/archive_repair_command.rb +129 -0
  248. data/lib/omnizip/commands/archive_verify_command.rb +115 -0
  249. data/lib/omnizip/commands/compress_command.rb +115 -0
  250. data/lib/omnizip/commands/decompress_command.rb +149 -0
  251. data/lib/omnizip/commands/list_command.rb +51 -0
  252. data/lib/omnizip/commands/metadata_command.rb +215 -0
  253. data/lib/omnizip/commands/parity_create_command.rb +114 -0
  254. data/lib/omnizip/commands/parity_repair_command.rb +120 -0
  255. data/lib/omnizip/commands/parity_verify_command.rb +122 -0
  256. data/lib/omnizip/commands/profile_list_command.rb +54 -0
  257. data/lib/omnizip/commands/profile_show_command.rb +44 -0
  258. data/lib/omnizip/commands.rb +21 -0
  259. data/lib/omnizip/convenience.rb +389 -0
  260. data/lib/omnizip/converter/conversion_registry.rb +50 -0
  261. data/lib/omnizip/converter/conversion_strategy.rb +108 -0
  262. data/lib/omnizip/converter/extract_repack_strategy.rb +51 -0
  263. data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +43 -0
  264. data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +54 -0
  265. data/lib/omnizip/converter.rb +124 -0
  266. data/lib/omnizip/crypto/aes256/cipher.rb +104 -0
  267. data/lib/omnizip/crypto/aes256/constants.rb +28 -0
  268. data/lib/omnizip/crypto/aes256/key_derivation.rb +100 -0
  269. data/lib/omnizip/crypto/aes256.rb +102 -0
  270. data/lib/omnizip/crypto.rb +11 -0
  271. data/lib/omnizip/entry.rb +44 -0
  272. data/lib/omnizip/error.rb +110 -0
  273. data/lib/omnizip/eta/exponential_smoothing_estimator.rb +95 -0
  274. data/lib/omnizip/eta/moving_average_estimator.rb +96 -0
  275. data/lib/omnizip/eta/rate_calculator.rb +104 -0
  276. data/lib/omnizip/eta/sample_history.rb +143 -0
  277. data/lib/omnizip/eta/time_estimator.rb +106 -0
  278. data/lib/omnizip/eta.rb +68 -0
  279. data/lib/omnizip/extraction/filter_chain.rb +179 -0
  280. data/lib/omnizip/extraction/glob_pattern.rb +140 -0
  281. data/lib/omnizip/extraction/pattern_matcher.rb +66 -0
  282. data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
  283. data/lib/omnizip/extraction/regex_pattern.rb +50 -0
  284. data/lib/omnizip/extraction/selective_extractor.rb +247 -0
  285. data/lib/omnizip/extraction.rb +115 -0
  286. data/lib/omnizip/file_type/mime_classifier.rb +144 -0
  287. data/lib/omnizip/file_type.rb +117 -0
  288. data/lib/omnizip/filter.rb +141 -0
  289. data/lib/omnizip/filter_pipeline.rb +108 -0
  290. data/lib/omnizip/filter_registry.rb +113 -0
  291. data/lib/omnizip/filters/bcj.rb +277 -0
  292. data/lib/omnizip/filters/bcj2/constants.rb +53 -0
  293. data/lib/omnizip/filters/bcj2/decoder.rb +263 -0
  294. data/lib/omnizip/filters/bcj2/encoder.rb +58 -0
  295. data/lib/omnizip/filters/bcj2/stream_data.rb +91 -0
  296. data/lib/omnizip/filters/bcj2.rb +93 -0
  297. data/lib/omnizip/filters/bcj_arm.rb +174 -0
  298. data/lib/omnizip/filters/bcj_arm64.rb +242 -0
  299. data/lib/omnizip/filters/bcj_ia64.rb +194 -0
  300. data/lib/omnizip/filters/bcj_ppc.rb +188 -0
  301. data/lib/omnizip/filters/bcj_sparc.rb +174 -0
  302. data/lib/omnizip/filters/bcj_x86.rb +191 -0
  303. data/lib/omnizip/filters/delta.rb +195 -0
  304. data/lib/omnizip/filters/xz_delta.rb +258 -0
  305. data/lib/omnizip/filters.rb +20 -0
  306. data/lib/omnizip/format_detector.rb +166 -0
  307. data/lib/omnizip/formats/.keep +0 -0
  308. data/lib/omnizip/formats/bzip2_file.rb +159 -0
  309. data/lib/omnizip/formats/cpio/bounded_io.rb +66 -0
  310. data/lib/omnizip/formats/cpio/constants.rb +55 -0
  311. data/lib/omnizip/formats/cpio/entry.rb +389 -0
  312. data/lib/omnizip/formats/cpio/reader.rb +194 -0
  313. data/lib/omnizip/formats/cpio/writer.rb +232 -0
  314. data/lib/omnizip/formats/cpio.rb +132 -0
  315. data/lib/omnizip/formats/format_spec_loader.rb +228 -0
  316. data/lib/omnizip/formats/gzip.rb +236 -0
  317. data/lib/omnizip/formats/iso/directory_builder.rb +321 -0
  318. data/lib/omnizip/formats/iso/directory_record.rb +162 -0
  319. data/lib/omnizip/formats/iso/joliet.rb +204 -0
  320. data/lib/omnizip/formats/iso/path_table.rb +125 -0
  321. data/lib/omnizip/formats/iso/reader.rb +194 -0
  322. data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
  323. data/lib/omnizip/formats/iso/volume_builder.rb +319 -0
  324. data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
  325. data/lib/omnizip/formats/iso/writer.rb +543 -0
  326. data/lib/omnizip/formats/iso.rb +133 -0
  327. data/lib/omnizip/formats/lzip.rb +161 -0
  328. data/lib/omnizip/formats/lzma_alone.rb +149 -0
  329. data/lib/omnizip/formats/msi/cab_extractor.rb +181 -0
  330. data/lib/omnizip/formats/msi/constants.rb +157 -0
  331. data/lib/omnizip/formats/msi/directory_resolver.rb +188 -0
  332. data/lib/omnizip/formats/msi/entry.rb +134 -0
  333. data/lib/omnizip/formats/msi/reader.rb +301 -0
  334. data/lib/omnizip/formats/msi/string_pool.rb +246 -0
  335. data/lib/omnizip/formats/msi/table_parser.rb +244 -0
  336. data/lib/omnizip/formats/msi.rb +73 -0
  337. data/lib/omnizip/formats/ole/allocation_table.rb +263 -0
  338. data/lib/omnizip/formats/ole/constants.rb +61 -0
  339. data/lib/omnizip/formats/ole/dirent.rb +439 -0
  340. data/lib/omnizip/formats/ole/header.rb +199 -0
  341. data/lib/omnizip/formats/ole/ranges_io.rb +347 -0
  342. data/lib/omnizip/formats/ole/storage.rb +482 -0
  343. data/lib/omnizip/formats/ole/types/variant.rb +338 -0
  344. data/lib/omnizip/formats/ole.rb +143 -0
  345. data/lib/omnizip/formats/rar/archive_repairer.rb +240 -0
  346. data/lib/omnizip/formats/rar/archive_verifier.rb +192 -0
  347. data/lib/omnizip/formats/rar/block_parser.rb +282 -0
  348. data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
  349. data/lib/omnizip/formats/rar/compression/dispatcher.rb +210 -0
  350. data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +212 -0
  351. data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +154 -0
  352. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
  353. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
  354. data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
  355. data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
  356. data/lib/omnizip/formats/rar/compression/lz77_huffman.rb +25 -0
  357. data/lib/omnizip/formats/rar/compression/ppmd/context.rb +103 -0
  358. data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +238 -0
  359. data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +250 -0
  360. data/lib/omnizip/formats/rar/compression/ppmd.rb +16 -0
  361. data/lib/omnizip/formats/rar/compression.rb +17 -0
  362. data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
  363. data/lib/omnizip/formats/rar/constants.rb +88 -0
  364. data/lib/omnizip/formats/rar/decompressor.rb +316 -0
  365. data/lib/omnizip/formats/rar/external_writer.rb +311 -0
  366. data/lib/omnizip/formats/rar/header.rb +209 -0
  367. data/lib/omnizip/formats/rar/license_validator.rb +111 -0
  368. data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
  369. data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
  370. data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
  371. data/lib/omnizip/formats/rar/models.rb +14 -0
  372. data/lib/omnizip/formats/rar/parity_handler.rb +299 -0
  373. data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +200 -0
  374. data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +584 -0
  375. data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
  376. data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
  377. data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +96 -0
  378. data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
  379. data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +162 -0
  380. data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
  381. data/lib/omnizip/formats/rar/rar5/header.rb +208 -0
  382. data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
  383. data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
  384. data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
  385. data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
  386. data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
  387. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +260 -0
  388. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
  389. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +176 -0
  390. data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +108 -0
  391. data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +139 -0
  392. data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
  393. data/lib/omnizip/formats/rar/rar5/vint.rb +53 -0
  394. data/lib/omnizip/formats/rar/rar5/writer.rb +540 -0
  395. data/lib/omnizip/formats/rar/rar_format_base.rb +239 -0
  396. data/lib/omnizip/formats/rar/reader.rb +377 -0
  397. data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
  398. data/lib/omnizip/formats/rar/volume_manager.rb +166 -0
  399. data/lib/omnizip/formats/rar/writer.rb +437 -0
  400. data/lib/omnizip/formats/rar.rb +193 -0
  401. data/lib/omnizip/formats/rar3/compressor.rb +71 -0
  402. data/lib/omnizip/formats/rar3/decompressor.rb +64 -0
  403. data/lib/omnizip/formats/rar3/reader.rb +107 -0
  404. data/lib/omnizip/formats/rar3/writer.rb +220 -0
  405. data/lib/omnizip/formats/rar3.rb +15 -0
  406. data/lib/omnizip/formats/rar5/compressor.rb +71 -0
  407. data/lib/omnizip/formats/rar5/decompressor.rb +64 -0
  408. data/lib/omnizip/formats/rar5/reader.rb +130 -0
  409. data/lib/omnizip/formats/rar5/writer.rb +65 -0
  410. data/lib/omnizip/formats/rar5.rb +15 -0
  411. data/lib/omnizip/formats/rpm/constants.rb +58 -0
  412. data/lib/omnizip/formats/rpm/entry.rb +106 -0
  413. data/lib/omnizip/formats/rpm/header.rb +106 -0
  414. data/lib/omnizip/formats/rpm/lead.rb +132 -0
  415. data/lib/omnizip/formats/rpm/tag.rb +228 -0
  416. data/lib/omnizip/formats/rpm/writer.rb +652 -0
  417. data/lib/omnizip/formats/rpm.rb +458 -0
  418. data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +274 -0
  419. data/lib/omnizip/formats/seven_zip/coder_chain.rb +169 -0
  420. data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
  421. data/lib/omnizip/formats/seven_zip/encoded_header.rb +110 -0
  422. data/lib/omnizip/formats/seven_zip/encrypted_header.rb +139 -0
  423. data/lib/omnizip/formats/seven_zip/file_collector.rb +143 -0
  424. data/lib/omnizip/formats/seven_zip/header.rb +102 -0
  425. data/lib/omnizip/formats/seven_zip/header_encryptor.rb +132 -0
  426. data/lib/omnizip/formats/seven_zip/header_writer.rb +425 -0
  427. data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
  428. data/lib/omnizip/formats/seven_zip/models/file_entry.rb +65 -0
  429. data/lib/omnizip/formats/seven_zip/models/folder.rb +67 -0
  430. data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
  431. data/lib/omnizip/formats/seven_zip/models.rb +20 -0
  432. data/lib/omnizip/formats/seven_zip/parser.rb +671 -0
  433. data/lib/omnizip/formats/seven_zip/reader.rb +626 -0
  434. data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +611 -0
  435. data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +308 -0
  436. data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
  437. data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +166 -0
  438. data/lib/omnizip/formats/seven_zip/writer.rb +801 -0
  439. data/lib/omnizip/formats/seven_zip.rb +179 -0
  440. data/lib/omnizip/formats/tar/constants.rb +73 -0
  441. data/lib/omnizip/formats/tar/entry.rb +98 -0
  442. data/lib/omnizip/formats/tar/header.rb +206 -0
  443. data/lib/omnizip/formats/tar/reader.rb +119 -0
  444. data/lib/omnizip/formats/tar/writer.rb +212 -0
  445. data/lib/omnizip/formats/tar.rb +74 -0
  446. data/lib/omnizip/formats/xar/constants.rb +119 -0
  447. data/lib/omnizip/formats/xar/entry.rb +268 -0
  448. data/lib/omnizip/formats/xar/header.rb +223 -0
  449. data/lib/omnizip/formats/xar/reader.rb +400 -0
  450. data/lib/omnizip/formats/xar/toc.rb +570 -0
  451. data/lib/omnizip/formats/xar/writer.rb +461 -0
  452. data/lib/omnizip/formats/xar.rb +145 -0
  453. data/lib/omnizip/formats/xz/reader.rb +121 -0
  454. data/lib/omnizip/formats/xz/writer.rb +416 -0
  455. data/lib/omnizip/formats/xz.rb +210 -0
  456. data/lib/omnizip/formats/xz_const.rb +49 -0
  457. data/lib/omnizip/formats/xz_impl/block_decoder.rb +761 -0
  458. data/lib/omnizip/formats/xz_impl/block_encoder.rb +304 -0
  459. data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
  460. data/lib/omnizip/formats/xz_impl/block_header_parser.rb +182 -0
  461. data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
  462. data/lib/omnizip/formats/xz_impl/index_encoder.rb +120 -0
  463. data/lib/omnizip/formats/xz_impl/stream_decoder.rb +470 -0
  464. data/lib/omnizip/formats/xz_impl/stream_encoder.rb +95 -0
  465. data/lib/omnizip/formats/xz_impl/stream_footer.rb +79 -0
  466. data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +115 -0
  467. data/lib/omnizip/formats/xz_impl/stream_header.rb +53 -0
  468. data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +106 -0
  469. data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
  470. data/lib/omnizip/formats/xz_impl.rb +52 -0
  471. data/lib/omnizip/formats/zip/central_directory_header.rb +223 -0
  472. data/lib/omnizip/formats/zip/constants.rb +69 -0
  473. data/lib/omnizip/formats/zip/end_of_central_directory.rb +132 -0
  474. data/lib/omnizip/formats/zip/local_file_header.rb +136 -0
  475. data/lib/omnizip/formats/zip/reader.rb +376 -0
  476. data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
  477. data/lib/omnizip/formats/zip/writer.rb +489 -0
  478. data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +102 -0
  479. data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +64 -0
  480. data/lib/omnizip/formats/zip/zip64_extra_field.rb +112 -0
  481. data/lib/omnizip/formats/zip.rb +50 -0
  482. data/lib/omnizip/formats.rb +29 -0
  483. data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
  484. data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
  485. data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
  486. data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
  487. data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
  488. data/lib/omnizip/implementations/base.rb +19 -0
  489. data/lib/omnizip/implementations/rust/archive.rb +93 -0
  490. data/lib/omnizip/implementations/rust/library.rb +221 -0
  491. data/lib/omnizip/implementations/rust.rb +26 -0
  492. data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +428 -0
  493. data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +456 -0
  494. data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +285 -0
  495. data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +197 -0
  496. data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +194 -0
  497. data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +139 -0
  498. data/lib/omnizip/implementations/seven_zip/lzma.rb +21 -0
  499. data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +56 -0
  500. data/lib/omnizip/implementations/seven_zip/lzma2.rb +12 -0
  501. data/lib/omnizip/implementations/seven_zip.rb +11 -0
  502. data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +547 -0
  503. data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +748 -0
  504. data/lib/omnizip/implementations/xz_utils/lzma2.rb +13 -0
  505. data/lib/omnizip/implementations/xz_utils.rb +10 -0
  506. data/lib/omnizip/implementations.rb +25 -0
  507. data/lib/omnizip/io/buffered_input.rb +147 -0
  508. data/lib/omnizip/io/buffered_output.rb +106 -0
  509. data/lib/omnizip/io/source.rb +143 -0
  510. data/lib/omnizip/io/stream_manager.rb +117 -0
  511. data/lib/omnizip/io.rb +15 -0
  512. data/lib/omnizip/link_handler/hard_link.rb +79 -0
  513. data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
  514. data/lib/omnizip/link_handler.rb +129 -0
  515. data/lib/omnizip/metadata/archive_metadata.rb +114 -0
  516. data/lib/omnizip/metadata/entry_metadata.rb +153 -0
  517. data/lib/omnizip/metadata/metadata_editor.rb +169 -0
  518. data/lib/omnizip/metadata/metadata_registry.rb +71 -0
  519. data/lib/omnizip/metadata/metadata_validator.rb +101 -0
  520. data/lib/omnizip/metadata.rb +58 -0
  521. data/lib/omnizip/models/.keep +0 -0
  522. data/lib/omnizip/models/algorithm_metadata.rb +41 -0
  523. data/lib/omnizip/models/attribute_apply.rb +40 -0
  524. data/lib/omnizip/models/compression_options.rb +53 -0
  525. data/lib/omnizip/models/conversion_options.rb +79 -0
  526. data/lib/omnizip/models/conversion_result.rb +141 -0
  527. data/lib/omnizip/models/eta_result.rb +45 -0
  528. data/lib/omnizip/models/extraction_rule.rb +115 -0
  529. data/lib/omnizip/models/filter_chain.rb +142 -0
  530. data/lib/omnizip/models/filter_config.rb +148 -0
  531. data/lib/omnizip/models/match_result.rb +141 -0
  532. data/lib/omnizip/models/optimization_suggestion.rb +95 -0
  533. data/lib/omnizip/models/parallel_options.rb +116 -0
  534. data/lib/omnizip/models/performance_result.rb +85 -0
  535. data/lib/omnizip/models/profile_report.rb +116 -0
  536. data/lib/omnizip/models/progress_options.rb +39 -0
  537. data/lib/omnizip/models/split_options.rb +116 -0
  538. data/lib/omnizip/optimization_registry.rb +45 -0
  539. data/lib/omnizip/parallel/engine.rb +52 -0
  540. data/lib/omnizip/parallel/job_queue.rb +209 -0
  541. data/lib/omnizip/parallel/job_scheduler.rb +225 -0
  542. data/lib/omnizip/parallel/parallel_compressor.rb +326 -0
  543. data/lib/omnizip/parallel/parallel_extractor.rb +238 -0
  544. data/lib/omnizip/parallel/thread_pool.rb +60 -0
  545. data/lib/omnizip/parallel/worker_pool.rb +227 -0
  546. data/lib/omnizip/parallel.rb +156 -0
  547. data/lib/omnizip/parity/chunked_block_processor.rb +194 -0
  548. data/lib/omnizip/parity/galois16.rb +145 -0
  549. data/lib/omnizip/parity/models/creator_packet.rb +71 -0
  550. data/lib/omnizip/parity/models/file_description_packet.rb +131 -0
  551. data/lib/omnizip/parity/models/ifsc_packet.rb +111 -0
  552. data/lib/omnizip/parity/models/main_packet.rb +126 -0
  553. data/lib/omnizip/parity/models/packet.rb +156 -0
  554. data/lib/omnizip/parity/models/packet_registry.rb +102 -0
  555. data/lib/omnizip/parity/models/recovery_slice_packet.rb +76 -0
  556. data/lib/omnizip/parity/models.rb +27 -0
  557. data/lib/omnizip/parity/par2_creator.rb +496 -0
  558. data/lib/omnizip/parity/par2_repairer.rb +409 -0
  559. data/lib/omnizip/parity/par2_verifier.rb +373 -0
  560. data/lib/omnizip/parity/par2cmdline_algorithm.rb +108 -0
  561. data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
  562. data/lib/omnizip/parity/reed_solomon_decoder.rb +263 -0
  563. data/lib/omnizip/parity/reed_solomon_encoder.rb +108 -0
  564. data/lib/omnizip/parity/reed_solomon_matrix.rb +339 -0
  565. data/lib/omnizip/parity.rb +207 -0
  566. data/lib/omnizip/password/encryption_registry.rb +26 -0
  567. data/lib/omnizip/password/encryption_strategy.rb +96 -0
  568. data/lib/omnizip/password/password_validator.rb +129 -0
  569. data/lib/omnizip/password/winzip_aes_strategy.rb +190 -0
  570. data/lib/omnizip/password/zip_crypto_strategy.rb +135 -0
  571. data/lib/omnizip/password.rb +88 -0
  572. data/lib/omnizip/pipe/stream_compressor.rb +124 -0
  573. data/lib/omnizip/pipe/stream_decompressor.rb +173 -0
  574. data/lib/omnizip/pipe.rb +120 -0
  575. data/lib/omnizip/platform/ntfs_streams.rb +200 -0
  576. data/lib/omnizip/platform.rb +189 -0
  577. data/lib/omnizip/profile/archive_profile.rb +36 -0
  578. data/lib/omnizip/profile/balanced_profile.rb +31 -0
  579. data/lib/omnizip/profile/binary_profile.rb +33 -0
  580. data/lib/omnizip/profile/compression_profile.rb +157 -0
  581. data/lib/omnizip/profile/custom_profile.rb +155 -0
  582. data/lib/omnizip/profile/fast_profile.rb +31 -0
  583. data/lib/omnizip/profile/maximum_profile.rb +31 -0
  584. data/lib/omnizip/profile/profile_detector.rb +108 -0
  585. data/lib/omnizip/profile/profile_registry.rb +160 -0
  586. data/lib/omnizip/profile/text_profile.rb +33 -0
  587. data/lib/omnizip/profile.rb +261 -0
  588. data/lib/omnizip/profiler/memory_profiler.rb +66 -0
  589. data/lib/omnizip/profiler/method_profiler.rb +49 -0
  590. data/lib/omnizip/profiler/report_generator.rb +158 -0
  591. data/lib/omnizip/profiler.rb +192 -0
  592. data/lib/omnizip/progress/callback_reporter.rb +34 -0
  593. data/lib/omnizip/progress/console_reporter.rb +59 -0
  594. data/lib/omnizip/progress/log_reporter.rb +89 -0
  595. data/lib/omnizip/progress/operation_progress.rb +118 -0
  596. data/lib/omnizip/progress/progress_bar.rb +156 -0
  597. data/lib/omnizip/progress/progress_reporter.rb +40 -0
  598. data/lib/omnizip/progress/progress_tracker.rb +215 -0
  599. data/lib/omnizip/progress/silent_reporter.rb +22 -0
  600. data/lib/omnizip/progress.rb +131 -0
  601. data/lib/omnizip/registry.rb +111 -0
  602. data/lib/omnizip/rubyzip_compat.rb +61 -0
  603. data/lib/omnizip/temp/safe_extract.rb +124 -0
  604. data/lib/omnizip/temp/temp_file.rb +123 -0
  605. data/lib/omnizip/temp/temp_file_pool.rb +109 -0
  606. data/lib/omnizip/temp.rb +184 -0
  607. data/lib/omnizip/version.rb +5 -0
  608. data/lib/omnizip/zip/entry.rb +160 -0
  609. data/lib/omnizip/zip/file.rb +485 -0
  610. data/lib/omnizip/zip/input_stream.rb +270 -0
  611. data/lib/omnizip/zip/output_stream.rb +320 -0
  612. data/lib/omnizip/zip.rb +23 -0
  613. data/lib/omnizip.rb +157 -0
  614. data/lib/tasks/msi_test_files.rake +66 -0
  615. data/lib/tasks/platform_gems.rake +147 -0
  616. data/lib/tasks/rust_backend.rake +48 -0
  617. data/readme-docs/advanced-features.adoc +514 -0
  618. data/readme-docs/api-usage.adoc +445 -0
  619. data/readme-docs/architecture.adoc +450 -0
  620. data/readme-docs/archive-formats.adoc +479 -0
  621. data/readme-docs/cli-usage.adoc +222 -0
  622. data/readme-docs/compression-algorithms.adoc +446 -0
  623. data/readme-docs/compression-profiles.adoc +247 -0
  624. data/readme-docs/encryption-checksums.adoc +328 -0
  625. data/readme-docs/format-converter.adoc +316 -0
  626. data/readme-docs/installation.adoc +228 -0
  627. data/readme-docs/par2-archives.adoc +608 -0
  628. data/readme-docs/performance-profiler.adoc +389 -0
  629. data/readme-docs/preprocessing-filters.adoc +280 -0
  630. data/vendor/libomnizip_ffi.so +0 -0
  631. data/xz-file-format-1.2.1.txt +1174 -0
  632. metadata +768 -0
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+
5
+ module Omnizip
6
+ module Pipe
7
+ # Stream-based decompression for pipe operations
8
+ #
9
+ # Accepts compressed archive from any IO-like source and extracts
10
+ # to directory or streams to output. Handles multi-file archives
11
+ # and provides error recovery for corrupted streams.
12
+ #
13
+ # @example Decompress to directory
14
+ # decompressor = StreamDecompressor.new($stdin, output_dir: 'extracted/')
15
+ # decompressor.decompress
16
+ #
17
+ # @example Decompress to stdout
18
+ # decompressor = StreamDecompressor.new($stdin, output: $stdout)
19
+ # decompressor.decompress
20
+ class StreamDecompressor
21
+ # Default chunk size for streaming extraction (64KB)
22
+ DEFAULT_CHUNK_SIZE = 64 * 1024
23
+
24
+ attr_reader :input, :output_dir, :output, :options, :bytes_written
25
+
26
+ # Initialize stream decompressor
27
+ #
28
+ # @param input [IO] Input stream containing archive
29
+ # @param output_dir [String, nil] Directory to extract to
30
+ # @param output [IO, nil] Output stream (for single-file extraction)
31
+ # @param options [Hash] Decompression options
32
+ # @option options [Symbol] :format Archive format (auto-detected if nil)
33
+ # @option options [Integer] :chunk_size Write buffer size
34
+ # @option options [Proc] :progress Progress callback
35
+ # @option options [Boolean] :preserve_paths Preserve directory structure
36
+ def initialize(input, output_dir: nil, output: nil, **options)
37
+ @input = input
38
+ @output_dir = output_dir
39
+ @output = output
40
+ @options = options
41
+ @chunk_size = options[:chunk_size] || DEFAULT_CHUNK_SIZE
42
+ @bytes_written = 0
43
+ @progress_callback = options[:progress]
44
+ @format = options[:format]
45
+ @preserve_paths = options.fetch(:preserve_paths, true)
46
+ end
47
+
48
+ # Decompress input stream
49
+ #
50
+ # Extracts archive to output directory or streams to output.
51
+ # Returns hash of extracted files or bytes written.
52
+ #
53
+ # @return [Hash<String, Integer>, Integer] Files => bytes or total bytes
54
+ # @raise [Omnizip::FormatError] If archive format is invalid
55
+ def decompress
56
+ if @output
57
+ decompress_to_stream
58
+ elsif @output_dir
59
+ decompress_to_directory
60
+ else
61
+ raise ArgumentError,
62
+ "Either output_dir or output must be specified"
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ # Decompress to output stream
69
+ #
70
+ # Extracts first non-directory entry to output stream.
71
+ # Useful for single-file archives or piping to stdout.
72
+ #
73
+ # @return [Integer] Bytes written to output
74
+ def decompress_to_stream
75
+ # Read archive into memory (necessary for format detection)
76
+ archive_data = @input.read
77
+
78
+ Omnizip::Buffer.open(archive_data, format: @format) do |archive|
79
+ archive.each_entry do |entry|
80
+ next if entry.directory?
81
+
82
+ # Stream first file to output
83
+ while chunk = entry.read(@chunk_size)
84
+ @output.write(chunk)
85
+ @bytes_written += chunk.bytesize
86
+
87
+ @progress_callback&.call(entry.name, @bytes_written)
88
+ end
89
+
90
+ break # Only extract first file for streaming
91
+ end
92
+ end
93
+
94
+ @bytes_written
95
+ rescue StandardError => e
96
+ raise Omnizip::Error,
97
+ "Stream decompression failed: #{e.message}"
98
+ end
99
+
100
+ # Decompress to directory
101
+ #
102
+ # Extracts all entries to specified directory with
103
+ # directory structure preservation.
104
+ #
105
+ # @return [Hash<String, Integer>] Filename => bytes mapping
106
+ def decompress_to_directory
107
+ FileUtils.mkdir_p(@output_dir)
108
+
109
+ # Read archive into memory
110
+ archive_data = @input.read
111
+ extracted_files = {}
112
+
113
+ Omnizip::Buffer.open(archive_data, format: @format) do |archive|
114
+ archive.each_entry do |entry|
115
+ if entry.directory?
116
+ create_directory(entry)
117
+ else
118
+ bytes = extract_file(entry)
119
+ extracted_files[entry.name] = bytes
120
+ end
121
+ end
122
+ end
123
+
124
+ extracted_files
125
+ rescue StandardError => e
126
+ raise Omnizip::Error,
127
+ "Directory extraction failed: #{e.message}"
128
+ end
129
+
130
+ # Create directory from entry
131
+ #
132
+ # @param entry [Object] Directory entry
133
+ def create_directory(entry)
134
+ return unless @preserve_paths
135
+
136
+ dir_path = File.join(@output_dir, entry.name)
137
+ FileUtils.mkdir_p(dir_path)
138
+ end
139
+
140
+ # Extract file from entry
141
+ #
142
+ # @param entry [Object] File entry
143
+ # @return [Integer] Bytes written
144
+ def extract_file(entry)
145
+ dest_path = if @preserve_paths
146
+ File.join(@output_dir, entry.name)
147
+ else
148
+ File.join(@output_dir, File.basename(entry.name))
149
+ end
150
+
151
+ # Create parent directory if needed
152
+ FileUtils.mkdir_p(File.dirname(dest_path))
153
+
154
+ bytes = 0
155
+ File.open(dest_path, "wb") do |file|
156
+ while chunk = entry.read(@chunk_size)
157
+ file.write(chunk)
158
+ bytes += chunk.bytesize
159
+ @bytes_written += chunk.bytesize
160
+
161
+ @progress_callback&.call(entry.name, @bytes_written)
162
+ end
163
+ end
164
+
165
+ # Preserve timestamp if available
166
+ mtime = entry.mtime if entry.is_a?(Omnizip::Metadata::EntryMetadata)
167
+ File.utime(mtime, mtime, dest_path) if mtime
168
+
169
+ bytes
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ # Unix pipe operations for stdin/stdout integration
5
+ #
6
+ # Enables compression and decompression through Unix pipes without
7
+ # temporary files, supporting container workflows, CI/CD pipelines,
8
+ # and stream processing scenarios.
9
+ #
10
+ # @example Compress stdin to stdout
11
+ # Omnizip::Pipe.compress($stdin, $stdout, format: :zip)
12
+ #
13
+ # @example Decompress stdin to directory
14
+ # Omnizip::Pipe.decompress($stdin, output_dir: 'extracted/')
15
+ #
16
+ # @example File-to-file via pipe
17
+ # File.open('input.txt', 'rb') do |input|
18
+ # File.open('output.zip', 'wb') do |output|
19
+ # Omnizip::Pipe.compress(input, output, format: :zip)
20
+ # end
21
+ # end
22
+ module Pipe
23
+ autoload :StreamCompressor, "omnizip/pipe/stream_compressor"
24
+ autoload :StreamDecompressor, "omnizip/pipe/stream_decompressor"
25
+ class << self
26
+ # Compress from input stream to output stream
27
+ #
28
+ # @param input [IO] Input stream (stdin, File, Socket, etc.)
29
+ # @param output [IO] Output stream (stdout, File, network, etc.)
30
+ # @param format [Symbol] Archive format (:zip, :seven_zip)
31
+ # @param compression [Symbol] Compression algorithm
32
+ # @param options [Hash] Additional compression options
33
+ # @option options [String] :entry_name Name for entry in archive
34
+ # @option options [Integer] :chunk_size Read buffer size (default 64KB)
35
+ # @option options [Integer] :level Compression level (1-9)
36
+ # @return [Integer] Number of bytes written
37
+ #
38
+ # @example Compress stdin to stdout
39
+ # Omnizip::Pipe.compress($stdin, $stdout, format: :zip)
40
+ #
41
+ # @example Compress file with custom options
42
+ # File.open('data.txt', 'rb') do |input|
43
+ # File.open('data.zip', 'wb') do |output|
44
+ # Omnizip::Pipe.compress(
45
+ # input, output,
46
+ # format: :zip,
47
+ # compression: :deflate,
48
+ # level: 9,
49
+ # entry_name: 'data.txt'
50
+ # )
51
+ # end
52
+ # end
53
+ def compress(input, output, format: :zip, compression: nil, **options)
54
+ compressor = Pipe::StreamCompressor.new(
55
+ input,
56
+ output,
57
+ format,
58
+ compression: compression,
59
+ **options,
60
+ )
61
+ compressor.compress
62
+ end
63
+
64
+ # Decompress from input stream
65
+ #
66
+ # @param input [IO] Input stream containing archive
67
+ # @param output_dir [String, nil] Directory to extract to (nil = stdout)
68
+ # @param options [Hash] Extraction options
69
+ # @return [Integer, Hash] Bytes written or extracted files hash
70
+ #
71
+ # @example Extract to directory
72
+ # Omnizip::Pipe.decompress($stdin, output_dir: 'extracted/')
73
+ #
74
+ # @example Extract to stdout (single file)
75
+ # Omnizip::Pipe.decompress($stdin, output: $stdout)
76
+ def decompress(input, output_dir: nil, output: nil, **options)
77
+ decompressor = Pipe::StreamDecompressor.new(
78
+ input,
79
+ output_dir: output_dir,
80
+ output: output,
81
+ **options,
82
+ )
83
+ decompressor.decompress
84
+ end
85
+
86
+ # Check if running in pipe mode
87
+ #
88
+ # Detects if stdin/stdout are pipes (not TTY), indicating
89
+ # the program is being used in a Unix pipeline.
90
+ #
91
+ # @return [Boolean] True if stdin and stdout are pipes
92
+ #
93
+ # @example
94
+ # if Omnizip::Pipe.pipe_mode?
95
+ # # Process stdin to stdout
96
+ # else
97
+ # # Show interactive help
98
+ # end
99
+ def pipe_mode?
100
+ !$stdin.tty? && !$stdout.tty?
101
+ end
102
+
103
+ # Detect if input is stdin
104
+ #
105
+ # @param input [String, IO] Input path or IO object
106
+ # @return [Boolean] True if input is stdin
107
+ def stdin?(input)
108
+ ["-", $stdin].include?(input)
109
+ end
110
+
111
+ # Detect if output is stdout
112
+ #
113
+ # @param output [String, IO] Output path or IO object
114
+ # @return [Boolean] True if output is stdout
115
+ def stdout?(output)
116
+ ["-", $stdout].include?(output)
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,200 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "English"
4
+
5
+ module Omnizip
6
+ module Platform
7
+ # NTFS Alternate Data Streams handler
8
+ # Windows-only feature for managing file alternate streams
9
+ module NtfsStreams
10
+ # Check if NTFS streams are available
11
+ #
12
+ # @return [Boolean] true if available
13
+ def self.available?
14
+ Platform.supports_ntfs_streams?
15
+ end
16
+
17
+ # List alternate data streams for a file
18
+ #
19
+ # @param file_path [String] Path to file
20
+ # @return [Array<String>] List of stream names
21
+ def self.list_streams(file_path)
22
+ return [] unless available?
23
+ return [] unless File.exist?(file_path)
24
+
25
+ streams = []
26
+
27
+ begin
28
+ # Use PowerShell to list streams
29
+ cmd = "powershell -Command \"Get-Item '#{file_path}' -Stream * | " \
30
+ "Select-Object -ExpandProperty Stream\""
31
+ output = `#{cmd} 2>&1`
32
+
33
+ if $CHILD_STATUS.success?
34
+ streams = output.lines.map(&:strip).reject do |s|
35
+ s.empty? || s == ":$DATA"
36
+ end
37
+ end
38
+ rescue StandardError => e
39
+ warn "Failed to list NTFS streams: #{e.message}" if ENV["DEBUG"]
40
+ end
41
+
42
+ streams
43
+ end
44
+
45
+ # Read alternate data stream
46
+ #
47
+ # @param file_path [String] Path to file
48
+ # @param stream_name [String] Stream name
49
+ # @return [String, nil] Stream content or nil
50
+ def self.read_stream(file_path, stream_name)
51
+ return nil unless available?
52
+ return nil unless File.exist?(file_path)
53
+
54
+ begin
55
+ # Read using alternate stream syntax: file.txt:StreamName
56
+ stream_path = "#{file_path}:#{stream_name}"
57
+ File.binread(stream_path)
58
+ rescue Errno::ENOENT, Errno::EINVAL
59
+ nil
60
+ rescue StandardError => e
61
+ warn "Failed to read NTFS stream: #{e.message}" if ENV["DEBUG"]
62
+ nil
63
+ end
64
+ end
65
+
66
+ # Write alternate data stream
67
+ #
68
+ # @param file_path [String] Path to file
69
+ # @param stream_name [String] Stream name
70
+ # @param data [String] Stream data
71
+ # @return [Boolean] true if successful
72
+ def self.write_stream(file_path, stream_name, data)
73
+ return false unless available?
74
+ return false unless File.exist?(file_path)
75
+
76
+ begin
77
+ # Write using alternate stream syntax: file.txt:StreamName
78
+ stream_path = "#{file_path}:#{stream_name}"
79
+ File.binwrite(stream_path, data)
80
+ true
81
+ rescue StandardError => e
82
+ warn "Failed to write NTFS stream: #{e.message}" if ENV["DEBUG"]
83
+ false
84
+ end
85
+ end
86
+
87
+ # Delete alternate data stream
88
+ #
89
+ # @param file_path [String] Path to file
90
+ # @param stream_name [String] Stream name
91
+ # @return [Boolean] true if successful
92
+ def self.delete_stream(file_path, stream_name)
93
+ return false unless available?
94
+ return false unless File.exist?(file_path)
95
+
96
+ begin
97
+ # Use PowerShell to remove stream
98
+ cmd = "powershell -Command \"Remove-Item -Path '#{file_path}' " \
99
+ "-Stream '#{stream_name}'\""
100
+ system(cmd)
101
+ $CHILD_STATUS.success?
102
+ rescue StandardError => e
103
+ warn "Failed to delete NTFS stream: #{e.message}" if ENV["DEBUG"]
104
+ false
105
+ end
106
+ end
107
+
108
+ # Copy all alternate streams from source to destination
109
+ #
110
+ # @param source_path [String] Source file
111
+ # @param dest_path [String] Destination file
112
+ # @return [Integer] Number of streams copied
113
+ def self.copy_streams(source_path, dest_path)
114
+ return 0 unless available?
115
+ return 0 unless File.exist?(source_path)
116
+ return 0 unless File.exist?(dest_path)
117
+
118
+ copied = 0
119
+ streams = list_streams(source_path)
120
+
121
+ streams.each do |stream|
122
+ next if stream == "$DATA" # Skip main data stream
123
+
124
+ data = read_stream(source_path, stream)
125
+ copied += 1 if data && write_stream(dest_path, stream, data)
126
+ end
127
+
128
+ copied
129
+ end
130
+
131
+ # Get stream information
132
+ #
133
+ # @param file_path [String] Path to file
134
+ # @param stream_name [String] Stream name
135
+ # @return [Hash, nil] Stream info or nil
136
+ def self.stream_info(file_path, stream_name)
137
+ return nil unless available?
138
+ return nil unless File.exist?(file_path)
139
+
140
+ data = read_stream(file_path, stream_name)
141
+ return nil unless data
142
+
143
+ {
144
+ name: stream_name,
145
+ size: data.bytesize,
146
+ exists: true,
147
+ }
148
+ end
149
+
150
+ # Check if file has any alternate streams
151
+ #
152
+ # @param file_path [String] Path to file
153
+ # @return [Boolean] true if has streams
154
+ def self.has_streams?(file_path)
155
+ return false unless available?
156
+
157
+ streams = list_streams(file_path)
158
+ streams.any? { |s| s != "$DATA" }
159
+ end
160
+
161
+ # Archive streams to a hash
162
+ #
163
+ # @param file_path [String] Path to file
164
+ # @return [Hash<String, String>] Stream name => data
165
+ def self.archive_streams(file_path)
166
+ return {} unless available?
167
+
168
+ streams_data = {}
169
+ streams = list_streams(file_path)
170
+
171
+ streams.each do |stream|
172
+ next if stream == "$DATA"
173
+
174
+ data = read_stream(file_path, stream)
175
+ streams_data[stream] = data if data
176
+ end
177
+
178
+ streams_data
179
+ end
180
+
181
+ # Restore streams from hash
182
+ #
183
+ # @param file_path [String] Path to file
184
+ # @param streams_data [Hash<String, String>] Stream name => data
185
+ # @return [Integer] Number of streams restored
186
+ def self.restore_streams(file_path, streams_data)
187
+ return 0 unless available?
188
+ return 0 unless File.exist?(file_path)
189
+
190
+ restored = 0
191
+
192
+ streams_data.each do |stream_name, data|
193
+ restored += 1 if write_stream(file_path, stream_name, data)
194
+ end
195
+
196
+ restored
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,189 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ # Platform detection and capabilities
5
+ # Provides cross-platform compatibility checks
6
+ module Platform
7
+ # Detect if running on Windows
8
+ #
9
+ # @return [Boolean] true if Windows
10
+ def self.windows?
11
+ !!(RUBY_PLATFORM =~ /mswin|mingw|cygwin/)
12
+ end
13
+
14
+ # Detect if running on macOS
15
+ #
16
+ # @return [Boolean] true if macOS
17
+ def self.macos?
18
+ !!RUBY_PLATFORM.include?("darwin")
19
+ end
20
+
21
+ # Detect if running on Linux
22
+ #
23
+ # @return [Boolean] true if Linux
24
+ def self.linux?
25
+ !!RUBY_PLATFORM.include?("linux")
26
+ end
27
+
28
+ # Detect if running on Unix-like system
29
+ #
30
+ # @return [Boolean] true if Unix-like (macOS, Linux, BSD, etc.)
31
+ def self.unix?
32
+ !windows?
33
+ end
34
+
35
+ # Get platform name
36
+ #
37
+ # @return [String] Platform name
38
+ def self.name
39
+ return "Windows" if windows?
40
+ return "macOS" if macos?
41
+ return "Linux" if linux?
42
+
43
+ "Unknown"
44
+ end
45
+
46
+ # Check if NTFS alternate streams are supported
47
+ # Only available on Windows with NTFS filesystem
48
+ #
49
+ # @return [Boolean] true if NTFS streams supported
50
+ def self.supports_ntfs_streams?
51
+ windows?
52
+ end
53
+
54
+ # Check if symbolic links are supported
55
+ #
56
+ # @return [Boolean] true if symlinks supported
57
+ def self.supports_symlinks?
58
+ unix? || (windows? && windows_developer_mode?)
59
+ end
60
+
61
+ # Check if hard links are supported
62
+ #
63
+ # @return [Boolean] true if hard links supported
64
+ def self.supports_hardlinks?
65
+ true # Supported on all modern platforms
66
+ end
67
+
68
+ # Check if extended attributes are supported
69
+ #
70
+ # @return [Boolean] true if xattrs supported
71
+ def self.supports_extended_attributes?
72
+ unix?
73
+ end
74
+
75
+ # Check if file permissions are supported
76
+ #
77
+ # @return [Boolean] true if POSIX permissions supported
78
+ def self.supports_file_permissions?
79
+ unix?
80
+ end
81
+
82
+ # Get platform-specific features
83
+ #
84
+ # @return [Hash] Feature flags
85
+ def self.features
86
+ {
87
+ ntfs_streams: supports_ntfs_streams?,
88
+ symlinks: supports_symlinks?,
89
+ hardlinks: supports_hardlinks?,
90
+ extended_attributes: supports_extended_attributes?,
91
+ file_permissions: supports_file_permissions?,
92
+ }
93
+ end
94
+
95
+ # Check Windows Developer Mode (for symlink support)
96
+ #
97
+ # @return [Boolean] true if developer mode enabled
98
+ def self.windows_developer_mode?
99
+ return false unless windows?
100
+
101
+ # Check registry for developer mode setting
102
+ # HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock
103
+ # AllowDevelopmentWithoutDevLicense = 1
104
+ begin
105
+ require "win32/registry"
106
+ Win32::Registry::HKEY_LOCAL_MACHINE.open(
107
+ 'SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock',
108
+ Win32::Registry::KEY_READ,
109
+ ) do |reg|
110
+ value = reg["AllowDevelopmentWithoutDevLicense"]
111
+ return value == 1
112
+ end
113
+ rescue LoadError, StandardError
114
+ # win32/registry not available or key doesn't exist
115
+ false
116
+ end
117
+ end
118
+
119
+ # Get file system type for a path
120
+ #
121
+ # @param path [String] File or directory path
122
+ # @return [String, nil] Filesystem type or nil if unknown
123
+ def self.filesystem_type(path)
124
+ return nil unless File.exist?(path)
125
+
126
+ if windows?
127
+ detect_windows_filesystem(path)
128
+ elsif macos?
129
+ detect_macos_filesystem(path)
130
+ elsif linux?
131
+ detect_linux_filesystem(path)
132
+ end
133
+ end
134
+
135
+ # Check if path is on NTFS filesystem
136
+ #
137
+ # @param path [String] File or directory path
138
+ # @return [Boolean] true if NTFS
139
+ def self.ntfs?(path)
140
+ filesystem_type(path)&.upcase == "NTFS"
141
+ end
142
+
143
+ # Detect Windows filesystem type
144
+ #
145
+ # @param path [String] Path
146
+ # @return [String, nil] Filesystem type
147
+ def self.detect_windows_filesystem(path)
148
+ # Get drive letter
149
+ drive = File.expand_path(path)[0, 2]
150
+ return nil unless drive =~ /^[A-Za-z]:$/
151
+
152
+ # Use fsutil to get filesystem type
153
+ output = `fsutil fsinfo volumeinfo #{drive} 2>&1`
154
+ Regexp.last_match(1) if output =~ /File System Name\s*:\s*(\w+)/i
155
+ rescue StandardError
156
+ nil
157
+ end
158
+
159
+ # Detect macOS filesystem type
160
+ #
161
+ # @param path [String] Path
162
+ # @return [String, nil] Filesystem type
163
+ def self.detect_macos_filesystem(path)
164
+ output = `df -T #{path} 2>&1`.lines.last
165
+ return nil unless output
166
+
167
+ # Format: filesystem type blocks used avail capacity mounted
168
+ parts = output.split
169
+ parts[1] if parts.size > 1
170
+ rescue StandardError
171
+ nil
172
+ end
173
+
174
+ # Detect Linux filesystem type
175
+ #
176
+ # @param path [String] Path
177
+ # @return [String, nil] Filesystem type
178
+ def self.detect_linux_filesystem(path)
179
+ output = `df -T #{path} 2>&1`.lines.last
180
+ return nil unless output
181
+
182
+ # Format: filesystem type blocks used avail use% mounted
183
+ parts = output.split
184
+ parts[1] if parts.size > 1
185
+ rescue StandardError
186
+ nil
187
+ end
188
+ end
189
+ end