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,349 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Formats
5
+ module Iso
6
+ # Rock Ridge Extensions for ISO 9660
7
+ #
8
+ # Implements System Use Sharing Protocol (SUSP) and Rock Ridge
9
+ # extensions to store Unix file attributes, permissions, symbolic links,
10
+ # and device nodes in ISO 9660 images.
11
+ #
12
+ # Rock Ridge allows ISO images to preserve full Unix filesystem semantics.
13
+ module RockRidge
14
+ # SUSP/Rock Ridge signature identifiers
15
+ module Signatures
16
+ SP = "SP" # System Use Sharing Protocol indicator
17
+ CE = "CE" # Continuation area
18
+ PX = "PX" # POSIX file attributes
19
+ PN = "PN" # POSIX device number
20
+ SL = "SL" # Symbolic link
21
+ NM = "NM" # Alternate name
22
+ CL = "CL" # Child link
23
+ PL = "PL" # Parent link
24
+ RE = "RE" # Relocated directory
25
+ TF = "TF" # Time stamps
26
+ SF = "SF" # Sparse file
27
+ end
28
+
29
+ # System Use Entry
30
+ class SUEntry
31
+ attr_accessor :signature, :length, :version, :data
32
+
33
+ # Initialize entry
34
+ #
35
+ # @param signature [String] 2-byte signature
36
+ # @param version [Integer] Entry version
37
+ # @param data [String] Entry data
38
+ def initialize(signature, version: 1, data: "")
39
+ @signature = signature
40
+ @length = 4 + data.bytesize
41
+ @version = version
42
+ @data = data
43
+ end
44
+
45
+ # Convert to binary
46
+ #
47
+ # @return [String] Binary representation
48
+ def to_binary
49
+ result = +""
50
+ result << @signature # 2 bytes
51
+ result << [@length].pack("C") # 1 byte
52
+ result << [@version].pack("C") # 1 byte
53
+ result << @data
54
+ result
55
+ end
56
+
57
+ # Parse from binary
58
+ #
59
+ # @param data [String] Binary data
60
+ # @param offset [Integer] Starting offset
61
+ # @return [SUEntry] Parsed entry
62
+ def self.parse(data, offset = 0)
63
+ signature = data[offset, 2]
64
+ length = data.getbyte(offset + 2)
65
+ version = data.getbyte(offset + 3)
66
+ entry_data = data[offset + 4, length - 4]
67
+
68
+ new(signature, version: version, data: entry_data)
69
+ end
70
+ end
71
+
72
+ # Add Rock Ridge extensions to directory record
73
+ #
74
+ # @param record_data [String] Directory record data
75
+ # @param file_stat [File::Stat] File statistics
76
+ # @param name [String] File name
77
+ # @param is_symlink [Boolean] Is this a symbolic link
78
+ # @return [String] Updated record with Rock Ridge fields
79
+ def self.add_extensions(record_data, file_stat, name, is_symlink: false)
80
+ system_use = +""
81
+
82
+ # Add SP entry (first entry in root directory only)
83
+ # This indicates Rock Ridge is being used
84
+ # For simplicity, we'll add to all entries
85
+
86
+ # Add PX (POSIX attributes)
87
+ system_use << build_px_entry(file_stat).to_binary
88
+
89
+ # Add TF (timestamps)
90
+ system_use << build_tf_entry(file_stat).to_binary
91
+
92
+ # Add NM (alternate name) if different from ISO name
93
+ unless name == File.basename(name).upcase
94
+ system_use << build_nm_entry(name).to_binary
95
+ end
96
+
97
+ # Add SL (symbolic link) if applicable
98
+ if is_symlink
99
+ link_target = File.readlink(file_stat)
100
+ system_use << build_sl_entry(link_target).to_binary
101
+ end
102
+
103
+ # Append system use to record
104
+ record_data + system_use
105
+ end
106
+
107
+ # Build PX (POSIX attributes) entry
108
+ #
109
+ # @param stat [File::Stat] File statistics
110
+ # @return [SUEntry] PX entry
111
+ def self.build_px_entry(stat)
112
+ data = +""
113
+
114
+ # File mode (both-endian)
115
+ data << [stat.mode].pack("V")
116
+ data << [stat.mode].pack("N")
117
+
118
+ # Number of links (both-endian)
119
+ data << [stat.nlink].pack("V")
120
+ data << [stat.nlink].pack("N")
121
+
122
+ # User ID (both-endian)
123
+ data << [stat.uid].pack("V")
124
+ data << [stat.uid].pack("N")
125
+
126
+ # Group ID (both-endian)
127
+ data << [stat.gid].pack("V")
128
+ data << [stat.gid].pack("N")
129
+
130
+ # Inode number (both-endian) - optional
131
+ data << [stat.ino].pack("V")
132
+ data << [stat.ino].pack("N")
133
+
134
+ SUEntry.new(Signatures::PX, data: data)
135
+ end
136
+
137
+ # Build TF (timestamps) entry
138
+ #
139
+ # @param stat [File::Stat] File statistics
140
+ # @return [SUEntry] TF entry
141
+ def self.build_tf_entry(stat)
142
+ # Flags indicating which timestamps are present
143
+ # Bit 0: Creation time
144
+ # Bit 1: Modify time
145
+ # Bit 2: Access time
146
+ # Bit 3: Attributes time
147
+ # Bit 4: Backup time
148
+ # Bit 5: Expiration time
149
+ # Bit 6: Effective time
150
+ # Bit 7: Long format (17 bytes instead of 7)
151
+
152
+ flags = 0b00000110 # Modify and access times, short format
153
+
154
+ data = +""
155
+ data << [flags].pack("C")
156
+
157
+ # Modification time (7-byte format)
158
+ data << encode_time_7byte(stat.mtime)
159
+
160
+ # Access time (7-byte format)
161
+ data << encode_time_7byte(stat.atime)
162
+
163
+ SUEntry.new(Signatures::TF, data: data)
164
+ end
165
+
166
+ # Build NM (alternate name) entry
167
+ #
168
+ # @param name [String] File name
169
+ # @return [SUEntry] NM entry
170
+ def self.build_nm_entry(name)
171
+ # Flags
172
+ # Bit 0: CONTINUE (name continues in next NM)
173
+ # Bit 1: CURRENT (name is ".")
174
+ # Bit 2: PARENT (name is "..")
175
+ flags = 0
176
+
177
+ data = +""
178
+ data << [flags].pack("C")
179
+ data << name
180
+
181
+ SUEntry.new(Signatures::NM, data: data)
182
+ end
183
+
184
+ # Build SL (symbolic link) entry
185
+ #
186
+ # @param target [String] Link target
187
+ # @return [SUEntry] SL entry
188
+ def self.build_sl_entry(target)
189
+ # Flags
190
+ # Bit 0: CONTINUE (link continues in next SL)
191
+ flags = 0
192
+
193
+ data = +""
194
+ data << [flags].pack("C")
195
+
196
+ # Component flags
197
+ # Bit 0: CONTINUE (component continues)
198
+ # Bit 1: CURRENT (component is ".")
199
+ # Bit 2: PARENT (component is "..")
200
+ # Bit 3: ROOT (component is root)
201
+ comp_flags = 0
202
+
203
+ # Component length
204
+ data << [comp_flags].pack("C")
205
+ data << [target.bytesize].pack("C")
206
+ data << target
207
+
208
+ SUEntry.new(Signatures::SL, data: data)
209
+ end
210
+
211
+ # Build PN (POSIX device number) entry
212
+ #
213
+ # @param stat [File::Stat] File statistics
214
+ # @return [SUEntry] PN entry
215
+ def self.build_pn_entry(stat)
216
+ data = +""
217
+
218
+ # Device number high (both-endian)
219
+ dev_high = (stat.rdev >> 32) & 0xFFFFFFFF
220
+ data << [dev_high].pack("V")
221
+ data << [dev_high].pack("N")
222
+
223
+ # Device number low (both-endian)
224
+ dev_low = stat.rdev & 0xFFFFFFFF
225
+ data << [dev_low].pack("V")
226
+ data << [dev_low].pack("N")
227
+
228
+ SUEntry.new(Signatures::PN, data: data)
229
+ end
230
+
231
+ # Encode time in 7-byte format
232
+ #
233
+ # @param time [Time] Time to encode
234
+ # @return [String] 7-byte encoded time
235
+ def self.encode_time_7byte(time)
236
+ [
237
+ time.year - 1900,
238
+ time.month,
239
+ time.day,
240
+ time.hour,
241
+ time.min,
242
+ time.sec,
243
+ 0, # GMT offset
244
+ ].pack("C7")
245
+ end
246
+
247
+ # Parse Rock Ridge extensions from system use field
248
+ #
249
+ # @param system_use [String] System use field data
250
+ # @return [Hash] Parsed attributes
251
+ def self.parse_extensions(system_use)
252
+ attributes = {}
253
+ offset = 0
254
+
255
+ while offset < system_use.bytesize
256
+ entry = SUEntry.parse(system_use, offset)
257
+
258
+ case entry.signature
259
+ when Signatures::PX
260
+ attributes[:posix] = parse_px_entry(entry)
261
+ when Signatures::TF
262
+ attributes[:times] = parse_tf_entry(entry)
263
+ when Signatures::NM
264
+ attributes[:name] = parse_nm_entry(entry)
265
+ when Signatures::SL
266
+ attributes[:symlink] = parse_sl_entry(entry)
267
+ end
268
+
269
+ offset += entry.length
270
+ end
271
+
272
+ attributes
273
+ end
274
+
275
+ # Parse PX entry
276
+ #
277
+ # @param entry [SUEntry] PX entry
278
+ # @return [Hash] Parsed POSIX attributes
279
+ def self.parse_px_entry(entry)
280
+ data = entry.data
281
+ {
282
+ mode: data[0, 4].unpack1("V"),
283
+ nlink: data[8, 4].unpack1("V"),
284
+ uid: data[16, 4].unpack1("V"),
285
+ gid: data[24, 4].unpack1("V"),
286
+ ino: data[32, 4].unpack1("V"),
287
+ }
288
+ end
289
+
290
+ # Parse TF entry
291
+ #
292
+ # @param entry [SUEntry] TF entry
293
+ # @return [Hash] Parsed timestamps
294
+ def self.parse_tf_entry(entry)
295
+ # Parse based on flags
296
+ flags = entry.data.getbyte(0)
297
+ times = {}
298
+
299
+ offset = 1
300
+ if flags & 0x02 # Modify time
301
+ times[:mtime] = parse_time_7byte(entry.data[offset, 7])
302
+ offset += 7
303
+ end
304
+
305
+ if flags & 0x04 # Access time
306
+ times[:atime] = parse_time_7byte(entry.data[offset, 7])
307
+ end
308
+
309
+ times
310
+ end
311
+
312
+ # Parse NM entry
313
+ #
314
+ # @param entry [SUEntry] NM entry
315
+ # @return [String] Alternate name
316
+ def self.parse_nm_entry(entry)
317
+ entry.data[1..]
318
+ end
319
+
320
+ # Parse SL entry
321
+ #
322
+ # @param entry [SUEntry] SL entry
323
+ # @return [String] Symbolic link target
324
+ def self.parse_sl_entry(entry)
325
+ # Skip flags byte, component flags, read length and target
326
+ comp_len = entry.data.getbyte(2)
327
+ entry.data[3, comp_len]
328
+ end
329
+
330
+ # Parse 7-byte time format
331
+ #
332
+ # @param data [String] 7-byte time data
333
+ # @return [Time] Parsed time
334
+ def self.parse_time_7byte(data)
335
+ year = 1900 + data.getbyte(0)
336
+ month = data.getbyte(1)
337
+ day = data.getbyte(2)
338
+ hour = data.getbyte(3)
339
+ minute = data.getbyte(4)
340
+ second = data.getbyte(5)
341
+
342
+ Time.new(year, month, day, hour, minute, second)
343
+ rescue ArgumentError
344
+ Time.now
345
+ end
346
+ end
347
+ end
348
+ end
349
+ end
@@ -0,0 +1,319 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "time"
4
+
5
+ module Omnizip
6
+ module Formats
7
+ module Iso
8
+ # ISO 9660 Volume Descriptor Builder
9
+ #
10
+ # Builds primary and supplementary volume descriptors for ISO images.
11
+ # Handles proper encoding of volume metadata and root directory information.
12
+ class VolumeBuilder
13
+ # @return [String] Volume identifier
14
+ attr_reader :volume_id
15
+
16
+ # @return [String] System identifier
17
+ attr_reader :system_id
18
+
19
+ # @return [String] Publisher
20
+ attr_reader :publisher
21
+
22
+ # @return [String] Preparer
23
+ attr_reader :preparer
24
+
25
+ # @return [String] Application
26
+ attr_reader :application
27
+
28
+ # @return [Integer] ISO level
29
+ attr_reader :level
30
+
31
+ # @return [Boolean] Rock Ridge enabled
32
+ attr_reader :rock_ridge
33
+
34
+ # @return [Boolean] Joliet enabled
35
+ attr_reader :joliet
36
+
37
+ # Initialize volume builder
38
+ #
39
+ # @param options [Hash] Builder options
40
+ def initialize(options = {})
41
+ @volume_id = options.fetch(:volume_id, "OMNIZIP")
42
+ @system_id = options.fetch(:system_id, "LINUX")
43
+ @publisher = options.fetch(:publisher, "")
44
+ @preparer = options.fetch(:preparer, "")
45
+ @application = options.fetch(:application, "OMNIZIP")
46
+ @level = options.fetch(:level, 2)
47
+ @rock_ridge = options.fetch(:rock_ridge, false)
48
+ @joliet = options.fetch(:joliet, false)
49
+ end
50
+
51
+ # Build primary volume descriptor
52
+ #
53
+ # @param root_dir [Hash] Root directory information
54
+ # @return [String] Primary VD sector (2048 bytes)
55
+ def build_primary(root_dir)
56
+ sector = +""
57
+
58
+ # Byte 0: Volume descriptor type (1 = Primary)
59
+ sector << [Iso::VD_PRIMARY].pack("C")
60
+
61
+ # Bytes 1-5: Standard identifier "CD001"
62
+ sector << VolumeDescriptor::ISO_IDENTIFIER
63
+
64
+ # Byte 6: Version (1)
65
+ sector << [1].pack("C")
66
+
67
+ # Byte 7: Unused (0)
68
+ sector << "\x00"
69
+
70
+ # Bytes 8-39: System identifier (a-characters, space-padded)
71
+ sector << pad_a_string(@system_id, 32)
72
+
73
+ # Bytes 40-71: Volume identifier (d-characters, space-padded)
74
+ sector << pad_d_string(@volume_id, 32)
75
+
76
+ # Bytes 72-79: Unused (zeros)
77
+ sector << ("\x00" * 8)
78
+
79
+ # Bytes 80-87: Volume space size (both-endian)
80
+ volume_sectors = root_dir[:total_sectors] || 100
81
+ sector << [volume_sectors].pack("V") # Little-endian
82
+ sector << [volume_sectors].pack("N") # Big-endian
83
+
84
+ # Bytes 88-119: Unused (zeros)
85
+ sector << ("\x00" * 32)
86
+
87
+ # Bytes 120-123: Volume set size (both-endian)
88
+ sector << [1].pack("v")
89
+ sector << [1].pack("n")
90
+
91
+ # Bytes 124-127: Volume sequence number (both-endian)
92
+ sector << [1].pack("v")
93
+ sector << [1].pack("n")
94
+
95
+ # Bytes 128-131: Logical block size (both-endian)
96
+ sector << [Iso::SECTOR_SIZE].pack("v")
97
+ sector << [Iso::SECTOR_SIZE].pack("n")
98
+
99
+ # Bytes 132-139: Path table size (both-endian)
100
+ path_table_size = root_dir[:path_table_size] || 10
101
+ sector << [path_table_size].pack("V")
102
+ sector << [path_table_size].pack("N")
103
+
104
+ # Bytes 140-143: Location of type L path table
105
+ sector << [root_dir[:path_table_location] || 19].pack("V")
106
+
107
+ # Bytes 144-147: Location of optional type L path table
108
+ sector << [0].pack("V")
109
+
110
+ # Bytes 148-151: Location of type M path table
111
+ sector << [root_dir[:path_table_location_be] || 20].pack("N")
112
+
113
+ # Bytes 152-155: Location of optional type M path table
114
+ sector << [0].pack("N")
115
+
116
+ # Bytes 156-189: Root directory record (34 bytes)
117
+ sector << build_root_directory_record(root_dir)
118
+
119
+ # Bytes 190-317: Volume set identifier
120
+ sector << pad_d_string("", 128)
121
+
122
+ # Bytes 318-445: Publisher identifier
123
+ sector << pad_a_string(@publisher, 128)
124
+
125
+ # Bytes 446-573: Data preparer identifier
126
+ sector << pad_a_string(@preparer, 128)
127
+
128
+ # Bytes 574-701: Application identifier
129
+ sector << pad_a_string(@application, 128)
130
+
131
+ # Bytes 702-738: Copyright file identifier
132
+ sector << pad_d_string("", 37)
133
+
134
+ # Bytes 739-775: Abstract file identifier
135
+ sector << pad_d_string("", 37)
136
+
137
+ # Bytes 776-812: Bibliographic file identifier
138
+ sector << pad_d_string("", 37)
139
+
140
+ # Bytes 813-829: Volume creation date/time
141
+ now = Time.now
142
+ sector << encode_volume_datetime(now)
143
+
144
+ # Bytes 830-846: Volume modification date/time
145
+ sector << encode_volume_datetime(now)
146
+
147
+ # Bytes 847-863: Volume expiration date/time (not set)
148
+ sector << encode_volume_datetime(nil)
149
+
150
+ # Bytes 864-880: Volume effective date/time (not set)
151
+ sector << encode_volume_datetime(nil)
152
+
153
+ # Byte 881: File structure version (1)
154
+ sector << [1].pack("C")
155
+
156
+ # Byte 882: Unused (0)
157
+ sector << "\x00"
158
+
159
+ # Bytes 883-1395: Application use
160
+ sector << ("\x00" * 513)
161
+
162
+ # Bytes 1396-2047: Reserved
163
+ sector << ("\x00" * 652)
164
+
165
+ sector
166
+ end
167
+
168
+ # Build Joliet supplementary volume descriptor
169
+ #
170
+ # @param root_dir [Hash] Root directory information
171
+ # @return [String] Joliet SVD sector (2048 bytes)
172
+ def build_joliet(root_dir)
173
+ # Joliet is similar to primary VD but with:
174
+ # - Type = 2 (supplementary)
175
+ # - UCS-2 encoding for strings
176
+ # - Escape sequences for character set
177
+
178
+ sector = build_primary(root_dir)
179
+
180
+ # Modify type to supplementary
181
+ sector.setbyte(0, Iso::VD_SUPPLEMENTARY)
182
+
183
+ # Add escape sequences for UCS-2
184
+ # Bytes 88-90: %/@ %/C %/E for levels 1, 2, 3
185
+ sector.setbyte(88, 0x25) # '%'
186
+ sector.setbyte(89, 0x2F) # '/'
187
+ sector.setbyte(90, 0x45) # 'E'
188
+
189
+ # Convert volume ID to UCS-2
190
+ volume_id_ucs2 = @volume_id.encode("UTF-16BE")
191
+ padded_volume_id = pad_string(volume_id_ucs2,
192
+ 32).force_encoding("ASCII-8BIT")
193
+
194
+ # Replace bytes 40-71 with UCS-2 volume ID
195
+ 32.times do |i|
196
+ sector.setbyte(40 + i, padded_volume_id.getbyte(i))
197
+ end
198
+
199
+ sector
200
+ end
201
+
202
+ private
203
+
204
+ # Build root directory record
205
+ #
206
+ # @param root_dir [Hash] Root directory info
207
+ # @return [String] 34-byte directory record
208
+ def build_root_directory_record(root_dir)
209
+ record = +""
210
+
211
+ # Length of record (34 bytes for root)
212
+ record << [34].pack("C")
213
+
214
+ # Extended attribute length (0)
215
+ record << [0].pack("C")
216
+
217
+ # Location of extent (both-endian)
218
+ location = root_dir[:location] || 21
219
+ record << [location].pack("V")
220
+ record << [location].pack("N")
221
+
222
+ # Data length (both-endian)
223
+ data_length = root_dir[:size] || Iso::SECTOR_SIZE
224
+ record << [data_length].pack("V")
225
+ record << [data_length].pack("N")
226
+
227
+ # Recording date
228
+ record << encode_record_datetime(Time.now)
229
+
230
+ # Flags (directory)
231
+ record << [Iso::FLAG_DIRECTORY].pack("C")
232
+
233
+ # File unit size, interleave gap
234
+ record << [0, 0].pack("C2")
235
+
236
+ # Volume sequence number (both-endian)
237
+ record << [1].pack("v")
238
+ record << [1].pack("n")
239
+
240
+ # File identifier length (1 for root)
241
+ record << [1].pack("C")
242
+
243
+ # File identifier (0x00 for root)
244
+ record << "\x00"
245
+
246
+ record
247
+ end
248
+
249
+ # Encode volume date/time (17-byte format)
250
+ #
251
+ # @param time [Time, nil] Time to encode
252
+ # @return [String] 17-byte encoded time
253
+ def encode_volume_datetime(time)
254
+ if time.nil?
255
+ # All zeros for unset time
256
+ return "#{'0' * 16}\u0000"
257
+ end
258
+
259
+ format(
260
+ "%04d%02d%02d%02d%02d%02d%02d",
261
+ time.year,
262
+ time.month,
263
+ time.day,
264
+ time.hour,
265
+ time.min,
266
+ time.sec,
267
+ 0, # Centiseconds
268
+ ) + [0].pack("c") # GMT offset
269
+ end
270
+
271
+ # Encode recording date/time (7-byte format)
272
+ #
273
+ # @param time [Time] Time to encode
274
+ # @return [String] 7-byte encoded time
275
+ def encode_record_datetime(time)
276
+ [
277
+ time.year - 1900,
278
+ time.month,
279
+ time.day,
280
+ time.hour,
281
+ time.min,
282
+ time.sec,
283
+ 0, # GMT offset
284
+ ].pack("C7")
285
+ end
286
+
287
+ # Pad string with spaces (a-characters)
288
+ #
289
+ # @param str [String] String to pad
290
+ # @param length [Integer] Target length
291
+ # @return [String] Padded string
292
+ def pad_a_string(str, length)
293
+ str = str[0, length] if str.bytesize > length
294
+ str + (" " * (length - str.bytesize))
295
+ end
296
+
297
+ # Pad string with spaces (d-characters)
298
+ #
299
+ # @param str [String] String to pad
300
+ # @param length [Integer] Target length
301
+ # @return [String] Padded string
302
+ def pad_d_string(str, length)
303
+ pad_a_string(str, length)
304
+ end
305
+
306
+ # Pad generic string
307
+ #
308
+ # @param str [String] String to pad
309
+ # @param length [Integer] Target length
310
+ # @return [String] Padded string
311
+ def pad_string(str, length)
312
+ str = str[0, length] if str.bytesize > length
313
+ padding = "\x00".encode(str.encoding) * (length - str.bytesize)
314
+ str + padding
315
+ end
316
+ end
317
+ end
318
+ end
319
+ end