omnizip 0.3.8 → 0.3.10

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 (201) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +51 -50
  3. data/Gemfile +2 -0
  4. data/Rakefile +3 -0
  5. data/TODO.refactor/00-overview.md +67 -0
  6. data/TODO.refactor/01-registry-base-class.md +81 -0
  7. data/TODO.refactor/02-error-hierarchy.md +57 -0
  8. data/TODO.refactor/03-autoload-entry-point.md +69 -0
  9. data/TODO.refactor/04-filter-base-consolidation.md +49 -0
  10. data/TODO.refactor/05-send-private-methods.md +64 -0
  11. data/TODO.refactor/06-instance-variable-access.md +69 -0
  12. data/TODO.refactor/07-respond-to-replacement.md +91 -0
  13. data/TODO.refactor/08-spec-doubles.md +27 -0
  14. data/TODO.refactor/09-cli-shared-module.md +35 -0
  15. data/TODO.refactor/10-format-detector-ocp.md +34 -0
  16. data/TODO.refactor/11-convenience-decoupling.md +38 -0
  17. data/TODO.refactor/12-thread-safety.md +8 -0
  18. data/TODO.refactor/13-lutaml-model-migration.md +82 -0
  19. data/TODO.refactor/14-add-missing-specs.md +25 -0
  20. data/lib/omnizip/algorithm.rb +0 -2
  21. data/lib/omnizip/algorithm_registry.rb +29 -57
  22. data/lib/omnizip/algorithms/lzma/bit_model.rb +1 -1
  23. data/lib/omnizip/algorithms/lzma/dictionary.rb +4 -3
  24. data/lib/omnizip/algorithms/lzma/distance_coder.rb +5 -102
  25. data/lib/omnizip/algorithms/lzma/length_coder.rb +4 -92
  26. data/lib/omnizip/algorithms/lzma/literal_decoder.rb +4 -119
  27. data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +2 -0
  28. data/lib/omnizip/algorithms/lzma/match_finder.rb +59 -29
  29. data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +20 -12
  30. data/lib/omnizip/algorithms/lzma/range_decoder.rb +77 -269
  31. data/lib/omnizip/algorithms/lzma/range_encoder.rb +0 -9
  32. data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +0 -15
  33. data/lib/omnizip/algorithms/lzma/xz_state.rb +0 -8
  34. data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +189 -968
  35. data/lib/omnizip/algorithms/lzma2/encoder.rb +0 -2
  36. data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +0 -2
  37. data/lib/omnizip/algorithms/lzma2/properties.rb +0 -2
  38. data/lib/omnizip/algorithms/ppmd7/model.rb +1 -1
  39. data/lib/omnizip/algorithms/ppmd8/context.rb +0 -2
  40. data/lib/omnizip/algorithms/ppmd8/model.rb +1 -1
  41. data/lib/omnizip/algorithms/ppmd8.rb +0 -2
  42. data/lib/omnizip/algorithms/ppmd_base.rb +0 -2
  43. data/lib/omnizip/algorithms/sevenzip_lzma2.rb +0 -5
  44. data/lib/omnizip/algorithms/xz_lzma2.rb +0 -5
  45. data/lib/omnizip/algorithms/zstandard/frame/header.rb +3 -5
  46. data/lib/omnizip/algorithms.rb +1 -0
  47. data/lib/omnizip/archive_handler.rb +75 -0
  48. data/lib/omnizip/archive_handlers/tar_handler.rb +51 -0
  49. data/lib/omnizip/archive_handlers/zip_handler.rb +73 -0
  50. data/lib/omnizip/archive_handlers.rb +11 -0
  51. data/lib/omnizip/checksum_registry.rb +23 -96
  52. data/lib/omnizip/cli/shared.rb +31 -0
  53. data/lib/omnizip/cli.rb +6 -43
  54. data/lib/omnizip/commands/archive_create_command.rb +0 -6
  55. data/lib/omnizip/commands/archive_extract_command.rb +0 -4
  56. data/lib/omnizip/commands/archive_list_command.rb +0 -4
  57. data/lib/omnizip/commands/archive_repair_command.rb +0 -2
  58. data/lib/omnizip/commands/archive_verify_command.rb +0 -2
  59. data/lib/omnizip/commands/compress_command.rb +0 -2
  60. data/lib/omnizip/commands/decompress_command.rb +0 -2
  61. data/lib/omnizip/commands/list_command.rb +0 -2
  62. data/lib/omnizip/commands/metadata_command.rb +0 -5
  63. data/lib/omnizip/commands/parity_create_command.rb +0 -2
  64. data/lib/omnizip/commands/parity_repair_command.rb +0 -2
  65. data/lib/omnizip/commands/parity_verify_command.rb +0 -2
  66. data/lib/omnizip/commands/profile_list_command.rb +0 -2
  67. data/lib/omnizip/commands/profile_show_command.rb +0 -2
  68. data/lib/omnizip/convenience.rb +111 -234
  69. data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +1 -1
  70. data/lib/omnizip/crypto/aes256/cipher.rb +6 -1
  71. data/lib/omnizip/error.rb +22 -18
  72. data/lib/omnizip/filter.rb +5 -3
  73. data/lib/omnizip/filter_registry.rb +74 -98
  74. data/lib/omnizip/filters/bcj2/decoder.rb +196 -130
  75. data/lib/omnizip/filters/bcj2.rb +0 -2
  76. data/lib/omnizip/filters/bcj_x86.rb +0 -2
  77. data/lib/omnizip/filters/filter_base.rb +4 -70
  78. data/lib/omnizip/filters/registry.rb +0 -2
  79. data/lib/omnizip/format_detector.rb +21 -12
  80. data/lib/omnizip/format_registry.rb +79 -38
  81. data/lib/omnizip/formats/bzip2_file.rb +0 -2
  82. data/lib/omnizip/formats/cpio/entry.rb +0 -2
  83. data/lib/omnizip/formats/cpio/reader.rb +0 -1
  84. data/lib/omnizip/formats/cpio/writer.rb +0 -1
  85. data/lib/omnizip/formats/cpio.rb +0 -1
  86. data/lib/omnizip/formats/format_spec_loader.rb +1 -1
  87. data/lib/omnizip/formats/gzip.rb +0 -2
  88. data/lib/omnizip/formats/iso/directory_record.rb +6 -3
  89. data/lib/omnizip/formats/iso/reader.rb +2 -2
  90. data/lib/omnizip/formats/iso.rb +0 -1
  91. data/lib/omnizip/formats/lzip.rb +5 -25
  92. data/lib/omnizip/formats/lzma_alone.rb +7 -25
  93. data/lib/omnizip/formats/msi/cab_extractor.rb +181 -0
  94. data/lib/omnizip/formats/msi/constants.rb +157 -0
  95. data/lib/omnizip/formats/msi/directory_resolver.rb +188 -0
  96. data/lib/omnizip/formats/msi/entry.rb +128 -0
  97. data/lib/omnizip/formats/msi/reader.rb +301 -0
  98. data/lib/omnizip/formats/msi/string_pool.rb +246 -0
  99. data/lib/omnizip/formats/msi/table_parser.rb +244 -0
  100. data/lib/omnizip/formats/msi.rb +84 -0
  101. data/lib/omnizip/formats/ole/allocation_table.rb +10 -1
  102. data/lib/omnizip/formats/ole/dirent.rb +20 -3
  103. data/lib/omnizip/formats/ole/header.rb +0 -1
  104. data/lib/omnizip/formats/ole/ranges_io.rb +21 -3
  105. data/lib/omnizip/formats/ole/storage.rb +19 -4
  106. data/lib/omnizip/formats/ole.rb +0 -2
  107. data/lib/omnizip/formats/rar/block_parser.rb +0 -1
  108. data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +1 -1
  109. data/lib/omnizip/formats/rar/decompressor.rb +38 -1
  110. data/lib/omnizip/formats/rar/header.rb +0 -1
  111. data/lib/omnizip/formats/rar/rar5/writer.rb +0 -2
  112. data/lib/omnizip/formats/rar/reader.rb +2 -3
  113. data/lib/omnizip/formats/rar/writer.rb +0 -1
  114. data/lib/omnizip/formats/rar.rb +2 -2
  115. data/lib/omnizip/formats/rpm/entry.rb +0 -1
  116. data/lib/omnizip/formats/rpm/header.rb +3 -8
  117. data/lib/omnizip/formats/rpm/lead.rb +37 -26
  118. data/lib/omnizip/formats/rpm/tag.rb +0 -1
  119. data/lib/omnizip/formats/rpm/writer.rb +0 -1
  120. data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +98 -61
  121. data/lib/omnizip/formats/seven_zip/coder_chain.rb +1 -2
  122. data/lib/omnizip/formats/seven_zip/encoded_header.rb +0 -1
  123. data/lib/omnizip/formats/seven_zip/encrypted_header.rb +0 -1
  124. data/lib/omnizip/formats/seven_zip/header.rb +0 -1
  125. data/lib/omnizip/formats/seven_zip/header_encryptor.rb +0 -1
  126. data/lib/omnizip/formats/seven_zip/header_writer.rb +22 -61
  127. data/lib/omnizip/formats/seven_zip/models/file_entry.rb +1 -1
  128. data/lib/omnizip/formats/seven_zip/parser.rb +14 -13
  129. data/lib/omnizip/formats/seven_zip/reader.rb +82 -19
  130. data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +0 -15
  131. data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +0 -1
  132. data/lib/omnizip/formats/seven_zip/writer.rb +22 -68
  133. data/lib/omnizip/formats/seven_zip.rb +63 -5
  134. data/lib/omnizip/formats/tar/entry.rb +0 -2
  135. data/lib/omnizip/formats/tar/header.rb +0 -2
  136. data/lib/omnizip/formats/tar/reader.rb +0 -2
  137. data/lib/omnizip/formats/tar/writer.rb +0 -2
  138. data/lib/omnizip/formats/tar.rb +0 -1
  139. data/lib/omnizip/formats/xar/entry.rb +0 -1
  140. data/lib/omnizip/formats/xar/header.rb +0 -1
  141. data/lib/omnizip/formats/xar/reader.rb +0 -1
  142. data/lib/omnizip/formats/xar/toc.rb +3 -3
  143. data/lib/omnizip/formats/xar/writer.rb +11 -3
  144. data/lib/omnizip/formats/xar.rb +0 -1
  145. data/lib/omnizip/formats/xz/reader.rb +7 -3
  146. data/lib/omnizip/formats/xz.rb +3 -40
  147. data/lib/omnizip/formats/xz_impl/block_decoder.rb +4 -10
  148. data/lib/omnizip/formats/xz_impl/block_encoder.rb +0 -2
  149. data/lib/omnizip/formats/xz_impl/block_header_parser.rb +0 -2
  150. data/lib/omnizip/formats/xz_impl/index_decoder.rb +0 -1
  151. data/lib/omnizip/formats/xz_impl/index_encoder.rb +0 -1
  152. data/lib/omnizip/formats/xz_impl/stream_encoder.rb +1 -1
  153. data/lib/omnizip/formats/xz_impl/stream_footer.rb +0 -1
  154. data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +0 -1
  155. data/lib/omnizip/formats/xz_impl/stream_header.rb +0 -1
  156. data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +0 -2
  157. data/lib/omnizip/formats/zip/central_directory_header.rb +2 -3
  158. data/lib/omnizip/formats/zip/end_of_central_directory.rb +0 -2
  159. data/lib/omnizip/formats/zip/local_file_header.rb +0 -2
  160. data/lib/omnizip/formats/zip/reader.rb +12 -2
  161. data/lib/omnizip/formats/zip/writer.rb +73 -1
  162. data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +0 -2
  163. data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +0 -2
  164. data/lib/omnizip/formats/zip/zip64_extra_field.rb +0 -2
  165. data/lib/omnizip/formats/zip.rb +0 -1
  166. data/lib/omnizip/formats.rb +9 -22
  167. data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +2 -2
  168. data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +1 -1
  169. data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +0 -6
  170. data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +18 -185
  171. data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +3 -3
  172. data/lib/omnizip/io/source.rb +136 -0
  173. data/lib/omnizip/io.rb +2 -0
  174. data/lib/omnizip/link_handler.rb +7 -3
  175. data/lib/omnizip/metadata/metadata_editor.rb +1 -1
  176. data/lib/omnizip/models/algorithm_metadata.rb +33 -60
  177. data/lib/omnizip/models/compression_options.rb +40 -53
  178. data/lib/omnizip/models/conversion_options.rb +9 -18
  179. data/lib/omnizip/models/parallel_options.rb +25 -0
  180. data/lib/omnizip/optimization_registry.rb +8 -44
  181. data/lib/omnizip/parallel/job_scheduler.rb +26 -8
  182. data/lib/omnizip/parallel/parallel_compressor.rb +10 -20
  183. data/lib/omnizip/parallel/parallel_extractor.rb +20 -11
  184. data/lib/omnizip/parity/par2_repairer.rb +5 -5
  185. data/lib/omnizip/parity/par2_verifier.rb +27 -22
  186. data/lib/omnizip/parity.rb +4 -4
  187. data/lib/omnizip/password/encryption_registry.rb +11 -50
  188. data/lib/omnizip/password/zip_crypto_strategy.rb +1 -4
  189. data/lib/omnizip/pipe/stream_decompressor.rb +2 -3
  190. data/lib/omnizip/profile/archive_profile.rb +0 -2
  191. data/lib/omnizip/profile/binary_profile.rb +0 -2
  192. data/lib/omnizip/profile/compression_profile.rb +0 -1
  193. data/lib/omnizip/profile/profile_detector.rb +0 -2
  194. data/lib/omnizip/profile/text_profile.rb +0 -2
  195. data/lib/omnizip/profile.rb +0 -2
  196. data/lib/omnizip/registry.rb +112 -0
  197. data/lib/omnizip/version.rb +1 -1
  198. data/lib/omnizip/zip/file.rb +20 -9
  199. data/lib/omnizip.rb +26 -55
  200. data/lib/tasks/msi_test_files.rake +66 -0
  201. metadata +57 -6
