Skip to content

Commit

Permalink
Add setting a compression level to the File options.
Browse files Browse the repository at this point in the history
It looks like it needs to be surfaced in `add` and `get_output_stream`.
The compression level defaults to whatever the global default is unless
it is overridden on opening the Zip::File.

Also needed to reorder some of the requires in the top-level module file
now that we are using defaults in the File class.
  • Loading branch information
hainesr committed May 24, 2020
1 parent 6f1ef97 commit 7212bab
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 36 deletions.
4 changes: 2 additions & 2 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ Metrics/CyclomaticComplexity:
# Offense count: 44
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/MethodLength:
Max: 29
Max: 30

# Offense count: 2
# Configuration parameters: CountKeywordArgs.
Metrics/ParameterLists:
Max: 10
Max: 12

# Offense count: 20
Metrics/PerceivedComplexity:
Expand Down
55 changes: 28 additions & 27 deletions lib/zip.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,9 @@
require 'singleton'
require 'tempfile'
require 'fileutils'
require 'rbconfig'
require 'stringio'
require 'zlib'
require 'zip/constants'
require 'zip/dos_time'
require 'zip/ioextras'
require 'rbconfig'
require 'zip/entry'
require 'zip/extra_field'
require 'zip/entry_set'
require 'zip/central_directory'
require 'zip/file'
require 'zip/input_stream'
require 'zip/output_stream'
require 'zip/decompressor'
require 'zip/compressor'
require 'zip/null_decompressor'
require 'zip/null_compressor'
require 'zip/null_input_stream'
require 'zip/pass_thru_compressor'
require 'zip/pass_thru_decompressor'
require 'zip/crypto/decrypted_io'
require 'zip/crypto/encryption'
require 'zip/crypto/null_encryption'
require 'zip/crypto/traditional_encryption'
require 'zip/inflater'
require 'zip/deflater'
require 'zip/streamable_stream'
require 'zip/streamable_directory'
require 'zip/errors'

module Zip
extend self
Expand Down Expand Up @@ -67,6 +41,33 @@ def setup
reset!
end

require 'zip/constants'
require 'zip/dos_time'
require 'zip/ioextras'
require 'zip/entry'
require 'zip/extra_field'
require 'zip/entry_set'
require 'zip/central_directory'
require 'zip/file'
require 'zip/input_stream'
require 'zip/output_stream'
require 'zip/decompressor'
require 'zip/compressor'
require 'zip/null_decompressor'
require 'zip/null_compressor'
require 'zip/null_input_stream'
require 'zip/pass_thru_compressor'
require 'zip/pass_thru_decompressor'
require 'zip/crypto/decrypted_io'
require 'zip/crypto/encryption'
require 'zip/crypto/null_encryption'
require 'zip/crypto/traditional_encryption'
require 'zip/inflater'
require 'zip/deflater'
require 'zip/streamable_stream'
require 'zip/streamable_directory'
require 'zip/errors'

# Copyright (C) 2002, 2003 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license.
16 changes: 11 additions & 5 deletions lib/zip/file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ class File < CentralDirectory
DEFAULT_OPTIONS = {
restore_ownership: false,
restore_permissions: false,
restore_times: false
restore_times: false,
compression_level: ::Zip.default_compression
}.freeze

attr_reader :name
Expand Down Expand Up @@ -111,6 +112,7 @@ def initialize(path_or_io, create = false, buffer = false, options = {})
@restore_ownership = options[:restore_ownership]
@restore_permissions = options[:restore_permissions]
@restore_times = options[:restore_times]
@compression_level = options[:compression_level]
end

class << self
Expand Down Expand Up @@ -266,14 +268,14 @@ def get_input_stream(entry, &a_proc)
# File.open method.
def get_output_stream(entry, permission_int = nil, comment = nil,
extra = nil, compressed_size = nil, crc = nil,
compression_method = nil, size = nil, time = nil,
&a_proc)
compression_method = nil, compression_level = nil,
size = nil, time = nil, &a_proc)

