Skip to content

Commit

Permalink
Support Decompressor plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
jspanjers committed Jan 26, 2020
1 parent 2b72683 commit a5d068d
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 6 deletions.
12 changes: 12 additions & 0 deletions lib/zip/decompressor.rb
Expand Up @@ -2,6 +2,18 @@ module Zip
class Decompressor #:nodoc:all
CHUNK_SIZE = 32_768

def self.decompressor_classes
@decompressor_classes ||= {}
end

def self.register(compression_method, decompressor_class)
decompressor_classes[compression_method] = decompressor_class
end

def self.find_by_compression_method(compression_method)
decompressor_classes[compression_method]
end

attr_reader :input_stream
attr_reader :decompressed_size

Expand Down
2 changes: 2 additions & 0 deletions lib/zip/inflater.rb
Expand Up @@ -43,6 +43,8 @@ def input_finished?
@zlib_inflater.finished?
end
end

::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_DEFLATE, ::Zip::Inflater)
end

# Copyright (C) 2002, 2003 Thomas Sondergaard
Expand Down
14 changes: 8 additions & 6 deletions lib/zip/input_stream.rb
Expand Up @@ -146,18 +146,20 @@ def get_decrypted_io
def get_decompressor
return ::Zip::NullDecompressor if @current_entry.nil?

if @current_entry.compression_method == ::Zip::Entry::STORED
decompressed_size =
if @current_entry.incomplete? && @current_entry.crc == 0 && @current_entry.size == 0 && @complete_entry
::Zip::PassThruDecompressor.new(@decrypted_io, @complete_entry.size)
@complete_entry.size
else
::Zip::PassThruDecompressor.new(@decrypted_io, @current_entry.size)
@current_entry.size
end
elsif @current_entry.compression_method == ::Zip::Entry::DEFLATED
::Zip::Inflater.new(@decrypted_io)
else

decompressor_class = ::Zip::Decompressor.find_by_compression_method(@current_entry.compression_method)
if decompressor_class.nil?
raise ::Zip::CompressionMethodError,
"Unsupported compression method #{@current_entry.compression_method}"
end

decompressor_class.new(@decrypted_io, decompressed_size)
end

def produce_input
Expand Down
2 changes: 2 additions & 0 deletions lib/zip/pass_thru_decompressor.rb
Expand Up @@ -22,6 +22,8 @@ def eof

alias_method :eof?, :eof
end

::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_STORE, ::Zip::PassThruDecompressor)
end

# Copyright (C) 2002, 2003 Thomas Sondergaard
Expand Down
15 changes: 15 additions & 0 deletions test/decompressor_test.rb
@@ -0,0 +1,15 @@
require 'test_helper'
class DecompressorTest < MiniTest::Test
TEST_COMPRESSION_METHOD = 255

class TestCompressionClass
end

def test_decompressor_registration
assert_nil(::Zip::Decompressor.find_by_compression_method(TEST_COMPRESSION_METHOD))

::Zip::Decompressor.register(TEST_COMPRESSION_METHOD, TestCompressionClass)

assert_equal(TestCompressionClass, ::Zip::Decompressor.find_by_compression_method(TEST_COMPRESSION_METHOD))
end
end

0 comments on commit a5d068d

Please sign in to comment.