@@ -17,10 +17,6 @@ module Omnizip
17
17
  # @option options [Integer] :dict_size Dictionary size (default: 8MB to match XZ Utils preset 6)
18
18
  # @option options [Integer] :check Check type (default: CRC64)
19
19
  def create(input, output = nil, options = {})
20
- require "omnizip/formats/xz_impl"
21
- require "omnizip/formats/xz_const"
22
- require "omnizip/formats/xz_impl/stream_encoder"
23
-
24
20
  encoder = ::Omnizip::Formats::XzImpl::StreamEncoder.new(
25
21
  check_type: options[:check] || ::Omnizip::Formats::XzConst::CHECK_CRC64,
26
22
  dict_size: options[:dict_size] || (64 * 1024 * 1024),
@@ -29,11 +25,7 @@ module Omnizip
29
25
  compressed = encoder.encode(input)
30
26
 
31
27
  if output
32
- if output.respond_to?(:write)
33
- output.write(compressed)
34
- else
35
- File.binwrite(output, compressed)
36
- end
28
+ Omnizip::IO::Sink.for(output).write(compressed)
37
29
  else
38
30
  compressed
39
31
  end
@@ -72,42 +64,13 @@ module Omnizip
72
64
  # @param options [Hash] Options (reserved for future use)
73
65
  # @return [String, nil] Decompressed data (if output is nil)
74
66
  def decompress(input, output = nil, _options = {})
75
- # Handle raw data string vs file path
76
- data = if input.respond_to?(:read)
77
- # Already an IO object - read content
78
- if input.respond_to?(:size)
79
- # Seekable IO (File, etc.) - read without consuming
80
- original_pos = input.pos
81
- content = input.read
82
- input.seek(original_pos)
83
- else
84
- # Non-seekable IO - read and consume
85
- content = input.read
86
- end
87
- content
88
- elsif input.is_a?(String)
89
- # Could be file path or raw data
90
- # If string contains null byte, it's definitely data (not a path)
91
- # Also check if it's a valid file path first
92
- if !input.include?("\0") && File.exist?(input)
93
- File.binread(input)
94
- else
95
- input.b
96
- end
97
- else
98
- raise ArgumentError,
99
- "Input must be a String or IO object"
100
- end
67
+ data = Omnizip::IO::Source.for(input).read
101
68
 
102
69
  # Detect format and decode
103
70
  decompressed = decode_lzma_data(data)
104
71
 
105
72
  if output
106
- if output.respond_to?(:write)
107
- output.write(decompressed)
108
- else
109
- File.binwrite(output, decompressed)
110
- end
73
+ Omnizip::IO::Sink.for(output).write(decompressed)
111
74
  nil
112
75
  else
113
76
  decompressed
@@ -567,11 +567,8 @@ module Omnizip
567
567
 
568
568
  # Create LZMA2 decoder with raw_mode for XZ format
569
569
  decoder = Omnizip::Implementations::XZUtils::LZMA2::Decoder.new(input_buffer,
570
- raw_mode: true)
571
-
572
- # Set dict_size directly since we skipped property byte reading
573
- decoder.instance_variable_set(:@dict_size, dict_size)
574
- decoder.instance_variable_set(:@properties, Omnizip::Algorithms::LZMA2::Properties.new(dict_size))
570
+ raw_mode: true,
571
+ dict_size: dict_size)
575
572
 
