omnizip 0.3.13 → 0.3.15

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/lib/omnizip/algorithm.rb +36 -1
  3. data/lib/omnizip/algorithms/bzip2.rb +1 -3
  4. data/lib/omnizip/algorithms/deflate.rb +1 -3
  5. data/lib/omnizip/algorithms/deflate64.rb +2 -2
  6. data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +7 -8
  7. data/lib/omnizip/algorithms/lzma.rb +1 -1
  8. data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +5 -1
  9. data/lib/omnizip/algorithms/lzma2.rb +4 -12
  10. data/lib/omnizip/algorithms/zstandard/constants.rb +38 -25
  11. data/lib/omnizip/algorithms/zstandard/decoder.rb +101 -136
  12. data/lib/omnizip/algorithms/zstandard/encoder.rb +81 -138
  13. data/lib/omnizip/algorithms/zstandard/frame/block.rb +17 -0
  14. data/lib/omnizip/algorithms/zstandard/frame/header.rb +42 -29
  15. data/lib/omnizip/algorithms/zstandard/fse/bitstream.rb +114 -117
  16. data/lib/omnizip/algorithms/zstandard/fse/encoder.rb +434 -222
  17. data/lib/omnizip/algorithms/zstandard/fse/interleaved.rb +92 -0
  18. data/lib/omnizip/algorithms/zstandard/fse/table.rb +98 -176
  19. data/lib/omnizip/algorithms/zstandard/fse/table_description.rb +203 -0
  20. data/lib/omnizip/algorithms/zstandard/fse.rb +21 -2
  21. data/lib/omnizip/algorithms/zstandard/huffman.rb +195 -188
  22. data/lib/omnizip/algorithms/zstandard/huffman_encoder.rb +232 -255
  23. data/lib/omnizip/algorithms/zstandard/literals.rb +170 -103
  24. data/lib/omnizip/algorithms/zstandard/literals_encoder.rb +47 -199
  25. data/lib/omnizip/algorithms/zstandard/sequences.rb +260 -252
  26. data/lib/omnizip/algorithms/zstandard/xxhash.rb +159 -0
  27. data/lib/omnizip/algorithms/zstandard.rb +20 -24
  28. data/lib/omnizip/algorithms.rb +14 -1
  29. data/lib/omnizip/buffer.rb +1 -2
  30. data/lib/omnizip/commands/archive_list_command.rb +9 -7
  31. data/lib/omnizip/convenience.rb +1 -2
  32. data/lib/omnizip/entry.rb +44 -0
  33. data/lib/omnizip/extraction/selective_extractor.rb +2 -10
  34. data/lib/omnizip/filter_pipeline.rb +1 -1
  35. data/lib/omnizip/filter_registry.rb +18 -16
  36. data/lib/omnizip/filters/bcj2.rb +1 -1
  37. data/lib/omnizip/filters/bcj_arm.rb +1 -1
  38. data/lib/omnizip/filters/bcj_arm64.rb +1 -1
  39. data/lib/omnizip/filters/bcj_ia64.rb +1 -1
  40. data/lib/omnizip/filters/bcj_ppc.rb +1 -1
  41. data/lib/omnizip/filters/bcj_sparc.rb +1 -1
  42. data/lib/omnizip/filters/bcj_x86.rb +1 -1
  43. data/lib/omnizip/filters.rb +0 -2
  44. data/lib/omnizip/formats/bzip2_file.rb +0 -7
  45. data/lib/omnizip/formats/cpio/entry.rb +6 -0
  46. data/lib/omnizip/formats/cpio.rb +0 -6
  47. data/lib/omnizip/formats/gzip.rb +0 -7
  48. data/lib/omnizip/formats/iso/directory_record.rb +7 -0
  49. data/lib/omnizip/formats/iso.rb +0 -5
  50. data/lib/omnizip/formats/lzip.rb +0 -7
  51. data/lib/omnizip/formats/lzma_alone.rb +0 -6
  52. data/lib/omnizip/formats/msi/entry.rb +6 -0
  53. data/lib/omnizip/formats/msi.rb +0 -9
  54. data/lib/omnizip/formats/ole/dirent.rb +6 -0
  55. data/lib/omnizip/formats/ole.rb +0 -9
  56. data/lib/omnizip/formats/rar.rb +0 -6
  57. data/lib/omnizip/formats/rar3/reader.rb +7 -0
  58. data/lib/omnizip/formats/rar5/reader.rb +7 -0
  59. data/lib/omnizip/formats/rpm/entry.rb +6 -0
  60. data/lib/omnizip/formats/seven_zip/models/file_entry.rb +7 -0
  61. data/lib/omnizip/formats/seven_zip.rb +0 -6
  62. data/lib/omnizip/formats/tar/entry.rb +6 -0
  63. data/lib/omnizip/formats/tar.rb +2 -10
  64. data/lib/omnizip/formats/xar/entry.rb +6 -0
  65. data/lib/omnizip/formats/xar.rb +0 -6
  66. data/lib/omnizip/formats/zip.rb +0 -6
  67. data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +33 -31
  68. data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +177 -163
  69. data/lib/omnizip/implementations.rb +18 -4
  70. data/lib/omnizip/io/source.rb +3 -0
  71. data/lib/omnizip/metadata/entry_metadata.rb +7 -0
  72. data/lib/omnizip/parallel/engine.rb +48 -0
  73. data/lib/omnizip/parallel/parallel_compressor.rb +5 -16
  74. data/lib/omnizip/parallel/parallel_extractor.rb +5 -16
  75. data/lib/omnizip/parallel.rb +1 -0
  76. data/lib/omnizip/profile/profile_registry.rb +1 -2
  77. data/lib/omnizip/registry.rb +0 -1
  78. data/lib/omnizip/rubyzip_compat.rb +0 -1
  79. data/lib/omnizip/temp/temp_file.rb +1 -2
  80. data/lib/omnizip/version.rb +1 -1
  81. data/lib/omnizip/zip/entry.rb +7 -0
  82. data/lib/omnizip/zip/file.rb +4 -8
  83. data/lib/omnizip.rb +1 -1
  84. metadata +7 -6
  85. data/lib/omnizip/filters/filter_base.rb +0 -6
  86. data/lib/omnizip/filters/registration.rb +0 -22
  87. data/lib/omnizip/filters/registry.rb +0 -111
  88. data/lib/omnizip/format_registry.rb +0 -100
