seven_zip_ruby 1.0.0-x86-mingw32
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.
- checksums.yaml +7 -0
- data/.gitignore +25 -0
- data/.travis.yml +10 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +39 -0
- data/README.md +176 -0
- data/Rakefile +47 -0
- data/lib/seven_zip_ruby.rb +16 -0
- data/lib/seven_zip_ruby/7z.dll +0 -0
- data/lib/seven_zip_ruby/7z64.dll +0 -0
- data/lib/seven_zip_ruby/archive_info.rb +21 -0
- data/lib/seven_zip_ruby/entry_info.rb +45 -0
- data/lib/seven_zip_ruby/exception.rb +7 -0
- data/lib/seven_zip_ruby/seven_zip_archive.so +0 -0
- data/lib/seven_zip_ruby/seven_zip_reader.rb +180 -0
- data/lib/seven_zip_ruby/seven_zip_writer.rb +143 -0
- data/lib/seven_zip_ruby/update_info.rb +116 -0
- data/lib/seven_zip_ruby/version.rb +3 -0
- data/seven_zip_ruby.gemspec +28 -0
- data/spec/seven_zip_ruby_spec.rb +490 -0
- data/spec/seven_zip_ruby_spec_helper.rb +122 -0
- metadata +109 -0
@@ -0,0 +1,143 @@
|
|
1
|
+
require("stringio")
|
2
|
+
|
3
|
+
module SevenZipRuby
|
4
|
+
class SevenZipWriter
|
5
|
+
PATH_ENCODING = Encoding::UTF_8
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def open(stream, param = {}, &block)
|
9
|
+
szw = self.new
|
10
|
+
szw.open(stream, param)
|
11
|
+
if (block)
|
12
|
+
block.call(szw)
|
13
|
+
szw.compress
|
14
|
+
szw.close
|
15
|
+
else
|
16
|
+
szw
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_directory(stream, dir, param = {})
|
21
|
+
password = { password: param.delete(:password) }
|
22
|
+
self.open(stream, password) do |szw|
|
23
|
+
szw.add_directory(dir, param)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
alias add_dir add_directory
|
27
|
+
|
28
|
+
def add_file(stream, filename, param = {})
|
29
|
+
password = { password: param.delete(:password) }
|
30
|
+
self.open(stream, password) do |szw|
|
31
|
+
szw.add_file(filename, param)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def open(stream, param = {})
|
37
|
+
stream.set_encoding(Encoding::ASCII_8BIT)
|
38
|
+
open_impl(stream, param)
|
39
|
+
return self
|
40
|
+
end
|
41
|
+
|
42
|
+
def compress
|
43
|
+
compress_impl(compress_proc)
|
44
|
+
return self
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_file(filename, opt={})
|
48
|
+
path = Pathname(filename)
|
49
|
+
check_option(opt, [ :as ])
|
50
|
+
|
51
|
+
if (opt[:as])
|
52
|
+
filename = Pathname(opt[:as]).cleanpath
|
53
|
+
raise ArgumentError.new(":as should contain valid pathname. #{opt[:as]}") if (filename.to_s.empty?)
|
54
|
+
raise ArgumentError.new(":as should be relative. #{opt[:as]}") if (filename.absolute?)
|
55
|
+
else
|
56
|
+
raise ArgumentError.new("filename should be relative. #{filename}") if (path.absolute?)
|
57
|
+
filename = path.cleanpath
|
58
|
+
end
|
59
|
+
add_item(UpdateInfo.file(filename.to_s.encode(PATH_ENCODING), path, self))
|
60
|
+
return self
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_data(data, filename, opt={})
|
64
|
+
path = Pathname(filename)
|
65
|
+
raise ArgumentError.new("filename should be relative") if (path.absolute?)
|
66
|
+
check_option(opt, [ :ctime, :atime, :mtime ])
|
67
|
+
|
68
|
+
name = path.cleanpath.to_s.encode(PATH_ENCODING)
|
69
|
+
add_item(UpdateInfo.buffer(name, data, opt))
|
70
|
+
return self
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_directory(directory, opt={})
|
74
|
+
directory = Pathname(directory).cleanpath
|
75
|
+
check_option(opt, [ :as ])
|
76
|
+
|
77
|
+
if (opt[:as])
|
78
|
+
base_dir = Pathname(opt[:as]).cleanpath
|
79
|
+
raise ArgumentError.new(":as should contain valid pathname. #{opt[:as]}") if (base_dir.to_s.empty?)
|
80
|
+
raise ArgumentError.new(":as should be relative. #{opt[:as]}") if (base_dir.absolute?)
|
81
|
+
|
82
|
+
mkdir(base_dir, { ctime: directory.ctime, atime: directory.atime, mtime: directory.mtime })
|
83
|
+
else
|
84
|
+
raise ArgumentError.new("directory should be relative #{directory}") if (directory.absolute?)
|
85
|
+
|
86
|
+
mkdir(directory, { ctime: directory.ctime, atime: directory.atime, mtime: directory.mtime })
|
87
|
+
end
|
88
|
+
|
89
|
+
Pathname.glob(directory.join("**", "*").to_s) do |entry|
|
90
|
+
name = (base_dir + entry.relative_path_from(directory)).cleanpath if (base_dir)
|
91
|
+
|
92
|
+
if (entry.file?)
|
93
|
+
add_file(entry, as: name)
|
94
|
+
elsif (entry.directory?)
|
95
|
+
mkdir(name || entry, { ctime: entry.ctime, atime: entry.atime, mtime: entry.mtime })
|
96
|
+
else
|
97
|
+
raise "#{entry} is invalid entry"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
return self
|
102
|
+
end
|
103
|
+
alias add_dir add_directory
|
104
|
+
|
105
|
+
def mkdir(directory_name, opt={})
|
106
|
+
path = Pathname(directory_name)
|
107
|
+
raise ArgumentError.new("directory_name should be relative") if (path.absolute?)
|
108
|
+
check_option(opt, [ :ctime, :atime, :mtime ])
|
109
|
+
|
110
|
+
name = path.cleanpath.to_s.encode(PATH_ENCODING)
|
111
|
+
add_item(UpdateInfo.dir(name, opt))
|
112
|
+
return self
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
def check_option(opt, keys)
|
117
|
+
invalid_keys = opt.keys - keys
|
118
|
+
raise ArgumentError.new("invalid option: " + invalid_keys.join(", ")) unless (invalid_keys.empty?)
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
def compress_proc
|
123
|
+
return Proc.new do |type, info|
|
124
|
+
case(type)
|
125
|
+
when :stream
|
126
|
+
if (info.buffer?)
|
127
|
+
next StringIO.new(info.data)
|
128
|
+
elsif (info.file?)
|
129
|
+
next File.open(info.data, "rb")
|
130
|
+
else
|
131
|
+
next nil
|
132
|
+
end
|
133
|
+
when :result
|
134
|
+
info[:stream].close if (info[:stream])
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
private :compress_proc
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
Writer = SevenZipWriter
|
143
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module SevenZipRuby
|
2
|
+
class UpdateInfo
|
3
|
+
class << self
|
4
|
+
def buffer(name, data, opt={})
|
5
|
+
new(:buffer, opt.merge({ name: name, data: data }))
|
6
|
+
end
|
7
|
+
|
8
|
+
def dir(name, opt={})
|
9
|
+
new(:dir, opt.merge({ name: name }))
|
10
|
+
end
|
11
|
+
|
12
|
+
def file(name, filepath, szw)
|
13
|
+
new(:file, { name: name, filepath: filepath, szw: szw })
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(type, param)
|
18
|
+
@type = type
|
19
|
+
case(type)
|
20
|
+
when :buffer
|
21
|
+
name = param.delete(:name)
|
22
|
+
data = param.delete(:data)
|
23
|
+
initialize_buffer(name, data, param)
|
24
|
+
when :dir
|
25
|
+
name = param.delete(:name)
|
26
|
+
initialize_dir(name, param)
|
27
|
+
when :file
|
28
|
+
initialize_file(param[:name], param[:filepath], param[:szw])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize_buffer(name, data, opt)
|
33
|
+
@index_in_archive = nil
|
34
|
+
@new_data = true
|
35
|
+
@new_properties = true
|
36
|
+
@anti = false
|
37
|
+
|
38
|
+
@path = name
|
39
|
+
@dir = false
|
40
|
+
@data = data
|
41
|
+
@size = data.size
|
42
|
+
@attrib = 0x20
|
43
|
+
@posix_attrib = 0x00
|
44
|
+
time = Time.now
|
45
|
+
@ctime = (opt[:ctime] || time)
|
46
|
+
@atime = (opt[:atime] || time)
|
47
|
+
@mtime = (opt[:mtime] || time)
|
48
|
+
@user = @group = nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize_dir(name, opt)
|
52
|
+
@index_in_archive = nil
|
53
|
+
@new_data = true
|
54
|
+
@new_properties = true
|
55
|
+
@anti = false
|
56
|
+
|
57
|
+
@path = name
|
58
|
+
@dir = true
|
59
|
+
@data = nil
|
60
|
+
@size = 0
|
61
|
+
@attrib = 0x10
|
62
|
+
@posix_attrib = 0x00
|
63
|
+
time = Time.now
|
64
|
+
@ctime = (opt[:ctime] || time)
|
65
|
+
@atime = (opt[:atime] || time)
|
66
|
+
@mtime = (opt[:mtime] || time)
|
67
|
+
@user = @group = nil
|
68
|
+
end
|
69
|
+
|
70
|
+
def initialize_file(name, filepath, szw)
|
71
|
+
@index_in_archive = nil
|
72
|
+
@new_data = true
|
73
|
+
@new_properties = true
|
74
|
+
@anti = false
|
75
|
+
|
76
|
+
@path = name.to_s
|
77
|
+
@dir = false
|
78
|
+
filepath = Pathname(filepath).expand_path
|
79
|
+
@data = filepath.to_s
|
80
|
+
@size = filepath.size
|
81
|
+
@attrib = (szw.get_file_attribute(filepath.to_s) || 0x20)
|
82
|
+
@posix_attrib = 0x00
|
83
|
+
@ctime = filepath.ctime
|
84
|
+
@atime = filepath.atime
|
85
|
+
@mtime = filepath.mtime
|
86
|
+
@user = @group = nil
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
attr_reader :index_in_archive, :path, :data, :size, :attrib, :ctime, :atime, :mtime, :posix_attrib, :user, :group
|
91
|
+
|
92
|
+
def buffer?
|
93
|
+
return (@type == :buffer)
|
94
|
+
end
|
95
|
+
|
96
|
+
def directory?
|
97
|
+
return @dir
|
98
|
+
end
|
99
|
+
|
100
|
+
def file?
|
101
|
+
return !(@dir)
|
102
|
+
end
|
103
|
+
|
104
|
+
def new_data?
|
105
|
+
return @new_data
|
106
|
+
end
|
107
|
+
|
108
|
+
def new_properties?
|
109
|
+
return @new_properties
|
110
|
+
end
|
111
|
+
|
112
|
+
def anti?
|
113
|
+
return @anti
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'seven_zip_ruby/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "seven_zip_ruby"
|
8
|
+
spec.version = SevenZipRuby::VERSION
|
9
|
+
spec.authors = ["Masamitsu MURASE"]
|
10
|
+
spec.email = ["masamitsu.murase@gmail.com"]
|
11
|
+
spec.description = %q{SevenZipRuby is a gem library to read and write 7zip archives. This gem library calls official 7z.dll internally.}
|
12
|
+
spec.summary = %q{This is a gem library to read and write 7-Zip files.}
|
13
|
+
spec.homepage = "https://github.com/masamitsu-murase/seven_zip_ruby"
|
14
|
+
spec.license = "LGPL + unRAR"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/).select{ |i| !(i.start_with?("pkg") || i.start_with?("resources") || i.start_with?("ext")) } + Dir.glob("lib/**/*.so").to_a
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
|
25
|
+
# spec.extensions << "ext/seven_zip_ruby/extconf.rb"
|
26
|
+
|
27
|
+
spec.platform = Gem::Platform::CURRENT
|
28
|
+
end
|
@@ -0,0 +1,490 @@
|
|
1
|
+
require("seven_zip_ruby")
|
2
|
+
require_relative("seven_zip_ruby_spec_helper")
|
3
|
+
|
4
|
+
describe SevenZipRuby do
|
5
|
+
before(:all) do
|
6
|
+
SevenZipRubySpecHelper.prepare_all
|
7
|
+
# GC.stress = true
|
8
|
+
end
|
9
|
+
|
10
|
+
after(:all) do
|
11
|
+
# GC.stress = false
|
12
|
+
SevenZipRubySpecHelper.cleanup_all
|
13
|
+
end
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
SevenZipRubySpecHelper.prepare_each
|
17
|
+
end
|
18
|
+
|
19
|
+
after(:each) do
|
20
|
+
SevenZipRubySpecHelper.cleanup_each
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
describe SevenZipRuby::SevenZipReader do
|
25
|
+
|
26
|
+
example "get entry information in the archive" do
|
27
|
+
File.open(SevenZipRubySpecHelper::SEVEN_ZIP_FILE, "rb") do |file|
|
28
|
+
szr = SevenZipRuby::SevenZipReader.new
|
29
|
+
szr.open(file)
|
30
|
+
entries = szr.entries
|
31
|
+
|
32
|
+
expect(entries.size).to be SevenZipRubySpecHelper::SAMPLE_DATA.size
|
33
|
+
|
34
|
+
SevenZipRubySpecHelper::SAMPLE_DATA.each do |sample|
|
35
|
+
entry = entries.select{ |i| i.path == Pathname(sample[:name]).cleanpath }
|
36
|
+
expect(entry.size).to be 1
|
37
|
+
|
38
|
+
entry = entry[0]
|
39
|
+
expect(entry.directory?).to be sample[:directory]
|
40
|
+
end
|
41
|
+
|
42
|
+
szr.close
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
example "get archive information" do
|
47
|
+
File.open(SevenZipRubySpecHelper::SEVEN_ZIP_FILE, "rb") do |file|
|
48
|
+
SevenZipRuby::SevenZipReader.open(file) do |szr|
|
49
|
+
info = szr.archive_property
|
50
|
+
|
51
|
+
expect(info.num_blocks).to be_a Integer
|
52
|
+
expect(info.header_size).to be < file.size
|
53
|
+
expect(info.method).to eq "LZMA"
|
54
|
+
expect(info.phy_size).to be file.size
|
55
|
+
expect(info.solid?).to be_true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
example "extract data directly from archive" do
|
61
|
+
File.open(SevenZipRubySpecHelper::SEVEN_ZIP_FILE, "rb") do |file|
|
62
|
+
SevenZipRuby::SevenZipReader.open(file) do |szr|
|
63
|
+
entries = szr.entries
|
64
|
+
|
65
|
+
SevenZipRubySpecHelper::SAMPLE_DATA.each do |sample|
|
66
|
+
entry = entries.find{ |i| i.path == Pathname(sample[:name]).cleanpath }
|
67
|
+
expect(szr.extract_data(entry.index)).to eq sample[:data]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
example "extract selected data from archive" do
|
74
|
+
File.open(SevenZipRubySpecHelper::SEVEN_ZIP_FILE, "rb") do |file|
|
75
|
+
SevenZipRuby::SevenZipReader.open(file) do |szr|
|
76
|
+
entries = szr.entries.select{ |i| i.file? }
|
77
|
+
expect(szr.extract_data(entries).all?).to eq true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
example "extract archive" do
|
83
|
+
File.open(SevenZipRubySpecHelper::SEVEN_ZIP_FILE, "rb") do |file|
|
84
|
+
SevenZipRuby::SevenZipReader.open(file) do |szr|
|
85
|
+
szr.extract_all(SevenZipRubySpecHelper::EXTRACT_DIR)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
Dir.chdir(SevenZipRubySpecHelper::EXTRACT_DIR) do
|
90
|
+
SevenZipRubySpecHelper::SAMPLE_DATA.each do |info|
|
91
|
+
path = Pathname(info[:name])
|
92
|
+
expected_path = Pathname(SevenZipRubySpecHelper::SAMPLE_FILE_DIR) + info[:name]
|
93
|
+
expect(path.mtime.to_i).to eq expected_path.mtime.to_i
|
94
|
+
expect(path.file?).to eq expected_path.file?
|
95
|
+
(expect(File.open(path, "rb", &:read)).to eq info[:data]) if (path.file?)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
example "run in another thread" do
|
101
|
+
File.open(SevenZipRubySpecHelper::SEVEN_ZIP_FILE, "rb") do |file|
|
102
|
+
szr = nil
|
103
|
+
sample = nil
|
104
|
+
entry = nil
|
105
|
+
th = Thread.new do
|
106
|
+
szr = SevenZipRuby::SevenZipReader.open(file)
|
107
|
+
sample = SevenZipRubySpecHelper::SAMPLE_DATA.sample
|
108
|
+
entry = szr.entries.find{ |i| i.path == Pathname(sample[:name]).cleanpath }
|
109
|
+
end
|
110
|
+
th.join
|
111
|
+
|
112
|
+
expect(szr.extract_data(entry.index)).to eq sample[:data]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
example "test archive" do
|
117
|
+
data = File.open(SevenZipRubySpecHelper::SEVEN_ZIP_FILE, "rb", &:read)
|
118
|
+
SevenZipRuby::SevenZipReader.open(StringIO.new(data)) do |szr|
|
119
|
+
expect(szr.test).to eq true
|
120
|
+
end
|
121
|
+
|
122
|
+
expect(SevenZipRuby::SevenZipReader.verify(StringIO.new(data))).to eq true
|
123
|
+
|
124
|
+
data[0x27] = 0xEB.chr # This highly dependes on the current test binary.
|
125
|
+
SevenZipRuby::SevenZipReader.open(StringIO.new(data)) do |szr|
|
126
|
+
expect(szr.test).to eq false
|
127
|
+
expect(szr.verify_detail).to eq [ :DataError, :DataError, :DataError, true, true, true ]
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
data = File.open(SevenZipRubySpecHelper::SEVEN_ZIP_PASSWORD_FILE, "rb", &:read)
|
132
|
+
SevenZipRuby::SevenZipReader.open(StringIO.new(data), { password: SevenZipRubySpecHelper::SEVEN_ZIP_PASSWORD }) do |szr|
|
133
|
+
expect(szr.verify).to eq true
|
134
|
+
end
|
135
|
+
|
136
|
+
SevenZipRuby::SevenZipReader.open(StringIO.new(data), { password: "wrong password" }) do |szr|
|
137
|
+
expect(szr.verify).to eq false
|
138
|
+
end
|
139
|
+
|
140
|
+
SevenZipRuby::SevenZipReader.open(StringIO.new(data), { password: "wrong password" }) do |szr|
|
141
|
+
expect(szr.verify_detail).to eq [ :DataError, :DataError, :DataError, true, true, true ]
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
describe "error handling" do
|
147
|
+
|
148
|
+
example "throw in method" do
|
149
|
+
[ :read, :seek ].each do |method|
|
150
|
+
catch do |tag|
|
151
|
+
File.open(SevenZipRubySpecHelper::SEVEN_ZIP_FILE, "rb") do |file|
|
152
|
+
file.define_singleton_method(method) do |*args|
|
153
|
+
throw tag
|
154
|
+
end
|
155
|
+
expect{ SevenZipRuby::SevenZipReader.open(file) }.to raise_error(ArgumentError)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
example "raise error in open" do
|
162
|
+
error = StandardError.new
|
163
|
+
|
164
|
+
[ :read, :seek ].each do |method|
|
165
|
+
file = File.open(SevenZipRubySpecHelper::SEVEN_ZIP_FILE, "rb")
|
166
|
+
file.define_singleton_method(method) do |*args|
|
167
|
+
raise error
|
168
|
+
end
|
169
|
+
expect{ SevenZipRuby::SevenZipReader.open(file) }.to raise_error(error)
|
170
|
+
file.close
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
example "raise error after open" do
|
175
|
+
error = StandardError.new
|
176
|
+
|
177
|
+
[ :read, :seek ].each do |method|
|
178
|
+
file = File.open(SevenZipRubySpecHelper::SEVEN_ZIP_FILE, "rb")
|
179
|
+
|
180
|
+
szr = nil
|
181
|
+
expect{ szr = SevenZipRuby::SevenZipReader.open(file) }.not_to raise_error
|
182
|
+
|
183
|
+
file.define_singleton_method(method) do |*args|
|
184
|
+
raise error
|
185
|
+
end
|
186
|
+
expect{ szr.extract_data(1) }.to raise_error(error)
|
187
|
+
|
188
|
+
file.close
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
example "try to extract/entries before open" do
|
193
|
+
File.open(SevenZipRubySpecHelper::SEVEN_ZIP_FILE, "rb") do |file|
|
194
|
+
szr = SevenZipRuby::SevenZipReader.new
|
195
|
+
expect{ szr.extract_data(1) }.to raise_error(SevenZipRuby::InvalidOperation)
|
196
|
+
expect{ szr.entry(1) }.to raise_error(SevenZipRuby::InvalidOperation)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
example "try to extract/entries after close" do
|
201
|
+
File.open(SevenZipRubySpecHelper::SEVEN_ZIP_FILE, "rb") do |file|
|
202
|
+
szr = SevenZipRuby::SevenZipReader.open(file)
|
203
|
+
szr.close
|
204
|
+
|
205
|
+
expect{ szr.extract_data(1) }.to raise_error(SevenZipRuby::InvalidOperation)
|
206
|
+
expect{ szr.entry(1) }.to raise_error(SevenZipRuby::InvalidOperation)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
example "kill thread" do
|
211
|
+
th = Thread.start do
|
212
|
+
File.open(SevenZipRubySpecHelper::SEVEN_ZIP_FILE, "rb") do |file|
|
213
|
+
class << file
|
214
|
+
alias orig_read read
|
215
|
+
|
216
|
+
def read(*args)
|
217
|
+
sleep 2
|
218
|
+
return orig_read(*args)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
SevenZipRuby::SevenZipReader.open(file)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
sleep 1
|
227
|
+
expect{ th.kill }.not_to raise_error # Thread can be killed.
|
228
|
+
|
229
|
+
|
230
|
+
th = Thread.start do
|
231
|
+
SevenZipRuby::SevenZipWriter.open(output) do |szw|
|
232
|
+
szw.method = "BZIP2"
|
233
|
+
szw.level = 9
|
234
|
+
szw.multi_thread = false
|
235
|
+
szw.add_data(SevenZipRubySpecHelper::SAMPLE_LARGE_RANDOM_DATA * 2, "hoge.txt")
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
sleep 0.1 # Highly dependes on CPU speed...
|
240
|
+
expect{ th.kill }.not_to raise_error # Thread can be killed.
|
241
|
+
end
|
242
|
+
|
243
|
+
end
|
244
|
+
|
245
|
+
end
|
246
|
+
|
247
|
+
|
248
|
+
describe SevenZipRuby::SevenZipWriter do
|
249
|
+
|
250
|
+
example "compress without block" do
|
251
|
+
output = StringIO.new("")
|
252
|
+
szw = SevenZipRuby::SevenZipWriter.new
|
253
|
+
szw.open(output)
|
254
|
+
szw.add_data("This is hoge.txt content.", "hoge.txt")
|
255
|
+
szw.add_data("This is hoge2.txt content.", "hoge2.txt")
|
256
|
+
szw.mkdir("hoge/hoge/hoge")
|
257
|
+
szw.compress
|
258
|
+
szw.close
|
259
|
+
output.close
|
260
|
+
end
|
261
|
+
|
262
|
+
example "compress" do
|
263
|
+
output = StringIO.new("")
|
264
|
+
SevenZipRuby::SevenZipWriter.open(output) do |szw|
|
265
|
+
szw.add_data("This is hoge.txt content.", "hoge.txt")
|
266
|
+
szw.add_data("This is hoge2.txt content.", "hoge2.txt")
|
267
|
+
szw.mkdir("hoge/hoge/hoge")
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
example "compress local file" do
|
272
|
+
Dir.chdir(SevenZipRubySpecHelper::SAMPLE_FILE_DIR) do
|
273
|
+
output = StringIO.new("")
|
274
|
+
SevenZipRuby::SevenZipWriter.open(output) do |szw|
|
275
|
+
data = SevenZipRubySpecHelper::SAMPLE_DATA[0]
|
276
|
+
szw.add_file(data[:name])
|
277
|
+
end
|
278
|
+
|
279
|
+
output.rewind
|
280
|
+
SevenZipRuby::SevenZipReader.open(output) do |szr|
|
281
|
+
data = SevenZipRubySpecHelper::SAMPLE_DATA[0]
|
282
|
+
expect(szr.entries[0].path.to_s).to eq data[:name]
|
283
|
+
expect(szr.extract_data(0)).to eq data[:data]
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
example "add_directory" do
|
289
|
+
Dir.chdir(SevenZipRubySpecHelper::SAMPLE_FILE_DIR) do
|
290
|
+
output = StringIO.new("")
|
291
|
+
SevenZipRuby::SevenZipWriter.open(output) do |szw|
|
292
|
+
Pathname.glob("*") do |path|
|
293
|
+
if (path.file?)
|
294
|
+
szw.add_file(path)
|
295
|
+
else
|
296
|
+
szw.add_directory(path)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
output.rewind
|
302
|
+
SevenZipRuby::SevenZipReader.open(output) do |szr|
|
303
|
+
entries = szr.entries
|
304
|
+
expect(entries.size).to eq SevenZipRubySpecHelper::SAMPLE_DATA.size
|
305
|
+
|
306
|
+
entries.each do |entry|
|
307
|
+
entry_in_sample = SevenZipRubySpecHelper::SAMPLE_DATA.find{ |i| i[:name] == entry.path.to_s }
|
308
|
+
local_entry = Pathname(File.join(SevenZipRubySpecHelper::SAMPLE_FILE_DIR, entry_in_sample[:name]))
|
309
|
+
if (entry_in_sample[:directory])
|
310
|
+
expect(entry.directory?).to eq true
|
311
|
+
else
|
312
|
+
expect(szr.extract_data(entry)).to eq File.open(entry_in_sample[:name], "rb", &:read)
|
313
|
+
end
|
314
|
+
expect(entry.mtime.to_i).to eq local_entry.mtime.to_i
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
example "add_directory singleton version" do
|
321
|
+
dir = File.join(SevenZipRubySpecHelper::SAMPLE_FILE_DIR, "..")
|
322
|
+
dirname = File.basename(SevenZipRubySpecHelper::SAMPLE_FILE_DIR)
|
323
|
+
Dir.chdir(dir) do
|
324
|
+
output = StringIO.new("")
|
325
|
+
SevenZipRuby::SevenZipWriter.add_directory(output, dirname)
|
326
|
+
|
327
|
+
output2 = StringIO.new("")
|
328
|
+
SevenZipRuby::SevenZipWriter.open(output2) do |szr|
|
329
|
+
szr.add_directory(dirname)
|
330
|
+
end
|
331
|
+
|
332
|
+
expect(output.string).to eq output2.string
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
example "use as option" do
|
337
|
+
output = StringIO.new("")
|
338
|
+
SevenZipRuby::SevenZipWriter.open(output) do |szw|
|
339
|
+
szw.add_directory(SevenZipRubySpecHelper::SAMPLE_FILE_DIR, as: "test/dir")
|
340
|
+
end
|
341
|
+
|
342
|
+
output.rewind
|
343
|
+
SevenZipRuby::SevenZipReader.open(output) do |szr|
|
344
|
+
base_dir = Pathname(SevenZipRubySpecHelper::SAMPLE_FILE_DIR)
|
345
|
+
entries = szr.entries
|
346
|
+
files = Pathname.glob(base_dir.to_s + "/**/*") +[ base_dir ]
|
347
|
+
|
348
|
+
expect(entries.size).to eq files.size
|
349
|
+
|
350
|
+
expect(entries.all?{ |i| i.path.to_s.start_with?("test/dir") }).to eq true
|
351
|
+
|
352
|
+
entries.each do |entry|
|
353
|
+
file = files.find do |i|
|
354
|
+
i.relative_path_from(base_dir) == entry.path.relative_path_from(Pathname("test/dir"))
|
355
|
+
end
|
356
|
+
expect(file.directory?).to eq entry.directory?
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
example "use various methods" do
|
362
|
+
[ "COPY", "DEFLATE", "LZMA", "LZMA2", "BZIP2", "PPMd" ].each do |type|
|
363
|
+
output = StringIO.new("")
|
364
|
+
SevenZipRuby::SevenZipWriter.open(output) do |szw|
|
365
|
+
szw.method = type
|
366
|
+
szw.add_data(SevenZipRubySpecHelper::SAMPLE_LARGE_RANDOM_DATA, "hoge.txt")
|
367
|
+
end
|
368
|
+
|
369
|
+
SevenZipRuby::SevenZipReader.open(StringIO.new(output.string)) do |szr|
|
370
|
+
expect(szr.extract_data(0)).to eq SevenZipRubySpecHelper::SAMPLE_LARGE_RANDOM_DATA
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
example "set compression level" do
|
376
|
+
size = [ 0, 1, 3, 5, 7, 9 ].map do |level|
|
377
|
+
output = StringIO.new("")
|
378
|
+
SevenZipRuby::SevenZipWriter.open(output) do |szw|
|
379
|
+
szw.level = level
|
380
|
+
data = SevenZipRubySpecHelper::SAMPLE_LARGE_RANDOM_DATA
|
381
|
+
time = SevenZipRubySpecHelper::SAMPLE_LARGE_RANDOM_DATA_TIMESTAMP
|
382
|
+
szw.add_data(data, "hoge1.txt", mtime: time)
|
383
|
+
szw.add_data(data + data.slice(1 .. -1), "hoge2.txt", mtime: time)
|
384
|
+
szw.add_data(data + data.reverse + data.slice(1 .. -1), "hoge3.txt", mtime: time)
|
385
|
+
end
|
386
|
+
next output.string.size
|
387
|
+
end
|
388
|
+
size.each_cons(2) do |large, small|
|
389
|
+
expect(large - small >= 0).to eq true
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
example "set solid" do
|
394
|
+
size = [ false, true ].map do |solid|
|
395
|
+
output = StringIO.new("")
|
396
|
+
SevenZipRuby::SevenZipWriter.open(output) do |szw|
|
397
|
+
szw.solid = solid
|
398
|
+
data = SevenZipRubySpecHelper::SAMPLE_LARGE_RANDOM_DATA
|
399
|
+
szw.add_data(data, "hoge1.txt")
|
400
|
+
szw.add_data(data + data.slice(1 .. -1), "hoge2.txt")
|
401
|
+
end
|
402
|
+
next output.string.size
|
403
|
+
end
|
404
|
+
expect(size.sort.reverse).to eq size
|
405
|
+
end
|
406
|
+
|
407
|
+
example "set header_compression" do
|
408
|
+
size = [ false, true ].map do |header_compression|
|
409
|
+
output = StringIO.new("")
|
410
|
+
SevenZipRuby::SevenZipWriter.open(output) do |szw|
|
411
|
+
szw.header_compression = header_compression
|
412
|
+
data = SevenZipRubySpecHelper::SAMPLE_LARGE_RANDOM_DATA
|
413
|
+
10.times do |i|
|
414
|
+
szw.add_data(data, "hoge#{i}.txt")
|
415
|
+
end
|
416
|
+
end
|
417
|
+
next output.string.size
|
418
|
+
end
|
419
|
+
expect(size.sort.reverse).to eq size
|
420
|
+
end
|
421
|
+
|
422
|
+
if (SevenZipRubySpecHelper.processor_count && SevenZipRubySpecHelper.processor_count > 1)
|
423
|
+
example "set multi_thread" do
|
424
|
+
time = [ false, true ].map do |multi_thread|
|
425
|
+
output = StringIO.new("")
|
426
|
+
start = nil
|
427
|
+
SevenZipRuby::SevenZipWriter.open(output) do |szw|
|
428
|
+
szw.method = "BZIP2" # BZIP2 uses multi threads.
|
429
|
+
szw.multi_thread = multi_thread
|
430
|
+
data = SevenZipRubySpecHelper::SAMPLE_LARGE_RANDOM_DATA
|
431
|
+
szw.add_data(data * 10, "hoge.txt")
|
432
|
+
start = Time.now
|
433
|
+
end
|
434
|
+
next Time.now - start
|
435
|
+
end
|
436
|
+
expect(time.sort.reverse).to eq time
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
|
441
|
+
describe "error handling" do
|
442
|
+
|
443
|
+
example "raise error in update" do
|
444
|
+
error = StandardError.new
|
445
|
+
|
446
|
+
[ :write, :seek ].each do |method|
|
447
|
+
output = StringIO.new("")
|
448
|
+
output.define_singleton_method(method) do |*args|
|
449
|
+
raise error
|
450
|
+
end
|
451
|
+
expect{ SevenZipRuby::SevenZipWriter.open(output).compress }.to raise_error(error)
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
example "invalid method" do
|
456
|
+
expect{ SevenZipRuby::SevenZipWriter.open(StringIO.new("")).method = "Unknown" }.to raise_error
|
457
|
+
end
|
458
|
+
|
459
|
+
example "invalid level" do
|
460
|
+
expect{ SevenZipRuby::SevenZipWriter.open(StringIO.new("")).level = 2 }.to raise_error
|
461
|
+
end
|
462
|
+
|
463
|
+
example "add_data/mkdir/compress/close before open" do
|
464
|
+
szw = SevenZipRuby::SevenZipWriter.new
|
465
|
+
expect{ szw.add_data("This is hoge.txt content.", "hoge.txt") }.to raise_error(SevenZipRuby::InvalidOperation)
|
466
|
+
|
467
|
+
szw = SevenZipRuby::SevenZipWriter.new
|
468
|
+
expect{ szw.mkdir("hoge/hoge") }.to raise_error(SevenZipRuby::InvalidOperation)
|
469
|
+
|
470
|
+
szw = SevenZipRuby::SevenZipWriter.new
|
471
|
+
expect{ szw.compress }.to raise_error(SevenZipRuby::InvalidOperation)
|
472
|
+
|
473
|
+
szw = SevenZipRuby::SevenZipWriter.new
|
474
|
+
expect{ szw.close }.to raise_error(SevenZipRuby::InvalidOperation)
|
475
|
+
end
|
476
|
+
|
477
|
+
example "add_data after close" do
|
478
|
+
output = StringIO.new("")
|
479
|
+
szw = SevenZipRuby::SevenZipWriter.new
|
480
|
+
szw.open(output)
|
481
|
+
szw.close
|
482
|
+
expect{ szw.add_data("This is hoge.txt content.", "hoge.txt") }.to raise_error(SevenZipRuby::InvalidOperation)
|
483
|
+
end
|
484
|
+
|
485
|
+
end
|
486
|
+
|
487
|
+
end
|
488
|
+
|
489
|
+
end
|
490
|
+
|