576
573
  # Decode stream
577
574
  uncompressed_data = decoder.decode_stream
@@ -623,11 +620,8 @@ module Omnizip
623
620
 
624
621
  # Create LZMA2 decoder with raw_mode for XZ format
625
622
  decoder = Omnizip::Implementations::XZUtils::LZMA2::Decoder.new(input_buffer,
626
- raw_mode: true)
627
-
628
- # Set dict_size directly since we skipped property byte reading
629
- decoder.instance_variable_set(:@dict_size, dict_size)
630
- decoder.instance_variable_set(:@properties, Omnizip::Algorithms::LZMA2::Properties.new(dict_size))
623
+ raw_mode: true,
624
+ dict_size: dict_size)
631
625
 
632
626
  # Decode stream
633
627
  decoder.decode_stream
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "stringio"
4
- require "omnizip/algorithms/xz_lzma2"
5
- require "omnizip/checksums/crc64"
6
4
  require "zlib"
7
5
 
8
6
  module Omnizip
@@ -22,8 +22,6 @@
22
22
 
23
23
  require "stringio"
24
24
  require "zlib"
25
- require "omnizip/error"
26
- require "omnizip/checksums/verifier"
27
25
 
28
26
  module Omnizip
29
27
  module Formats
@@ -22,7 +22,6 @@
22
22
 