@@ -201,20 +201,11 @@ module Omnizip
201
201
  )
202
202
  end
203
203
 
204
- # Create worker pool
205
- pool = WorkerPool.new(
206
- worker_class: ExtractionWorker,
207
- num_workers: @options.threads,
208
- continuous: false,
209
- )
210
-
211
- pool.start
212
- pool.submit_batch(work_items)
213
- pool.run
214
-
215
- # Collect results
216
- results = pool.successful_results
217
- errors = pool.failed_results
204
+ # Run the worker pool through the shared engine.
205
+ engine = Engine.new(worker_class: ExtractionWorker,
206
+ threads: @options.threads)
207
+ results = []
208
+ errors = engine.run(work_items) { |r| results << r }
218
209
 
219
210
  # Handle errors
220
211
  unless errors.empty?
@@ -227,8 +218,6 @@ module Omnizip
227
218
  # Write files to disk (thread-safe)
228
219
  extracted_paths = write_extracted_files(results, overwrite: overwrite)
229
220
 
230
- pool.shutdown
231
-
232
221
  @stats[:end_time] = Time.now
233
222
  @stats[:files_extracted] = results.size
234
223
 
@@ -26,6 +26,7 @@ module Omnizip
26
26
  autoload :JobQueue, "omnizip/parallel/job_queue"
27
27
  autoload :JobScheduler, "omnizip/parallel/job_scheduler"
28
28
  autoload :WorkerPool, "omnizip/parallel/worker_pool"