new_entry =
if entry.kind_of?(Entry)
entry
else
Entry.new(@name, entry.to_s, comment, extra, compressed_size, crc, compression_method, ::Zip.default_compression, size, time)
Entry.new(@name, entry.to_s, comment, extra, compressed_size, crc, compression_method, compression_level, size, time)
end
if new_entry.directory?
raise ArgumentError,
Expand All @@ -299,7 +301,11 @@ def read(entry)
def add(entry, src_path, &continue_on_exists_proc)
continue_on_exists_proc ||= proc { ::Zip.continue_on_exists_proc }
check_entry_exists(entry, continue_on_exists_proc, 'add')
new_entry = entry.kind_of?(::Zip::Entry) ? entry : ::Zip::Entry.new(@name, entry.to_s)
new_entry = if entry.kind_of?(::Zip::Entry)
entry
else
::Zip::Entry.new(@name, entry.to_s, nil, nil, 0, 0, ::Zip::Entry::DEFLATED, @compression_level)
end
new_entry.gather_fileinfo_from_srcpath(src_path)
new_entry.dirty = true
@entry_set << new_entry
Expand Down
41 changes: 39 additions & 2 deletions test/file_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def test_get_output_stream
assert_equal(count + 1, zf.size)
assert_equal('Putting stuff in data/generated/empty.txt', zf.read('test/data/generated/empty.txt'))

custom_entry_args = [TEST_COMMENT, TEST_EXTRA, TEST_COMPRESSED_SIZE, TEST_CRC, ::Zip::Entry::STORED, TEST_SIZE, TEST_TIME]
custom_entry_args = [TEST_COMMENT, TEST_EXTRA, TEST_COMPRESSED_SIZE, TEST_CRC, ::Zip::Entry::STORED, ::Zlib::BEST_SPEED, TEST_SIZE, TEST_TIME]
zf.get_output_stream('entry_with_custom_args.txt', nil, *custom_entry_args) do |os|
os.write 'Some data'
end
Expand Down Expand Up @@ -188,7 +188,7 @@ def test_cleans_up_tempfiles_after_close
assert_equal(false, File.exist?(@tempfile_path))
end

def test_add
def test_add_default_compression
src_file = 'test/data/file2.txt'
entry_name = 'newEntryName.rb'
assert(::File.exist?(src_file))
Expand All @@ -197,9 +197,46 @@ def test_add
zf.close

zf_read = ::Zip::File.new(EMPTY_FILENAME)
entry = zf_read.entries.first
assert_equal('', zf_read.comment)
assert_equal(1, zf_read.entries.length)
assert_equal(entry_name, zf_read.entries.first.name)
assert_equal(File.size(src_file), entry.size)
assert_equal(8_764, entry.compressed_size)
AssertEntry.assert_contents(src_file,
zf_read.get_input_stream(entry_name, &:read))
end

def test_add_best_compression
src_file = 'test/data/file2.txt'
entry_name = 'newEntryName.rb'
assert(::File.exist?(src_file))
zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE, false, { compression_level: Zlib::BEST_COMPRESSION })
zf.add(entry_name, src_file)
zf.close

zf_read = ::Zip::File.new(EMPTY_FILENAME)
entry = zf_read.entries.first
assert_equal(1, zf_read.entries.length)
assert_equal(File.size(src_file), entry.size)
assert_equal(8_658, entry.compressed_size)
AssertEntry.assert_contents(src_file,
zf_read.get_input_stream(entry_name, &:read))
end

def test_add_best_speed
src_file = 'test/data/file2.txt'
entry_name = 'newEntryName.rb'
assert(::File.exist?(src_file))
zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE, false, { compression_level: Zlib::BEST_SPEED })
zf.add(entry_name, src_file)
zf.close

zf_read = ::Zip::File.new(EMPTY_FILENAME)
entry = zf_read.entries.first
assert_equal(1, zf_read.entries.length)
assert_equal(File.size(src_file), entry.size)
assert_equal(10_938, entry.compressed_size)
AssertEntry.assert_contents(src_file,
zf_read.get_input_stream(entry_name, &:read))
end
Expand Down

0 comments on commit 7212bab

Please sign in to comment.