23
23
  require "stringio"
24
24
  require "zlib"
25
- require "omnizip/error"
26
25
 
27
26
  module Omnizip
28
27
  module Formats
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "stringio"
4
4
  require "zlib"
5
- require "omnizip/error"
6
5
 
7
6
  module Omnizip
8
7
  module Formats
@@ -25,7 +25,7 @@ module Omnizip
25
25
  output.set_encoding(Encoding::BINARY)
26
26
 
27
27
  # Read input data
28
- input_data = input.respond_to?(:read) ? input.read : input.to_s
28
+ input_data = Omnizip::IO::Source.for(input).read
29
29
  input_data = input_data.dup.force_encoding(Encoding::BINARY)
30
30
 
31
31
  # 1. Write Stream Header
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "zlib"
4
- require "omnizip/error"
5
4
 
6
5
  module Omnizip
7
6
  module Formats
@@ -21,7 +21,6 @@
21
21
  # DEALINGS IN THE SOFTWARE.
22
22
 
23
23
  require "zlib"
24
- require "omnizip/error"
25
24
 
26
25
  module Omnizip
27
26
  module Formats
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "zlib"
4
- require "omnizip/error"
5
4
 
6
5
  module Omnizip
7
6
  module Formats
@@ -21,8 +21,6 @@
21
21
  # DEALINGS IN THE SOFTWARE.