29
+ autoload :Engine, "omnizip/parallel/engine"
29
30
  autoload :ParallelCompressor, "omnizip/parallel/parallel_compressor"
30
31
  autoload :ParallelExtractor, "omnizip/parallel/parallel_extractor"
31
32
 
@@ -133,11 +133,10 @@ module Omnizip
133
133
  # @yield [profile] Yields each profile
134
134
  # @yieldparam profile [CompressionProfile] A registered profile
135
135
  # @return [void]
136
- # rubocop:disable Naming/BlockForwarding, Style/ArgumentsForwarding -- Ruby 3.0 compatibility
136
+ # rubocop:disable-next Naming/BlockForwarding, Style/ArgumentsForwarding -- Ruby 3.0 compatibility
137
137
  def each(&block)
138
138
  all.each(&block)
139
139
  end
140
- # rubocop:enable Naming/BlockForwarding, Style/ArgumentsForwarding
141
140
 
142
141
  # Get profile information as hash
143
142
  #
@@ -48,7 +48,6 @@ module Omnizip
48
48
 
49
49
  trigger = lazy_triggers[normalized]
50
50
  if trigger
51
- synchronize { lazy_triggers.delete(normalized) }
52
51
  trigger.call
53
52
  value = storage[normalized]
54
53
  return value if value
@@ -15,7 +15,6 @@
15
15
  # end
16
16
  #
17
17
 
18
-
19
18
  # Create Zip namespace as alias for Omnizip::Zip
20
19
  module Zip
21
20
  # Rubyzip-compatible File class
@@ -108,7 +108,7 @@ module Omnizip
108
108
  ObjectSpace.define_finalizer(self, self.class.finalizer(@tempfile))
109
109
  end
110
110
 
111
- # rubocop:disable Lint/IneffectiveAccessModifier
111
+ # rubocop:disable-next Lint/IneffectiveAccessModifier
112
112
  def self.finalizer(tempfile)
113
113
  proc do
114
114
  tempfile.close unless tempfile.closed?
@@ -118,7 +118,6 @@ module Omnizip
118
118
  nil
119
119
  end
120
120
  end
121
- # rubocop:enable Lint/IneffectiveAccessModifier
122
121
  end
123
122
  end
124
123
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Omnizip
4
- VERSION = "0.3.13"
4
+ VERSION = "0.3.15"
5
5
  end
@@ -5,8 +5,15 @@ module Omnizip
5
5
  # Rubyzip-compatible Entry class
6
6
  # Wraps CentralDirectoryHeader with rubyzip API
7
7
  class Entry
8
+ include Omnizip::Entry
9
+
8
10
  attr_reader :header, :ftype, :filepath
9
11
 
12
+ def entry_name = name
13
+ def entry_directory? = directory?
14
+ def entry_size = size
15
+ def entry_mtime = time
16
+
10
17
  # Create entry from CentralDirectoryHeader
11
18
  def initialize(header, filepath: nil)
12
19
  @header = header
@@ -94,7 +94,7 @@ module Omnizip
94
94
  # @param entry [Entry, String] Entry object or name
95
95
  # @yield [stream] Block to read from the stream
96
96
  # @return [String] Entry content (if no block given)
97
- # rubocop:disable Naming/BlockForwarding, Style/ArgumentsForwarding, Style/BlockDelimiters -- Ruby 3.0 compatibility
97
+ # rubocop:disable-next Naming/BlockForwarding, Style/ArgumentsForwarding, Style/BlockDelimiters -- Ruby 3.0 compatibility
98
98
  def get_input_stream(entry, &block)
99
99
  entry = get_entry(entry) if entry.is_a?(String)
100
100
  raise Errno::ENOENT, "Entry not found: #{entry}" unless entry
@@ -108,16 +108,14 @@ module Omnizip
108
108
  content
109
109
  end
110
110
  end
