Support Decompressor plugins

This commit is contained in:
Jan-Joost Spanjers 2019-12-20 20:01:53 +01:00
parent 2b7268373a
commit a5d068d3e8
5 changed files with 39 additions and 6 deletions

View File

@ -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

View File

@ -43,6 +43,8 @@ module Zip
@zlib_inflater.finished?
end
end
::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_DEFLATE, ::Zip::Inflater)
end
# Copyright (C) 2002, 2003 Thomas Sondergaard

View File

@ -146,18 +146,20 @@ module Zip
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

View File

@ -22,6 +22,8 @@ module Zip
alias_method :eof?, :eof
end
::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_STORE, ::Zip::PassThruDecompressor)
end
# Copyright (C) 2002, 2003 Thomas Sondergaard

15
test/decompressor_test.rb Normal file
View File

@ -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