22
22
 
23
23
  require "zlib"
24
- require "omnizip/error"
25
- require "omnizip/checksums/verifier"
26
24
 
27
25
  module Omnizip
28
26
  module Formats
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "omnizip/formats/zip"
4
-
5
3
  module Omnizip
6
4
  module Formats
7
5
  module Zip
@@ -14,7 +12,8 @@ module Omnizip
14
12
  :crc32, :compressed_size, :uncompressed_size,
15
13
  :filename_length, :extra_field_length, :comment_length,
16
14
  :disk_number_start, :internal_attributes, :external_attributes,
17
- :local_header_offset, :filename, :extra_field, :comment
15
+ :local_header_offset, :filename, :extra_field, :comment,
16
+ :cached_original_data
18
17
 
19
18
  def initialize(
20
19
  signature: CENTRAL_DIRECTORY_SIGNATURE,
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "omnizip/formats/zip"
4
-
5
3
  module Omnizip
6
4
  module Formats
7
5
  module Zip
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "omnizip/formats/zip"
4
-
5
3
  module Omnizip
6
4
  module Formats
7
5
  module Zip
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "omnizip/formats/zip"
4
-
5
3
  module Omnizip
6
4
  module Formats
7
5
  module Zip
@@ -149,6 +147,18 @@ dereference_links: false)
149
147
  end
150
148
  end
151
149
 
