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,461 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "zlib"
4
+ require "digest"
5
+ require "fileutils"
6
+ require "stringio"
7
+
8
+ module Omnizip
9
+ module Formats
10
+ module Xar
11
+ # XAR archive writer
12
+ #
13
+ # Provides write access to create XAR archives with support for:
14
+ # - Multiple compression algorithms (gzip, bzip2, lzma, xz, none)
15
+ # - Checksum generation (md5, sha1, sha256, etc.)
16
+ # - Extended attributes
17
+ # - Hardlinks and symlinks
18
+ class Writer
19
+ include Omnizip::Formats::Xar::Constants
20
+
21
+ attr_reader :output_path, :entries, :options
22
+
23
+ # Create a XAR archive
24
+ #
25
+ # @param output_path [String] Path to output file
26
+ # @param options [Hash] Archive options
27
+ # @yield [Writer] Writer instance for adding files
28
+ # @return [String] Path to created archive
29
+ def self.create(output_path, options = {})
30
+ writer = new(output_path, options)
31
+
32
+ yield writer if block_given?
33
+
34
+ writer.write
35
+ output_path
36
+ end
37
+
38
+ # Initialize writer
39
+ #
40
+ # @param output_path [String] Path to output file
41
+ # @param options [Hash] Archive options
42
+ # @option options [String] :compression Compression algorithm (gzip, bzip2, lzma, xz, none)
43
+ # @option options [Integer] :compression_level Compression level (1-9)
44
+ # @option options [String] :toc_checksum TOC checksum algorithm (sha1, md5, sha256)
45
+ # @option options [String] :file_checksum File checksum algorithm (sha1, md5, sha256)
46
+ def initialize(output_path, options = {})
47
+ @output_path = output_path
48
+ @options = {
49
+ compression: DEFAULT_COMPRESSION,
50
+ compression_level: DEFAULT_COMPRESSION_LEVEL,
51
+ toc_checksum: DEFAULT_TOC_CHECKSUM,
52
+ file_checksum: DEFAULT_FILE_CHECKSUM,
53
+ }.merge(options)
54
+
55
+ @entries = []
56
+ @heap_data = +""
57
+ @next_id = 1
58
+ @hardlinks = {} # inode -> entry mapping for hardlink detection
59
+ end
60
+
61
+ # Add file to archive
62
+ #
63
+ # @param path [String] File path (on disk)
64
+ # @param archive_path [String, nil] Path in archive (defaults to basename)
65
+ # @return [Entry] Added entry
66
+ def add_file(path, archive_path = nil)
67
+ archive_path ||= File.basename(path)
68
+ stat = File.stat(path)
69
+
70
+ entry = Entry.new(archive_path, {
71
+ type: TYPE_FILE,
72
+ mode: stat.mode & 0o7777,
73
+ uid: stat.uid,
74
+ gid: stat.gid,
75
+ size: stat.size,
76
+ mtime: stat.mtime,
77
+ atime: stat.atime,
78
+ ctime: to_time(stat.ctime),
79
+ })
80
+
81
+ # Check for hardlink
82
+ if stat.nlink > 1
83
+ inode_key = "#{stat.dev}:#{stat.ino}"
84
+ if (existing = @hardlinks[inode_key])
85
+ # Create hardlink entry instead
86
+ entry.type = TYPE_HARDLINK
87
+ entry.link_type = "hard"
88
+ entry.link_target = existing.name
89
+ entry.nlink = stat.nlink
90
+ else
91
+ @hardlinks[inode_key] = entry
92
+ read_and_add_file_data(entry, path)
93
+ end
94
+ else
95
+ read_and_add_file_data(entry, path)
96
+ end
97
+
98
+ add_entry(entry)
99
+ end
100
+
101
+ # Add directory to archive
102
+ #
103
+ # @param path [String] Directory path (on disk)
104
+ # @param archive_path [String, nil] Path in archive
105
+ # @return [Entry] Added entry
106
+ def add_directory(path, archive_path = nil)
107
+ archive_path ||= File.basename(path)
108
+ stat = File.stat(path)
109
+
110
+ entry = Entry.new(archive_path, {
111
+ type: TYPE_DIRECTORY,
112
+ mode: stat.mode & 0o7777,
113
+ uid: stat.uid,
114
+ gid: stat.gid,
115
+ mtime: stat.mtime,
116
+ atime: stat.atime,
117
+ ctime: to_time(stat.ctime),
118
+ })
119
+
120
+ add_entry(entry)
121
+ end
122
+
123
+ # Add symlink to archive
124
+ #
125
+ # @param path [String] Symlink path (on disk)
126
+ # @param archive_path [String, nil] Path in archive
127
+ # @return [Entry] Added entry
128
+ def add_symlink(path, archive_path = nil)
129
+ archive_path ||= File.basename(path)
130
+ stat = File.lstat(path)
131
+
132
+ entry = Entry.new(archive_path, {
133
+ type: TYPE_SYMLINK,
134
+ mode: stat.mode & 0o7777,
135
+ uid: stat.uid,
136
+ gid: stat.gid,
137
+ mtime: stat.mtime,
138
+ atime: stat.atime,
139
+ link_type: "symbolic",
140
+ link_target: File.readlink(path),
141
+ })
142
+
143
+ add_entry(entry)
144
+ end
145
+
146
+ # Add entry from data
147
+ #
148
+ # @param archive_path [String] Path in archive
149
+ # @param data [String] File data
150
+ # @param options [Hash] Entry options
151
+ # @return [Entry] Added entry
152
+ def add_data(archive_path, data, options = {})
153
+ entry = Entry.new(archive_path, {
154
+ type: TYPE_FILE,
155
+ mode: options[:mode] || 0o644,
156
+ mtime: options[:mtime] || Time.now,
157
+ atime: options[:atime] || Time.now,
158
+ **options,
159
+ })
160
+
161
+ entry.data = data
162
+ compress_and_add_entry_data(entry, data)
163
+ add_entry(entry)
164
+ end
165
+
166
+ # Add entry to archive
167
+ #
168
+ # @param entry [Entry] Entry to add
169
+ # @return [Entry] Added entry
170
+ def add_entry(entry)
171
+ entry.id ||= @next_id
172
+ @next_id = [@next_id, entry.id + 1].max
173
+ @entries << entry
174
+ entry
175
+ end
176
+
177
+ # Add tree (directory recursively) to archive
178
+ #
179
+ # @param path [String] Root directory path
180
+ # @param archive_path [String, nil] Base path in archive
181
+ def add_tree(path, archive_path = nil)
182
+ stat = File.lstat(path)
183
+
184
+ if stat.symlink?
185
+ add_symlink(path, archive_path)
186
+ elsif stat.directory?
187
+ add_directory(path, archive_path)
188
+
189
+ Dir.foreach(path) do |entry|
190
+ next if [".", ".."].include?(entry)
191
+
192
+ child_path = File.join(path, entry)
193
+ child_archive_path = if archive_path
194
+ File.join(archive_path,
195
+ entry)
196
+ else
197
+ entry
198
+ end
199
+ add_tree(child_path, child_archive_path)
200
+ end
201
+ else
202
+ add_file(path, archive_path)
203
+ end
204
+ end
205
+
206
+ # Write archive to disk
207
+ #
208
+ # @return [String] Output path
209
+ def write
210
+ File.open(@output_path, "wb") do |file|
211
+ # Reserve space for header (will write at end)
212
+ header = Header.new(
213
+ checksum_algorithm: checksum_to_constant(@options[:toc_checksum]),
214
+ checksum_name: checksum_needs_name(@options[:toc_checksum]) ? @options[:toc_checksum] : nil,
215
+ )
216
+ file.write("\x00" * header.header_size)
217
+
218
+ # Build TOC with heap offsets
219
+ toc = build_toc
220
+
221
+ # Write compressed TOC
222
+ compressed_toc = toc.compress
223
+ toc_uncompressed_size = toc.uncompressed_size
224
+ file.write(compressed_toc)
225
+
226
+ # Calculate and write TOC checksum
227
+ file.pos
228
+ toc_checksum_data = compute_checksum(compressed_toc,
229
+ @options[:toc_checksum])
230
+ file.write(toc_checksum_data)
231
+ toc_checksum_size = toc_checksum_data.bytesize
232
+
233
+ # Update TOC checksum info
234
+ toc.checksum_offset = 0
235
+ toc.checksum_size = toc_checksum_size
236
+
237
+ # Write heap data
238
+ file.pos
239
+ file.write(@heap_data)
240
+
241
+ # Now write header at beginning
242
+ header = Header.new(
243
+ toc_compressed_size: compressed_toc.bytesize,
244
+ toc_uncompressed_size: toc_uncompressed_size,
245
+ checksum_algorithm: checksum_to_constant(@options[:toc_checksum]),
246
+ checksum_name: checksum_needs_name(@options[:toc_checksum]) ? @options[:toc_checksum] : nil,
247
+ )
248
+ file.seek(0)
249
+ file.write(header.to_bytes)
250
+ end
251
+
252
+ @output_path
253
+ end
254
+
255
+ private
256
+
257
+ # Coerce a ctime value (File::Stat returns Time on Unix, may
258
+ # return other types on Windows) into a Time.
259
+ def to_time(value)
260
+ return value if value.is_a?(Time)
261
+ return value.to_time if value.is_a?(Date) || value.is_a?(DateTime)
262
+
263
+ value
264
+ end
265
+
266
+ # Read file data and add to heap
267
+ #
268
+ # @param entry [Entry] Entry to populate
269
+ # @param path [String] File path
270
+ def read_and_add_file_data(entry, path)
271
+ data = File.binread(path)
272
+ entry.size = data.bytesize
273
+ compress_and_add_entry_data(entry, data)
274
+ end
275
+
276
+ # Compress and add entry data to heap
277
+ #
278
+ # @param entry [Entry] Entry to populate
279
+ # @param data [String] Uncompressed data
280
+ def compress_and_add_entry_data(entry, data)
281
+ return if data.nil? || data.empty?
282
+
283
+ # Calculate extracted checksum
284
+ entry.extracted_checksum = compute_checksum_hex(data,
285
+ @options[:file_checksum])
286
+ entry.extracted_checksum_style = @options[:file_checksum]
287
+
288
+ # Compress data
289
+ compressed = compress_data(data)
290
+ entry.data_encoding = @options[:compression]
291
+ entry.data_length = compressed.bytesize
292
+ entry.data_size = data.bytesize
293
+
294
+ # Calculate archived checksum
295
+ entry.archived_checksum = compute_checksum_hex(compressed,
296
+ @options[:file_checksum])
297
+ entry.archived_checksum_style = @options[:file_checksum]
298
+
299
+ # Add to heap
300
+ # Data offset must account for TOC checksum at start of heap
301
+ checksum_size = CHECKSUM_SIZES[@options[:toc_checksum]] || 0
302
+ entry.data_offset = checksum_size + @heap_data.bytesize
303
+ @heap_data << compressed
304
+ end
305
+
306
+ # Compress data based on configured algorithm
307
+ #
308
+ # @param data [String] Uncompressed data
309
+ # @return [String] Compressed data
310
+ def compress_data(data)
311
+ case @options[:compression]
312
+ when COMPRESSION_GZIP
313
+ compress_gzip(data)
314
+ when COMPRESSION_BZIP2
315
+ compress_bzip2(data)
316
+ when COMPRESSION_LZMA
317
+ compress_lzma(data)
318
+ when COMPRESSION_XZ
319
+ compress_xz(data)
320
+ else
321
+ data
322
+ end
323
+ end
324
+
325
+ # Compress with gzip
326
+ #
327
+ # @param data [String] Uncompressed data
328
+ # @return [String] Gzip compressed data
329
+ def compress_gzip(data)
330
+ level = @options[:compression_level] || DEFAULT_COMPRESSION_LEVEL
331
+ zlib = Zlib::Deflate.new(level, -Zlib::MAX_WBITS)
332
+ result = zlib.deflate(data, Zlib::FINISH)
333
+ zlib.close
334
+ result
335
+ end
336
+
337
+ # Compress with bzip2
338
+ #
339
+ # @param data [String] Uncompressed data
340
+ # @return [String] Bzip2 compressed data
341
+ def compress_bzip2(data)
342
+ compressor = Omnizip::Algorithms::Bzip2::Compressor.new(
343
+ level: @options[:compression_level] || DEFAULT_COMPRESSION_LEVEL,
344
+ )
345
+ compressor.compress(data)
346
+ end
347
+
348
+ # Compress with LZMA
349
+ #
350
+ # @param data [String] Uncompressed data
351
+ # @return [String] LZMA compressed data
352
+ def compress_lzma(data)
353
+ encoder = Omnizip::Algorithms::Lzma::Encoder.new(
354
+ level: @options[:compression_level] || DEFAULT_COMPRESSION_LEVEL,
355
+ )
356
+ encoder.encode(data)
357
+ end
358
+
359
+ # Compress with XZ
360
+ #
361
+ # @param data [String] Uncompressed data
362
+ # @return [String] XZ compressed data
363
+ def compress_xz(data)
364
+ output = StringIO.new
365
+ writer = Omnizip::Formats::Xz::StreamWriter.new(output,
366
+ level: @options[:compression_level] || DEFAULT_COMPRESSION_LEVEL)
367
+ writer.write(data)
368
+ writer.close
369
+ output.string
370
+ end
371
+
372
+ # Compute checksum (returns binary data)
373
+ #
374
+ # @param data [String] Data to checksum
375
+ # @param algorithm [String] Checksum algorithm
376
+ # @return [String] Binary checksum
377
+ def compute_checksum(data, algorithm)
378
+ case algorithm.to_s.downcase
379
+ when "md5"
380
+ Digest::MD5.digest(data)
381
+ when "sha1"
382
+ Digest::SHA1.digest(data)
383
+ when "sha224"
384
+ Digest::SHA2.new(224).digest(data)
385
+ when "sha256"
386
+ Digest::SHA256.digest(data)
387
+ when "sha384"
388
+ Digest::SHA2.new(384).digest(data)
389
+ when "sha512"
390
+ Digest::SHA512.digest(data)
391
+ else
392
+ ""
393
+ end
394
+ end
395
+
396
+ # Compute checksum as hex string (for XML attributes)
397
+ #
398
+ # @param data [String] Data to checksum
399
+ # @param algorithm [String] Checksum algorithm
400
+ # @return [String] Hex checksum string
401
+ def compute_checksum_hex(data, algorithm)
402
+ case algorithm.to_s.downcase
403
+ when "md5"
404
+ Digest::MD5.hexdigest(data)
405
+ when "sha1"
406
+ Digest::SHA1.hexdigest(data)
407
+ when "sha224"
408
+ Digest::SHA2.new(224).hexdigest(data)
409
+ when "sha256"
410
+ Digest::SHA256.hexdigest(data)
411
+ when "sha384"
412
+ Digest::SHA2.new(384).hexdigest(data)
413
+ when "sha512"
414
+ Digest::SHA512.hexdigest(data)
415
+ else
416
+ ""
417
+ end
418
+ end
419
+
420
+ # Convert checksum name to constant
421
+ #
422
+ # @param name [String] Checksum name
423
+ # @return [Integer] Checksum constant
424
+ def checksum_to_constant(name)
425
+ case name.to_s.downcase
426
+ when "none"
427
+ CKSUM_NONE
428
+ when "sha1"
429
+ CKSUM_SHA1
430
+ when "md5"
431
+ CKSUM_MD5
432
+ else
433
+ CKSUM_OTHER
434
+ end
435
+ end
436
+
437
+ # Check if checksum needs name in header
438
+ #
439
+ # @param name [String] Checksum name
440
+ # @return [Boolean] true if name needed
441
+ def checksum_needs_name(name)
442
+ !["none", "sha1", "md5"].include?(name.to_s.downcase)
443
+ end
444
+
445
+ # Build TOC from entries
446
+ #
447
+ # @return [Toc] TOC object
448
+ def build_toc
449
+ toc = Toc.new
450
+ toc.checksum_style = @options[:toc_checksum]
451
+
452
+ @entries.each do |entry|
453
+ toc.add_entry(entry)
454
+ end
455
+
456
+ toc
457
+ end
458
+ end
459
+ end
460
+ end
461
+ end
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Formats
5
+ # XAR archive format support
6
+ #
7
+ # XAR (eXtensible ARchive) format is primarily used on macOS for:
8
+ # - Software packages (.pkg files)
9
+ # - OS installers
10
+ # - Software distribution
11
+ #
12
+ # Features:
13
+ # - GZIP-compressed XML Table of Contents (TOC)
14
+ # - Multiple compression algorithms (gzip, bzip2, lzma, xz, none)
15
+ # - Checksum verification (MD5, SHA1, SHA256, etc.)
16
+ # - Extended attributes (xattrs)
17
+ # - Hardlinks and symlinks
18
+ # - Device nodes and FIFOs
19
+ #
20
+ # @example Create XAR archive
21
+ # Omnizip::Formats::Xar.create('archive.xar') do |xar|
22
+ # xar.add_file('document.pdf')
23
+ # xar.add_directory('resources/')
24
+ # end
25
+ #
26
+ # @example Extract XAR archive
27
+ # Omnizip::Formats::Xar.extract('archive.xar', 'output/')
28
+ #
29
+ # @example List XAR contents
30
+ # entries = Omnizip::Formats::Xar.list('archive.xar')
31
+ # entries.each { |e| puts "#{e.name} (#{e.size} bytes)" }
32
+ module Xar
33
+ # Nested classes - autoloaded
34
+ autoload :Constants, "omnizip/formats/xar/constants"
35
+ autoload :Header, "omnizip/formats/xar/header"
36
+ autoload :Entry, "omnizip/formats/xar/entry"
37
+ autoload :Toc, "omnizip/formats/xar/toc"
38
+ autoload :Reader, "omnizip/formats/xar/reader"
39
+ autoload :Writer, "omnizip/formats/xar/writer"
40
+
41
+ # Re-export constants for external access
42
+ CKSUM_NONE = Constants::CKSUM_NONE
43
+ CKSUM_SHA1 = Constants::CKSUM_SHA1
44
+ CKSUM_MD5 = Constants::CKSUM_MD5
45
+ CKSUM_OTHER = Constants::CKSUM_OTHER
46
+
47
+ class << self
48
+ # Create XAR archive
49
+ #
50
+ # @param path [String] Output XAR file path
51
+ # @param options [Hash] Archive options
52
+ # @option options [String] :compression Compression algorithm (gzip, bzip2, lzma, xz, none)
53
+ # @option options [Integer] :compression_level Compression level (1-9)
54
+ # @option options [String] :toc_checksum TOC checksum algorithm (sha1, md5, sha256)
55
+ # @option options [String] :file_checksum File checksum algorithm (sha1, md5, sha256)
56
+ # @yield [writer] Block for adding files/directories
57
+ # @yieldparam writer [Writer] XAR writer
58
+ # @return [String] Path to created archive
59
+ #
60
+ # @example Create archive with gzip compression
61
+ # Omnizip::Formats::Xar.create('archive.xar', compression: 'gzip') do |xar|
62
+ # xar.add_file('config.yml')
63
+ # xar.add_directory('config.d/')
64
+ # end
65
+ #
66
+ # @example Create archive with bzip2 and SHA256 checksums
67
+ # Omnizip::Formats::Xar.create('archive.xar',
68
+ # compression: 'bzip2',
69
+ # toc_checksum: 'sha256',
70
+ # file_checksum: 'sha256'
71
+ # ) do |xar|
72
+ # xar.add_file('data.bin')
73
+ # end
74
+ def create(path, options = {})
75
+ Writer.create(path, options) do |writer|
76
+ yield writer if block_given?
77
+ end
78
+ end
79
+
80
+ # Open XAR archive for reading
81
+ #
82
+ # @param path [String] Path to XAR file
83
+ # @yield [reader] Block for reading archive
84
+ # @yieldparam reader [Reader] XAR reader
85
+ # @return [Reader] XAR reader
86
+ #
87
+ # @example Read XAR archive
88
+ # Omnizip::Formats::Xar.open('archive.xar') do |xar|
89
+ # xar.entries.each { |entry| puts entry.name }
90
+ # end
91
+ def open(path)
92
+ reader = Reader.open(path)
93
+
94
+ if block_given?
95
+ begin
96
+ yield reader
97
+ ensure
98
+ reader.close
99
+ end
100
+ else
101
+ reader
102
+ end
103
+ end
104
+
105
+ # List XAR archive contents
106
+ #
107
+ # @param path [String] Path to XAR file
108
+ # @return [Array<Entry>] Archive entries
109
+ #
110
+ # @example List archive contents
111
+ # entries = Omnizip::Formats::Xar.list('archive.xar')
112
+ # entries.each { |e| puts "#{e.name} (#{e.size} bytes)" }
113
+ def list(path)
114
+ open(path, &:entries) # rubocop:disable Security/Open
115
+ end
116
+
117
+ # Extract XAR archive
118
+ #
119
+ # @param xar_path [String] Path to XAR file
120
+ # @param output_dir [String] Output directory
121
+ #
122
+ # @example Extract archive
123
+ # Omnizip::Formats::Xar.extract('archive.xar', 'output/')
124
+ def extract(xar_path, output_dir)
125
+ open(xar_path) do |xar| # rubocop:disable Security/Open
126
+ xar.extract_all(output_dir)
127
+ end
128
+ end
129
+
130
+ # Get archive information
131
+ #
132
+ # @param path [String] Path to XAR file
133
+ # @return [Hash] Archive information
134
+ #
135
+ # @example Get archive info
136
+ # info = Omnizip::Formats::Xar.info('archive.xar')
137
+ # puts "Format: XAR version #{info[:header][:version]}"
138
+ # puts "Files: #{info[:file_count]}"
139
+ def info(path)
140
+ open(path, &:info) # rubocop:disable Security/Open
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end