111
- # rubocop:enable Naming/BlockForwarding, Style/ArgumentsForwarding, Style/BlockDelimiters
112
111
  alias_method :read, :get_input_stream
113
112
 
114
113
  # Iterate over all entries
115
114
  # @yield [entry] Block to execute for each entry
116
- # rubocop:disable Naming/BlockForwarding, Style/ArgumentsForwarding -- Ruby 3.0 compatibility
115
+ # rubocop:disable-next Naming/BlockForwarding, Style/ArgumentsForwarding -- Ruby 3.0 compatibility
117
116
  def each(&block)
118
117
  entries.each(&block)
119
118
  end
120
- # rubocop:enable Naming/BlockForwarding, Style/ArgumentsForwarding
121
119
 
122
120
  # Extract an entry to a destination path
123
121
  # @param entry [Entry, String] Entry object or name
@@ -164,12 +162,11 @@ module Omnizip
164
162
  # Replace entry content
165
163
  # @param entry_name [String] Entry name
166
164
  # @param src_path [String, nil] Source file path
167
- # rubocop:disable Naming/BlockForwarding, Style/ArgumentsForwarding -- Ruby 3.0 compatibility
165
+ # rubocop:disable-next Naming/BlockForwarding, Style/ArgumentsForwarding -- Ruby 3.0 compatibility
168
166
  def replace(entry_name, src_path = nil, &block)
169
167
  remove(entry_name)
170
168
  add(entry_name, src_path, &block)
171
169
  end
172
- # rubocop:enable Naming/BlockForwarding, Style/ArgumentsForwarding
173
170
 
174
171
  # Get archive comment
175
172
  def comment
@@ -216,7 +213,7 @@ module Omnizip
216
213
  # Glob entries by pattern
217
214
  # @param pattern [String] Glob pattern
218
215
  # @return [Array<Entry>] Matching entries
219
- # rubocop:disable Naming/BlockForwarding, Style/ArgumentsForwarding, Style/BlockDelimiters -- Ruby 3.0 compatibility
216
+ # rubocop:disable-next Naming/BlockForwarding, Style/ArgumentsForwarding, Style/BlockDelimiters -- Ruby 3.0 compatibility
220
217
  def glob(pattern, &block)
221
218
  matching = entries.select { |e| ::File.fnmatch(pattern, e.name) }
222
219
 
@@ -226,7 +223,6 @@ module Omnizip
226
223
  matching
227
224
  end
228
225
  end
229
- # rubocop:enable Naming/BlockForwarding, Style/ArgumentsForwarding, Style/BlockDelimiters
230
226
 
231
227
  # Extract files matching a pattern
232
228
  # @param pattern [String, Regexp, Array] Pattern(s) to match
data/lib/omnizip.rb CHANGED
@@ -43,7 +43,6 @@ module Omnizip
43
43
  autoload :Registry, "omnizip/registry"
44
44
  autoload :Algorithm, "omnizip/algorithm"
45
45
  autoload :AlgorithmRegistry, "omnizip/algorithm_registry"
46
- autoload :FormatRegistry, "omnizip/format_registry"
47
46
  autoload :OptimizationRegistry, "omnizip/optimization_registry"
48
47
  autoload :ChecksumRegistry, "omnizip/checksum_registry"
49
48
  autoload :FilterRegistry, "omnizip/filter_registry"
@@ -60,6 +59,7 @@ module Omnizip
60
59
  autoload :ETA, "omnizip/eta"
61
60
  autoload :Progress, "omnizip/progress"
62
61
  autoload :Metadata, "omnizip/metadata"
62
+ autoload :Entry, "omnizip/entry"
63
63
  autoload :Converter, "omnizip/converter"
64
64
  autoload :LinkHandler, "omnizip/link_handler"
65
65
  autoload :Parity, "omnizip/parity"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omnizip
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.13
4
+ version: 0.3.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-07-24 00:00:00.000000000 Z
11
+ date: 2026-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64
@@ -310,12 +310,15 @@ files:
310
310
  - lib/omnizip/algorithms/zstandard/fse.rb