150
+ # Decompress +compressed_data+ according to +method+. Public API
151
+ # for callers (e.g., ParallelExtractor) that hold raw compressed
152
+ # payload outside an entry stream.
153
+ #
154
+ # @param compressed_data [String] Compressed bytes
155
+ # @param method [Integer] ZIP compression method code
156
+ # @param uncompressed_size [Integer] Expected uncompressed size
157
+ # @return [String] Decompressed bytes
158
+ def decompress(compressed_data, method, uncompressed_size)
159
+ decompress_data(compressed_data, method, uncompressed_size)
160
+ end
161
+
152
162
  private
153
163
 
154
164
  # Read central directory entries
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "fileutils"
4
- require "omnizip/formats/zip"
5
4
 
6
5
  module Omnizip
7
6
  module Formats
@@ -112,6 +111,79 @@ module Omnizip
112
111
  end
113
112
  end
114
113
 
114
+ # Add an entry whose payload is already compressed. Bypasses
115
+ # per-entry compression in +#write+, so +#write_precompressed+
116
+ # must be used instead of +#write+ to emit the archive.
117
+ #
118
+ # @param filename [String] Entry name in the archive
119
+ # @param uncompressed_size [Integer] Size before compression
120
+ # @param compressed_size [Integer] Size of +compressed_data+
121
+ # @param crc32 [Integer] CRC32 of the uncompressed data
122
+ # @param compressed_data [String] Pre-compressed payload
123
+ # @param stat [File::Stat, nil] Optional stat for the source file
124
+ def add_precompressed_entry(filename:, uncompressed_size:,
125
+ compressed_size:, crc32:,
126
+ compressed_data:, stat: nil)
127
+ entry = create_entry(
128
+ filename: filename,
129
+ uncompressed_data: "",
130
+ stat: stat,
131
+ )
132
+ entry[:compressed_size] = compressed_size
133
+ entry[:uncompressed_size] = uncompressed_size
134
+ entry[:crc32] = crc32
135
+ entry[:compressed_data] = compressed_data
136
+ @entries << entry
137
+ entry
138
+ end
139
+
140
+ # Write the archive using pre-compressed entry payloads (set
141
+ # via +#add_precompressed_entry+).
142
+ #
143
+ # @param compression_method [Integer] ZIP compression method
144
+ # code recorded in the headers
145
+ def write_precompressed(compression_method: COMPRESSION_DEFLATE)
146
+ File.open(file_path, "wb") do |io|
147
+ write_precompressed_to_io(io, compression_method: compression_method)
148
+ end
149
+ end
150
+
151
+ def write_precompressed_to_io(io, compression_method: COMPRESSION_DEFLATE)
152
+ local_header_offsets = []
153
+
154
+ entries.each do |entry|
155
+ offset = io.pos
156
+ local_header_offsets << offset
157
+
158
+ local_header = create_local_header(entry, compression_method)
159
+ local_header.compressed_size = entry[:compressed_size]
160
+ local_header.uncompressed_size = entry[:uncompressed_size]
161
+ local_header.crc32 = entry[:crc32]
162
+ io.write(local_header.to_binary)
163
+ io.write(entry[:compressed_data]) unless entry[:directory]
164
+ end
165
+
166
+ central_directory_offset = io.pos
167
+
168
+ entries.each_with_index do |entry, index|
169
+ central_header = create_central_header(
170
+ entry,
171
+ compression_method,
172
+ local_header_offsets[index],
173
+ )
174
+ io.write(central_header.to_binary)
175
+ end
176
+
177
+ central_directory_size = io.pos - central_directory_offset
178
+
179
+ eocd = create_eocd(
180
+ total_entries: entries.size,
181
+ central_directory_size: central_directory_size,
182
+ central_directory_offset: central_directory_offset,
183
+ )
184
+ io.write(eocd.to_binary)
185
+ end
186
+
115
187
  # Write to an IO object
116
188
  def write_to_io(io, compression_method: COMPRESSION_DEFLATE, level: 6)
117
189
  local_header_offsets = []
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "omnizip/formats/zip"
4
-
5
3
  module Omnizip
6
4
  module Formats
7
5
  module Zip
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "omnizip/formats/zip"
4
-
5
3
  module Omnizip
6
4
  module Formats
7
5
  module Zip
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "omnizip/formats/zip"
4
-
5
3
  module Omnizip
6
4
  module Formats
7
5
  module Zip
@@ -47,7 +47,6 @@ module Omnizip
47
47
 
48
48
  # Auto-register .zip format when loaded
