omnizip 0.4.7-aarch64-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,270 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
4
+
5
+ module Omnizip
6
+ module Zip
7
+ # Rubyzip-compatible InputStream class
8
+ # Provides streaming read API for ZIP archives
9
+ class InputStream
10
+ include Omnizip::Formats::Zip::Constants
11
+
12
+ # Open an input stream
13
+ # @param file_path_or_io [String, IO] File path or IO object
14
+ # @yield [stream] Block to read from the stream
15
+ # @return [InputStream] The stream (if no block given)
16
+ def self.open(file_path_or_io, &block)
17
+ stream = new(file_path_or_io)
18
+
19
+ if block
20
+ begin
21
+ yield(stream)
22
+ ensure
23
+ stream.close
24
+ end
25
+ else
26
+ stream
27
+ end
28
+ end
29
+
30
+ # Initialize input stream
31
+ # @param file_path_or_io [String, IO] File path or IO object
32
+ def initialize(file_path_or_io)
33
+ if file_path_or_io.is_a?(String)
34
+ @file_path = file_path_or_io
35
+ @io = ::File.open(file_path_or_io, "rb")
36
+ @owns_io = true
37
+ else
38
+ @io = file_path_or_io
39
+ @owns_io = false
40
+ end
41
+
42
+ @current_entry = nil
43
+ @current_entry_io = nil
44
+ @current_index = 0
45
+ @closed = false
46
+ @hit_nil = false
47
+
48
+ # Find and parse central directory for efficient access
49
+ parse_central_directory
50
+ end
51
+
52
+ # Get next entry in the archive
53
+ # @return [Entry, nil] Next entry or nil if no more entries
54
+ def get_next_entry
55
+ # Check if we can fetch another entry
56
+ if @current_index >= @all_entries.size
57
+ # Mark that get_next_entry returned nil
58
+ @hit_nil = true
59
+ return nil
60
+ end
61
+
62
+ # Close previous entry data if open
63
+ @current_entry_io = nil
64
+
65
+ # Get next entry from our parsed list
66
+ header = @all_entries[@current_index]
67
+ @current_index += 1
68
+
69
+ # Successfully got an entry - clear the nil flag
70
+ @hit_nil = false
71
+
72
+ # Position at entry data
73
+ position_at_entry_data(header)
74
+
75
+ @current_entry = Entry.new(header)
76
+ @current_entry
77
+ end
78
+
79
+ # Read from current entry
80
+ # @param size [Integer, nil] Number of bytes to read (nil for all)
81
+ # @return [String, nil] Data read or nil if no current entry
82
+ def read(size = nil)
83
+ return nil unless @current_entry
84
+
85
+ # Initialize entry IO if needed
86
+ unless @current_entry_io
87
+ compressed_data = @io.read(@current_entry.compressed_size)
88
+ decompressed = decompress_data(
89
+ compressed_data,
90
+ @current_entry.compression_method,
91
+ @current_entry.size,
92
+ )
93
+ @current_entry_io = StringIO.new(decompressed, "rb")
94
+ end
95
+
96
+ @current_entry_io.read(size)
97
+ end
98
+
99
+ # Rewind the stream
100
+ def rewind
101
+ @current_index = 0
102
+ @current_entry = nil
103
+ @current_entry_io = nil
104
+ @hit_nil = false
105
+ end
106
+
107
+ # Close the stream
108
+ def close
109
+ return if @closed
110
+
111
+ @current_entry_io = nil
112
+ @io.close if @owns_io
113
+ @closed = true
114
+ end
115
+
116
+ # Check if stream is closed
117
+ def closed?
118
+ @closed
119
+ end
120
+
121
+ # Check if at end of file
122
+ # Returns true if the NEXT call to get_next_entry would return nil
123
+ def eof?
124
+ @current_index >= @all_entries.size
125
+ end
126
+ alias_method :eof, :eof?
127
+
128
+ private
129
+
130
+ # Parse central directory to get all entries
131
+ def parse_central_directory
132
+ # Find End of Central Directory
133
+ eocd = find_eocd
134
+
135
+ # Read central directory entries
136
+ @io.seek(eocd[:central_directory_offset], ::IO::SEEK_SET)
137
+ @all_entries = []
138
+
139
+ eocd[:total_entries].times do
140
+ header_data = @io.read(46)
141
+ break unless header_data && header_data.size == 46
142
+
143
+ # Get dynamic field lengths
144
+ _, _, _, _, _, _, _, _, _, _,
145
+ filename_length, extra_field_length, comment_length = header_data.unpack("VvvvvvvVVVvvv")
146
+
147
+ # Read complete header
148
+ complete_data = header_data + @io.read(filename_length + extra_field_length + comment_length)
149
+ entry = Omnizip::Formats::Zip::CentralDirectoryHeader.from_binary(complete_data)
150
+
151
+ @all_entries << entry
152
+ end
153
+ end
154
+
155
+ # Find End of Central Directory record
156
+ def find_eocd
157
+ # Start from end of file
158
+ @io.seek(0, ::IO::SEEK_END)
159
+ file_size = @io.pos
160
+
161
+ # EOCD is at least 22 bytes
162
+ return nil if file_size < 22
163
+
164
+ # Search backwards for EOCD signature
165
+ # Maximum comment length is 65535, so search up to 65557 bytes from end
166
+ search_start = [file_size - 65557, 0].max
167
+ @io.seek(search_start, ::IO::SEEK_SET)
168
+ buffer = @io.read
169
+
170
+ # Find signature
171
+ signature = [END_OF_CENTRAL_DIRECTORY_SIGNATURE].pack("V")
172
+ pos = buffer.rindex(signature)
173
+
174
+ unless pos
175
+ raise Omnizip::FormatError,
176
+ "End of Central Directory not found"
177
+ end
178
+
179
+ # Parse EOCD
180
+ eocd_data = buffer[pos..]
181
+
182
+ sig, disk_num, disk_with_cd, entries_this_disk, total_entries,
183
+ cd_size, cd_offset, comment_length = eocd_data.unpack("VvvvvVVv")
184
+
185
+ {
186
+ signature: sig,
187
+ disk_number: disk_num,
188
+ disk_number_with_cd: disk_with_cd,
189
+ total_entries_this_disk: entries_this_disk,
190
+ total_entries: total_entries,
191
+ central_directory_size: cd_size,
192
+ central_directory_offset: cd_offset,
193
+ comment_length: comment_length,
194
+ comment: eocd_data[22, comment_length] || "",
195
+ }
196
+ end
197
+
198
+ # Position IO at entry's data (after local file header)
199
+ def position_at_entry_data(header)
200
+ # Seek to local file header
201
+ @io.seek(header.local_header_offset, ::IO::SEEK_SET)
202
+
203
+ # Read fixed part of local file header
204
+ fixed_header = @io.read(30)
205
+
206
+ # Extract variable lengths
207
+ _, _, _, _, _, _, _, _, _, filename_length, extra_length =
208
+ fixed_header.unpack("VvvvvvVVVvv")
209
+
210
+ # Skip variable parts to get to data
211
+ @io.read(filename_length + extra_length)
212
+ end
213
+
214
+ # Decompress data based on compression method
215
+ def decompress_data(compressed_data, method, uncompressed_size)
216
+ case method
217
+ when COMPRESSION_STORE
218
+ compressed_data
219
+ when COMPRESSION_DEFLATE
220
+ decompress_deflate(compressed_data)
221
+ when COMPRESSION_BZIP2
222
+ decompress_bzip2(compressed_data)
223
+ when COMPRESSION_LZMA
224
+ decompress_lzma(compressed_data, uncompressed_size)
225
+ when COMPRESSION_ZSTANDARD
226
+ decompress_zstandard(compressed_data)
227
+ else
228
+ raise Omnizip::UnsupportedFormatError,
229
+ "Unsupported compression method: #{method}"
230
+ end
231
+ end
232
+
233
+ # Decompress using Deflate
234
+ def decompress_deflate(data)
235
+ require "zlib"
236
+ Zlib::Inflate.new(-Zlib::MAX_WBITS).inflate(data)
237
+ rescue StandardError => e
238
+ raise Omnizip::DecompressionError,
239
+ "Deflate decompression failed: #{e.message}"
240
+ end
241
+
242
+ # Decompress using BZip2
243
+ def decompress_bzip2(data)
244
+ algorithm = Omnizip::AlgorithmRegistry.get(:bzip2)
245
+ algorithm.decompress(data)
246
+ rescue StandardError => e
247
+ raise Omnizip::DecompressionError,
248
+ "BZip2 decompression failed: #{e.message}"
249
+ end
250
+
251
+ # Decompress using LZMA
252
+ def decompress_lzma(data, uncompressed_size)
253
+ algorithm = Omnizip::AlgorithmRegistry.get(:lzma)
254
+ algorithm.decompress(data, uncompressed_size: uncompressed_size)
255
+ rescue StandardError => e
256
+ raise Omnizip::DecompressionError,
257
+ "LZMA decompression failed: #{e.message}"
258
+ end
259
+
260
+ # Decompress using Zstandard
261
+ def decompress_zstandard(data)
262
+ algorithm = Omnizip::AlgorithmRegistry.get(:zstandard)
263
+ algorithm.decompress(data)
264
+ rescue StandardError => e
265
+ raise Omnizip::DecompressionError,
266
+ "Zstandard decompression failed: #{e.message}"
267
+ end
268
+ end
269
+ end
270
+ end
@@ -0,0 +1,320 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+
5
+ module Omnizip
6
+ module Zip
7
+ # Rubyzip-compatible OutputStream class
8
+ # Provides streaming write API for ZIP archives
9
+ class OutputStream
10
+ include Omnizip::Formats::Zip::Constants
11
+
12
+ # Open a new output stream
13
+ # @param file_path [String] Path to ZIP file
14
+ # @yield [stream] Block to write to the stream
15
+ # @return [OutputStream] The stream (if no block given)
16
+ def self.open(file_path, &block)
17
+ stream = new(file_path)
18
+
19
+ if block
20
+ begin
21
+ yield(stream)
22
+ ensure
23
+ stream.close
24
+ end
25
+ else
26
+ stream
27
+ end
28
+ end
29
+
30
+ # Initialize output stream
31
+ # @param file_path_or_io [String, IO] File path or IO object
32
+ def initialize(file_path_or_io)
33
+ if file_path_or_io.is_a?(String)
34
+ @file_path = file_path_or_io
35
+ @io = ::File.open(file_path_or_io, "wb")
36
+ @owns_io = true
37
+ else
38
+ @io = file_path_or_io
39
+ @owns_io = false
40
+ end
41
+
42
+ @entries = []
43
+ @current_entry = nil
44
+ @current_entry_data = nil
45
+ @closed = false
46
+ end
47
+
48
+ # Start a new entry
49
+ # @param name [String] Entry name
50
+ # @param time [Time] Modification time
51
+ # @param comment [String] Entry comment
52
+ # @param compression [Symbol] Compression method (:store or :deflate)
53
+ # @param level [Integer] Compression level (1-9)
54
+ def put_next_entry(name, time: Time.now, comment: "",
55
+ compression: :deflate, level: 6)
56
+ close_entry if @current_entry
57
+
58
+ @current_entry = {
59
+ name: name,
60
+ time: time,
61
+ comment: comment,
62
+ compression: compression_method_for(compression),
63
+ level: level,
64
+ offset: @io.pos,
65
+ directory: name.end_with?("/"),
66
+ }
67
+ @current_entry_data = String.new(encoding: Encoding::BINARY)
68
+
69
+ # Write placeholder local file header (will update later)
70
+ write_local_file_header_placeholder
71
+
72
+ self
73
+ end
74
+
75
+ # Write data to current entry
76
+ # @param data [String] Data to write
77
+ def write(data)
78
+ raise Omnizip::IOError, "No entry started. Call put_next_entry first" unless @current_entry
79
+
80
+ @current_entry_data << data.b
81
+ self
82
+ end
83
+ alias_method :<<, :write
84
+
85
+ # Print data to current entry
86
+ def print(*args)
87
+ write(args.join)
88
+ end
89
+
90
+ # Put data to current entry
91
+ def puts(*args)
92
+ args.each { |arg| write("#{arg}\n") }
93
+ end
94
+
95
+ # Close current entry
96
+ def close_entry
97
+ return unless @current_entry
98
+
99
+ # Compress data if needed
100
+ compressed_data = compress_entry_data
101
+
102
+ # Calculate CRC32
103
+ crc32 = @current_entry[:directory] ? 0 : calculate_crc32(@current_entry_data)
104
+
105
+ # Write compressed data
106
+ @io.write(compressed_data) unless @current_entry[:directory]
107
+
108
+ # Update entry info
109
+ @current_entry.merge!({
110
+ crc32: crc32,
111
+ compressed_size: compressed_data.bytesize,
112
+ uncompressed_size: @current_entry_data.bytesize,
113
+ })
114
+
115
+ # Update local file header with correct sizes
116
+ current_pos = @io.pos
117
+ @io.seek(@current_entry[:offset], ::IO::SEEK_SET)
118
+ write_local_file_header
119
+ @io.seek(current_pos, ::IO::SEEK_SET)
120
+
121
+ # Save entry for central directory
122
+ @entries << @current_entry
123
+
124
+ @current_entry = nil
125
+ @current_entry_data = nil
126
+ end
127
+
128
+ # Set archive comment
129
+ def comment=(comment)
130
+ @comment = comment
131
+ end
132
+
133
+ # Get archive comment
134
+ def comment
135
+ @comment || ""
136
+ end
137
+
138
+ # Close the stream
139
+ def close
140
+ return if @closed
141
+
142
+ close_entry if @current_entry
143
+
144
+ # Write central directory
145
+ central_directory_offset = @io.pos
146
+ write_central_directory
147
+ central_directory_size = @io.pos - central_directory_offset
148
+
149
+ # Write end of central directory
150
+ write_end_of_central_directory(central_directory_offset,
151
+ central_directory_size)
152
+
153
+ @io.close if @owns_io
154
+ @closed = true
155
+ end
156
+
157
+ # Check if stream is closed
158
+ def closed?
159
+ @closed
160
+ end
161
+
162
+ private
163
+
164
+ # Get compression method code
165
+ def compression_method_for(symbol)
166
+ case symbol
167
+ when :store, :none then COMPRESSION_STORE
168
+ when :deflate then COMPRESSION_DEFLATE
169
+ when :bzip2 then COMPRESSION_BZIP2
170
+ when :lzma then COMPRESSION_LZMA
171
+ when :zstandard then COMPRESSION_ZSTANDARD
172
+ else COMPRESSION_DEFLATE
173
+ end
174
+ end
175
+
176
+ # Write local file header placeholder
177
+ def write_local_file_header_placeholder
178
+ # Write zeros for now, will update after compression
179
+ @io.write("\x00" * 30) # Fixed part
180
+ @io.write(@current_entry[:name].b) # Filename
181
+ @current_entry[:filename_length] = @current_entry[:name].bytesize
182
+ @current_entry[:extra_field_length] = 0
183
+ end
184
+
185
+ # Write actual local file header
186
+ def write_local_file_header
187
+ header = Omnizip::Formats::Zip::LocalFileHeader.new(
188
+ version_needed: version_for_method(@current_entry[:compression]),
189
+ flags: FLAG_UTF8,
190
+ compression_method: @current_entry[:directory] ? COMPRESSION_STORE : @current_entry[:compression],
191
+ last_mod_time: dos_time(@current_entry[:time]),
192
+ last_mod_date: dos_date(@current_entry[:time]),
193
+ crc32: @current_entry[:crc32],
194
+ compressed_size: @current_entry[:compressed_size],
195
+ uncompressed_size: @current_entry[:uncompressed_size],
196
+ filename: @current_entry[:name],
197
+ )
198
+
199
+ @io.write(header.to_binary)
200
+ end
201
+
202
+ # Compress current entry data
203
+ def compress_entry_data
204
+ return "" if @current_entry[:directory]
205
+
206
+ case @current_entry[:compression]
207
+ when COMPRESSION_STORE
208
+ @current_entry_data
209
+ when COMPRESSION_DEFLATE
210
+ compress_deflate(@current_entry_data, @current_entry[:level])
211
+ when COMPRESSION_BZIP2
212
+ compress_bzip2(@current_entry_data, @current_entry[:level])
213
+ when COMPRESSION_LZMA
214
+ compress_lzma(@current_entry_data, @current_entry[:level])
215
+ when COMPRESSION_ZSTANDARD
216
+ compress_zstandard(@current_entry_data, @current_entry[:level])
217
+ else
218
+ @current_entry_data
219
+ end
220
+ end
221
+
222
+ # Write central directory
223
+ def write_central_directory
224
+ @entries.each do |entry|
225
+ external_attrs = if entry[:directory]
226
+ UNIX_DIR_PERMISSIONS | ATTR_DIRECTORY
227
+ else
228
+ UNIX_FILE_PERMISSIONS
229
+ end
230
+
231
+ header = Omnizip::Formats::Zip::CentralDirectoryHeader.new(
232
+ version_made_by: VERSION_MADE_BY_UNIX | version_for_method(entry[:compression]),
233
+ version_needed: version_for_method(entry[:compression]),
234
+ flags: FLAG_UTF8,
235
+ compression_method: entry[:directory] ? COMPRESSION_STORE : entry[:compression],
236
+ last_mod_time: dos_time(entry[:time]),
237
+ last_mod_date: dos_date(entry[:time]),
238
+ crc32: entry[:crc32],
239
+ compressed_size: entry[:compressed_size],
240
+ uncompressed_size: entry[:uncompressed_size],
241
+ disk_number_start: 0,
242
+ internal_attributes: 0,
243
+ external_attributes: external_attrs,
244
+ local_header_offset: entry[:offset],
245
+ filename: entry[:name],
246
+ extra_field: "",
247
+ comment: entry[:comment] || "",
248
+ )
249
+
250
+ @io.write(header.to_binary)
251
+ end
252
+ end
253
+
254
+ # Write end of central directory
255
+ def write_end_of_central_directory(offset, size)
256
+ eocd = Omnizip::Formats::Zip::EndOfCentralDirectory.new(
257
+ disk_number: 0,
258
+ disk_number_with_cd: 0,
259
+ total_entries_this_disk: @entries.size,
260
+ total_entries: @entries.size,
261
+ central_directory_size: size,
262
+ central_directory_offset: offset,
263
+ comment: comment,
264
+ )
265
+
266
+ @io.write(eocd.to_binary)
267
+ end
268
+
269
+ # Compress using Deflate
270
+ def compress_deflate(data, level)
271
+ require "zlib"
272
+ Zlib::Deflate.new(level, -Zlib::MAX_WBITS).deflate(data, Zlib::FINISH)
273
+ end
274
+
275
+ # Compress using BZip2
276
+ def compress_bzip2(data, level)
277
+ algorithm = Omnizip::AlgorithmRegistry.get(:bzip2)
278
+ algorithm.compress(data, level: level)
279
+ end
280
+
281
+ # Compress using LZMA
282
+ def compress_lzma(data, level)
283
+ algorithm = Omnizip::AlgorithmRegistry.get(:lzma)
284
+ algorithm.compress(data, level: level)
285
+ end
286
+
287
+ # Compress using Zstandard
288
+ def compress_zstandard(data, level)
289
+ algorithm = Omnizip::AlgorithmRegistry.get(:zstandard)
290
+ algorithm.compress(data, level: level)
291
+ end
292
+
293
+ # Calculate CRC32
294
+ def calculate_crc32(data)
295
+ Omnizip::Checksums::Crc32.new.tap { |c| c.update(data) }.finalize
296
+ end
297
+
298
+ # Get version needed for compression method
299
+ def version_for_method(method)
300
+ case method
301
+ when COMPRESSION_STORE then VERSION_DEFAULT
302
+ when COMPRESSION_DEFLATE then VERSION_DEFLATE
303
+ when COMPRESSION_BZIP2 then VERSION_BZIP2
304
+ when COMPRESSION_LZMA then VERSION_LZMA
305
+ else VERSION_DEFAULT
306
+ end
307
+ end
308
+
309
+ # Convert Time to DOS time
310
+ def dos_time(time)
311
+ ((time.hour << 11) | (time.min << 5) | (time.sec / 2)) & 0xFFFF
312
+ end
313
+
314
+ # Convert Time to DOS date
315
+ def dos_date(time)
316
+ (((time.year - 1980) << 9) | (time.month << 5) | time.day) & 0xFFFF
317
+ end
318
+ end
319
+ end
320
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ # Rubyzip-compatible API module
5
+ #
6
+ # Provides a Rubyzip-compatible interface for working with ZIP archives.
7
+ # This allows existing code that uses Rubyzip to work with Omnizip.
8
+ module Zip
9
+ autoload :Entry, "omnizip/zip/entry"
10
+ autoload :File, "omnizip/zip/file"
11
+ autoload :OutputStream, "omnizip/zip/output_stream"
12
+ autoload :InputStream, "omnizip/zip/input_stream"
13
+
14
+ # Cross-namespace dependencies - autoloaded
15
+ autoload :ZipConstants, "omnizip/formats/zip/constants"
16
+ autoload :LocalFileHeader, "omnizip/formats/zip/local_file_header"
17
+ autoload :CentralDirectoryHeader,
18
+ "omnizip/formats/zip/central_directory_header"
19
+ autoload :EndOfCentralDirectory,
20
+ "omnizip/formats/zip/end_of_central_directory"
21
+ autoload :EntryMetadata, "omnizip/metadata/entry_metadata"
22
+ end
23
+ end