311
311
  - lib/omnizip/algorithms/zstandard/fse/bitstream.rb
312
312
  - lib/omnizip/algorithms/zstandard/fse/encoder.rb
313
+ - lib/omnizip/algorithms/zstandard/fse/interleaved.rb
313
314
  - lib/omnizip/algorithms/zstandard/fse/table.rb
315
+ - lib/omnizip/algorithms/zstandard/fse/table_description.rb
314
316
  - lib/omnizip/algorithms/zstandard/huffman.rb
315
317
  - lib/omnizip/algorithms/zstandard/huffman_encoder.rb
316
318
  - lib/omnizip/algorithms/zstandard/literals.rb
317
319
  - lib/omnizip/algorithms/zstandard/literals_encoder.rb
318
320
  - lib/omnizip/algorithms/zstandard/sequences.rb
321
+ - lib/omnizip/algorithms/zstandard/xxhash.rb
319
322
  - lib/omnizip/archive_handler.rb
320
323
  - lib/omnizip/archive_handlers.rb
321
324
  - lib/omnizip/archive_handlers/tar_handler.rb
@@ -364,6 +367,7 @@ files:
364
367
  - lib/omnizip/crypto/aes256/cipher.rb
365
368
  - lib/omnizip/crypto/aes256/constants.rb
366
369
  - lib/omnizip/crypto/aes256/key_derivation.rb
370
+ - lib/omnizip/entry.rb
367
371
  - lib/omnizip/error.rb
368
372
  - lib/omnizip/eta.rb
369
373
  - lib/omnizip/eta/exponential_smoothing_estimator.rb
@@ -397,12 +401,8 @@ files:
397
401
  - lib/omnizip/filters/bcj_sparc.rb
398
402
  - lib/omnizip/filters/bcj_x86.rb
399
403
  - lib/omnizip/filters/delta.rb
400
- - lib/omnizip/filters/filter_base.rb
401
- - lib/omnizip/filters/registration.rb
402
- - lib/omnizip/filters/registry.rb
403
404
  - lib/omnizip/filters/xz_delta.rb
404
405
  - lib/omnizip/format_detector.rb
405
- - lib/omnizip/format_registry.rb
406
406
  - lib/omnizip/formats.rb
407
407
  - lib/omnizip/formats/.keep
408
408
  - lib/omnizip/formats/bzip2_file.rb
@@ -630,6 +630,7 @@ files:
630
630
  - lib/omnizip/models/split_options.rb
631
631
  - lib/omnizip/optimization_registry.rb
632
632
  - lib/omnizip/parallel.rb
633
+ - lib/omnizip/parallel/engine.rb
633
634
  - lib/omnizip/parallel/job_queue.rb
634
635
  - lib/omnizip/parallel/job_scheduler.rb