49
49
  def register!
50
- require "omnizip/format_registry"
51
50
  FormatRegistry.register(".zip", Omnizip::Formats::Zip)
52
51
  end
53
52
  end
@@ -2,39 +2,26 @@
2
2
 
3
3
  module Omnizip
4
4
  module Formats
5
- # Archive format support
6
- #
7
- # This module contains format-specific autoload declarations.
8
- # Less commonly used formats are autoloaded for lazy loading.
9
-
10
- # Format specification loader
11
5
  autoload :FormatSpecLoader, "omnizip/formats/format_spec_loader"
12
6
 
13
- # CPIO archive format
14
- autoload :Cpio, "omnizip/formats/cpio"
7
+ autoload :SevenZip, "omnizip/formats/seven_zip"
8
+ autoload :Zip, "omnizip/formats/zip"
9
+ autoload :Rar, "omnizip/formats/rar"
10
+ autoload :Tar, "omnizip/formats/tar"
11
+ autoload :Gzip, "omnizip/formats/gzip"
12
+ autoload :Bzip2File, "omnizip/formats/bzip2_file"
13
+ autoload :Xz, "omnizip/formats/xz"
15
14
 
16
- # RPM package format
15
+ autoload :Cpio, "omnizip/formats/cpio"
17
16
  autoload :Rpm, "omnizip/formats/rpm"
18
-
19
- # OLE compound documents (MSI, DOC, XLS, PPT)
20
17
  autoload :Ole, "omnizip/formats/ole"
21
-
22
- # XAR archive format
18
+ autoload :Msi, "omnizip/formats/msi"
23
19
  autoload :Xar, "omnizip/formats/xar"
24
-
25
- # ISO 9660 CD-ROM format
26
20
  autoload :Iso, "omnizip/formats/iso"
27
-
28
- # LZMA alone format
29
21
  autoload :LzmaAlone, "omnizip/formats/lzma_alone"
30
-
31
- # LZIP format
32
22
  autoload :Lzip, "omnizip/formats/lzip"
33
23
 
34
- # XZ format constants (at Formats level for cross-module access)
35
24
  autoload :XzConst, "omnizip/formats/xz_const"
36
-
37
- # XZ implementation details
38
25
  autoload :XzImpl, "omnizip/formats/xz_impl"
39
26
  end
40
27
  end
@@ -74,14 +74,14 @@ module Omnizip
74
74
  # UPDATE_0: bit is 0
75
75
  @range = bound & 0xFFFFFFFF
76
76
  new_prob = prob + ((BIT_MODEL_TOTAL - prob) >> MOVE_BITS)
77
- model.instance_variable_set(:@probability, new_prob)
77
+ model.probability = new_prob
78
78
  0
79
79
  else
80
80
  # UPDATE_1: bit is 1
81
81
  @range = (@range - bound) & 0xFFFFFFFF
82
82
  @code = (@code - bound) & 0xFFFFFFFF
83
83
  new_prob = prob - (prob >> MOVE_BITS)
84
- model.instance_variable_set(:@probability, new_prob)
84
+ model.probability = new_prob
85
85
  1
86
86
  end
87
87
  end
@@ -91,7 +91,7 @@ module Omnizip
91
91
  # Update probability: ttt -= ttt >> kNumMoveBits
92
92
  prob - (prob >> MOVE_BITS)
93
93
  end
94
- model.instance_variable_set(:@probability, new_prob)
94
+ model.probability = new_prob
95
95
 
96
96
  # RC_NORM: Normalize AFTER encoding (key SDK difference!)
97
97
  normalize
@@ -71,12 +71,6 @@ module Omnizip
71
71
 
72
72
  # Initialize shared state across all chunks
73
73
  # Using XZ Utils components (tested and working)
74
- require "omnizip/algorithms/lzma/dictionary"
75
- require "omnizip/algorithms/lzma/lzma_state"
76
- require "omnizip/algorithms/lzma/xz_probability_models"
77
- require "omnizip/algorithms/lzma/match_finder"
78
- require "omnizip/algorithms/lzma/optimal_encoder"
79
- require "omnizip/algorithms/lzma/xz_range_encoder_exact"
80
74
 
81
75
  @dictionary = Omnizip::Algorithms::LZMA::Dictionary.new(dict_size)
82
76
  @state = Omnizip::Algorithms::LZMA::LZMAState.new(0)