Skip to content

Commit a5d068d

Browse files
committed
Support Decompressor plugins
1 parent 2b72683 commit a5d068d

File tree

5 files changed

+39
-6
lines changed

5 files changed

+39
-6
lines changed

lib/zip/decompressor.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@ module Zip
22
class Decompressor #:nodoc:all
33
CHUNK_SIZE = 32_768
44

5+
def self.decompressor_classes
6+
@decompressor_classes ||= {}
7+
end
8+
9+
def self.register(compression_method, decompressor_class)
10+
decompressor_classes[compression_method] = decompressor_class
11+
end
12+
13+
def self.find_by_compression_method(compression_method)
14+
decompressor_classes[compression_method]
15+
end
16+
517
attr_reader :input_stream
618
attr_reader :decompressed_size
719

lib/zip/inflater.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ def input_finished?
4343
@zlib_inflater.finished?
4444
end
4545
end
46+
47+
::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_DEFLATE, ::Zip::Inflater)
4648
end
4749

4850
# Copyright (C) 2002, 2003 Thomas Sondergaard

lib/zip/input_stream.rb

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,18 +146,20 @@ def get_decrypted_io
146146
def get_decompressor
147147
return ::Zip::NullDecompressor if @current_entry.nil?
148148

149-
if @current_entry.compression_method == ::Zip::Entry::STORED
149+
decompressed_size =
150150
if @current_entry.incomplete? && @current_entry.crc == 0 && @current_entry.size == 0 && @complete_entry
151-
::Zip::PassThruDecompressor.new(@decrypted_io, @complete_entry.size)
151+
@complete_entry.size
152152
else
153-
::Zip::PassThruDecompressor.new(@decrypted_io, @current_entry.size)
153+
@current_entry.size
154154
end
155-
elsif @current_entry.compression_method == ::Zip::Entry::DEFLATED
156-
::Zip::Inflater.new(@decrypted_io)
157-
else
155+
156+
decompressor_class = ::Zip::Decompressor.find_by_compression_method(@current_entry.compression_method)
157+
if decompressor_class.nil?
158158
raise ::Zip::CompressionMethodError,
159159
"Unsupported compression method #{@current_entry.compression_method}"
160160
end
161+
162+
decompressor_class.new(@decrypted_io, decompressed_size)
161163
end
162164

163165
def produce_input

lib/zip/pass_thru_decompressor.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ def eof
2222

2323
alias_method :eof?, :eof
2424
end
25+
26+
::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_STORE, ::Zip::PassThruDecompressor)
2527
end
2628

2729
# Copyright (C) 2002, 2003 Thomas Sondergaard

test/decompressor_test.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
require 'test_helper'
2+
class DecompressorTest < MiniTest::Test
3+
TEST_COMPRESSION_METHOD = 255
4+
5+
class TestCompressionClass
6+
end
7+
8+
def test_decompressor_registration
9+
assert_nil(::Zip::Decompressor.find_by_compression_method(TEST_COMPRESSION_METHOD))
10+
11+
::Zip::Decompressor.register(TEST_COMPRESSION_METHOD, TestCompressionClass)
12+
13+
assert_equal(TestCompressionClass, ::Zip::Decompressor.find_by_compression_method(TEST_COMPRESSION_METHOD))
14+
end
15+
end

0 commit comments

Comments
 (0)