635
636
  - lib/omnizip/parallel/parallel_compressor.rb
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # FilterBase is a historical alias for Omnizip::Filter. New code should
4
- # inherit from Omnizip::Filter directly; FilterBase is kept for
5
- # backward compatibility with existing subclasses (BcjX86, BcjArm, …).
6
- Omnizip::Filters::FilterBase = Omnizip::Filter
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Filter registration - triggers autoload and registers all filters
4
- # This file should be required after filters.rb which sets up autoloads
5
-
6
- module Omnizip
7
- module Filters
8
- # Touch constants to trigger autoload
9
- BCJ
10
- BcjX86
11
- Bcj2
12
- BcjArm
13
- BcjArm64
14
- BcjPpc
15
- BcjSparc
16
- BcjIa64
17
- Delta
18
- end
19
- end
20
-
21
- # Filter registration is handled by each filter class in their initialize methods
22
- # via FilterRegistry.register calls
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #
4
- # Copyright (C) 2024 Ribose Inc.
5
- #
6
- # This file is part of Omnizip.
7
- #
8
- # Omnizip is a pure Ruby port of 7-Zip compression algorithms.
9
- # Based on the 7-Zip LZMA SDK by Igor Pavlov.
10
- #
11
- # This library is free software; you can redistribute it and/or
12
- # modify it under the terms of the GNU Lesser General Public
13
- # License as published by the Free Software Foundation; either
14
- # version 2.1 of the License, or (at your option) any later version.
15
- #
16
- # See the COPYING file for the complete text of the license.
17
- #
18
-
19
- module Omnizip
20
- module Filters
21
- # Registry for auto-registering all preprocessing filters.
22
- #
23
- # This module centralizes filter registration, ensuring all filters
24
- # are properly registered with their supported formats.
25
- module Registry
26
- # Register all BCJ filters with appropriate format support.
27
- #
28
- # BCJ filters are architecture-specific filters for executable code.
29
- # XZ format supports a subset of architectures (no ARM64),
30
- # while 7z supports all.
31
- #
32
- # @return [void]
33
- def self.register_bcj_filters
34
- # Individual BCJ architecture filters (use hyphens to match existing convention)
35
- register_bcj_filter(:"bcj-x86", BcjX86, architecture: :x86)
36
- register_bcj_filter(:"bcj-arm", BcjArm, architecture: :arm)
37
- register_bcj_filter(:"bcj-arm64", BcjArm64, architecture: :arm64,
38
- xz_supported: false)
39
- register_bcj_filter(:"bcj-ia64", BcjIa64, architecture: :ia64)
40
- register_bcj_filter(:"bcj-ppc", BcjPpc, architecture: :powerpc)
41
- register_bcj_filter(:"bcj-sparc", BcjSparc, architecture: :sparc)
42
-
43
- # Unified BCJ filter (Task 2) - supports all architectures
44
- # Note: We register it as 'bcj' without architecture suffix
45
- Omnizip::FilterRegistry.register_with_formats(
46
- :bcj,
47
- Omnizip::Filters::BCJ,
48
- formats: [:seven_zip], # Only 7z for now (uses architecture parameter)
49
- )
50
- end
51
-
52
- # Register a BCJ filter with format support.
53
- #
54
- # @param name [Symbol] Filter name identifier
55
- # @param filter_class [Class] Filter class to register
56
- # @param architecture [Symbol] Target architecture
57
- # @param xz_supported [Boolean] Whether XZ format supports this architecture
58
- # @return [void]
59
- def self.register_bcj_filter(name, filter_class, architecture:,
60
- xz_supported: true)
61
- formats = [:seven_zip]
62
- formats << :xz if xz_supported
63
- Omnizip::FilterRegistry.register_with_formats(name, filter_class,
64
- formats: formats)
65
- end
66
-
67
- # Register Delta filter.
68
- #
69
- # Delta filter is supported by both XZ and 7z formats.
70
- #
71
- # @return [void]
72
- def self.register_delta_filter
73
- Omnizip::FilterRegistry.register_with_formats(
74
- :delta,
75
- Delta,
76
- formats: %i[seven_zip xz],
77
- )
78
- end
79
-
80
- # Register BCJ2 filter.
81
- #
82
- # BCJ2 is a 4-stream variant of BCJ, primarily used by 7z.
83
- # XZ does not support BCJ2.
84
- #
85
- # @return [void]
86
- def self.register_bcj2_filter
87
- Omnizip::FilterRegistry.register_with_formats(
88
- :bcj2,
89
- Bcj2,
90
- formats: [:seven_zip], # Only 7z supports BCJ2
91
- )
92
- end
93
-
94
- # Register all filters.
95
- #
96
- # This method registers all available filters with their
97
- # appropriate format support. Call this during application
98
- # initialization to ensure all filters are available.
99
- #
100
- # @return [void]
101
- def self.register_all
102
- register_bcj_filters
103
- register_delta_filter
104
- register_bcj2_filter
105
- end
106
- end
107
- end
108
- end
109
-
110
- # Auto-register all filters on load
111
- Omnizip::Filters::Registry.register_all
@@ -1,100 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Omnizip
4
- class FormatRegistry < Omnizip::Registry
5
- BUILTIN_FORMATS = {
6
- ".7z" => "Omnizip::Formats::SevenZip::Reader",
7
- ".zip" => "Omnizip::Formats::Zip",
8
- ".rar" => "Omnizip::Formats::Rar::Reader",
9
- ".tar" => "Omnizip::Formats::Tar",
10
- ".gz" => "Omnizip::Formats::Gzip",
11
- ".gzip" => "Omnizip::Formats::Gzip",
12
- ".bz2" => "Omnizip::Formats::Bzip2File",
13
- ".bzip2" => "Omnizip::Formats::Bzip2File",
14
- ".xz" => "Omnizip::Formats::Xz",
15
- ".msi" => "Omnizip::Formats::Msi",
16
- ".msp" => "Omnizip::Formats::Msi",
17
- ".cpio" => "Omnizip::Formats::Cpio::Reader",
18
- ".iso" => "Omnizip::Formats::Iso::Reader",
19
- ".xar" => "Omnizip::Formats::Xar::Reader",
20
- ".lz" => "Omnizip::Formats::Lzip",
21
- ".lzip" => "Omnizip::Formats::Lzip",
22
- ".lzma" => "Omnizip::Formats::LzmaAlone",
23
- ".ole" => "Omnizip::Formats::Ole::Storage",
24
- ".doc" => "Omnizip::Formats::Ole::Storage",
25
- ".xls" => "Omnizip::Formats::Ole::Storage",
26
- ".ppt" => "Omnizip::Formats::Ole::Storage",
27
- }.freeze
28
-
29
- class << self
30
- def label
31
- "Format"
32
- end
33
-
34
- def normalize_key(extension)
35
- ext = extension.to_s
36
- ext = ".#{ext}" unless ext.start_with?(".")
37
- ext.downcase
38
- end
39
-
40
- def get(extension)
41
- normalized = normalize_key(extension)
42
- handler = storage[normalized]
43
- return resolve_handler(handler, extension) if handler
44
-
45
- trigger = lazy_triggers[normalized]
46
- if trigger
47
- synchronize { lazy_triggers.delete(normalized) }
48
- trigger.call
49
- handler = storage[normalized]
50
- return resolve_handler(handler, extension) if handler
51
- end
52
-
53
- nil
54
- end
55
-
56
- def supported?(extension)
57
- registered?(extension) || lazy_triggers.key?(normalize_key(extension))
58
- end
59
- alias supported_formats available
60
-
61
- def resolve_constant(name)
62
- return nil unless name.is_a?(String)
63
-
64
- parts = name.split("::")
65
- parts.shift if parts.empty? || parts.first.empty?
66
-
67
- constant = Object
68
- parts.each do |n|
69
- return nil unless constant.const_defined?(n, false)
70
-
71
- constant = constant.const_get(n)
72
- end
73
- constant
74
- rescue StandardError
75
- nil
76
- end
77
-
78
- private
79
-
80
- def resolve_handler(handler, _original_extension)
81
- return nil if handler.nil?
82
- return handler if handler.is_a?(Class) || handler.is_a?(Module)
83
-
84
- resolve_constant(handler)
85
- end
86
- end
87
- end
88
- end
89
-
90
- # Lazy triggers — explicitly re-register on each miss so the entry
91
- # survives reset!. Object.const_get alone doesn't re-run the file body
92
- # once the constant is loaded.
93
- Omnizip::FormatRegistry::BUILTIN_FORMATS.each do |ext, const_path|
94
- Omnizip::FormatRegistry.register_lazy(ext) do
95
- handler = Object.const_get(const_path)
96
- # Register under the original extension; some formats (e.g. Rar)
97
- # store a string class path that needs resolve_constant on get.
98
- Omnizip::FormatRegistry.register(ext, handler)
99
- end
100
- end