rubyzip 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubyzip might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 68e2727c6e1f49edc93c3081e74a8b8dd6cf8ea8
4
- data.tar.gz: c6e0a74722936557ccec3a74f3d2efcf2e4a21b1
3
+ metadata.gz: e7eca6764ebd3b2104ce779b422472ed1df3f034
4
+ data.tar.gz: 2f90a3751e1533d46ff864f177f09cd2433b90e0
5
5
  SHA512:
6
- metadata.gz: 77c0f46c33bfe45177adcc0bddf68fc3ae55624ed5fc95163eaf0546c028fd204fdf8167a2ce041389c4c9fe4961868dfd0ed79dfe3ea3439634542db9aecd1d
7
- data.tar.gz: 7a2a4164ce2591204f30a36b337a4e1ce5907b3649487c9a366aff6d366b68cb61b15136cb2c0015845239a40d99158aabba2d635e7b46e5e508813dc1512aae
6
+ metadata.gz: ebd0ca646df6f8d652fc91f5d5306b101fe56bb8577d6a401b3b46f6a1fc6c9281df3cb88a555bed175c53ae01d437fd92b01487983f1eaf50d03fc94586bd1a
7
+ data.tar.gz: eff9c8f931440447bf5656720f32748523b792e5189e7bed1d000c7686f09a19cd4a019629d81f058dffd6d770aa1928e28e86cdb93561c801dbc3c6c21f7c56
data/README.md CHANGED
@@ -9,11 +9,11 @@ rubyzip is a ruby library for reading and writing zip files.
9
9
 
10
10
  Rubyzip interface changed!!! No need to do `require "zip/zip"` and `Zip` prefix in class names removed.
11
11
 
12
- If you have issues with any third-party gems what required rubyzip you can use next temporary fix:
12
+ If you have issues with any third-party gems what required old version of rubyzip you can use next workaround:
13
13
 
14
14
  ```ruby
15
- # Place this line before your library or on the head of your Gemfile
16
- gem 'rubyzip', '< 1.0.0'
15
+ gem 'rubyzip', '>= 1.0.0' # will load new rubyzip version
16
+ gem 'zip-zip' # will load compatibility for old rubyzip API.
17
17
  ```
18
18
 
19
19
  ## Requirements
@@ -53,6 +53,7 @@ Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
53
53
  # - The original file, including the path to find it
54
54
  zipfile.add(filename, folder + '/' + filename)
55
55
  end
56
+ zipfile.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
56
57
  end
57
58
  ```
58
59
 
@@ -90,6 +91,26 @@ fruit/orange
90
91
 
91
92
  After this entries in zip archive will be saved in ordered state.
92
93
 
94
+ ### Reading a Zip file
95
+
96
+ ```ruby
97
+ Zip::File.open('foo.zip') do |zip_file|
98
+ # Handle entries one by one
99
+ zip_file.each do |entry|
100
+ # Extract to file/directory/symlink
101
+ puts "Extracting #{entry.name}"
102
+ entry.extract(dest_file)
103
+
104
+ # Read into memory
105
+ content = entry.get_input_stream.read
106
+ end
107
+
108
+ # Find specific entry
109
+ entry = zip_file.glob('*.csv').first
110
+ puts entry.get_input_stream.read
111
+ end
112
+ ```
113
+
93
114
  ## Known issues
94
115
 
95
116
  ### Modify docx file with rubyzip
@@ -115,32 +136,6 @@ end
115
136
  File.open(new_path, "w") {|f| f.write(buffer.string) }
116
137
  ```
117
138
 
118
- ## Further Documentation
119
-
120
- There is more than one way to access or create a zip archive with
121
- rubyzip. The basic API is modeled after the classes in
122
- java.util.zip from the Java SDK. This means there are classes such
123
- as Zip::InputStream, Zip::OutputStream and
124
- Zip::File. Zip::InputStream provides a basic interface for
125
- iterating through the entries in a zip archive and reading from the
126
- entries in the same way as from a regular File or IO
127
- object. OutputStream is the corresponding basic output
128
- facility. Zip::File provides a mean for accessing the archives
129
- central directory and provides means for accessing any entry without
130
- having to iterate through the archive. Unlike Java's
131
- java.util.zip.ZipFile rubyzip's Zip::File is mutable, which means
132
- it can be used to change zip files as well.
133
-
134
- Another way to access a zip archive with rubyzip is to use rubyzip's
135
- Zip::FileSystem API. Using this API files can be read from and
136
- written to the archive in much the same manner as ruby's builtin
137
- classes allows files to be read from and written to the file system.
138
-
139
- For details about the specific behaviour of classes and methods refer
140
- to the test suite. Finally you can generate the rdoc documentation or
141
- visit http://rubyzip.sourceforge.net.
142
-
143
-
144
139
  ## Configuration
145
140
 
146
141
  By default, rubyzip will not overwrite files if they already exist inside of the extracted path. To change this behavior, you may specify a configuration option like so:
@@ -163,6 +158,14 @@ If you want to store non english names and want to open properly file on Windows
163
158
  Zip.unicode_names = true
164
159
  ```
165
160
 
161
+ You can set the default compression level like so:
162
+
163
+ ```ruby
164
+ Zip.default_compression = Zlib::DEFAULT_COMPRESSION
165
+ ```
166
+
167
+ It defaults to `Zlib::DEFAULT_COMPRESSION`. Possible values are `Zlib::BEST_COMPRESSION`, `Zlib::DEFAULT_COMPRESSION` and `Zlib::NO_COMPRESSION`
168
+
166
169
  All settings in same time
167
170
 
168
171
  ```ruby
@@ -170,9 +173,18 @@ All settings in same time
170
173
  c.on_exists_proc = true
171
174
  c.continue_on_exists_proc = true
172
175
  c.unicode_names = true
176
+ c.default_compression = Zlib::BEST_COMPRESSION
173
177
  end
174
178
  ```
175
179
 
180
+ By default Zip64 support is disabled for writing. To enable it do next:
181
+
182
+ ```ruby
183
+ Zip.write_zip64_support = true
184
+ ```
185
+
186
+ _NOTE_: If you will enable Zip64 writing then you will need zip extractor with Zip64 support to extract archive.
187
+
176
188
  ## Developing
177
189
 
178
190
  To run tests you need run next commands:
data/Rakefile CHANGED
@@ -4,16 +4,16 @@ require 'rake/testtask'
4
4
  task :default => :test
5
5
 
6
6
  Rake::TestTask.new(:test) do |test|
7
- test.libs << File.join(File.dirname(__FILE__), 'lib')
8
- test.libs << File.join(File.dirname(__FILE__), 'test')
9
- test.pattern = File.join(File.dirname(__FILE__), 'test/alltests.rb')
7
+ test.libs << 'lib'
8
+ test.libs << 'test'
9
+ test.pattern = 'test/**/*_test.rb'
10
10
  test.verbose = true
11
11
  end
12
12
 
13
- Rake::TestTask.new(:zip64_full_test) do |test|
14
- test.libs << File.join(File.dirname(__FILE__), 'lib')
15
- test.libs << File.join(File.dirname(__FILE__), 'test')
16
- test.pattern = File.join(File.dirname(__FILE__), 'test/zip64_full_test.rb')
17
- test.verbose = true
18
- end
13
+ #Rake::TestTask.new(:zip64_full_test) do |test|
14
+ # test.libs << File.join(File.dirname(__FILE__), 'lib')
15
+ # test.libs << File.join(File.dirname(__FILE__), 'test')
16
+ # test.pattern = File.join(File.dirname(__FILE__), 'test/zip64_full_test.rb')
17
+ # test.verbose = true
18
+ #end
19
19
 
data/TODO CHANGED
@@ -4,7 +4,6 @@
4
4
  * Suggestion: Add ZipFile/ZipInputStream example that demonstrates extracting all entries.
5
5
  * Suggestion: ZipFile#extract destination should default to "."
6
6
  * Suggestion: ZipEntry should have extract(), get_input_stream() methods etc
7
- * Suggestion: ZipInputStream/ZipOutputStream should accept an IO object in addition to a filename.
8
7
  * (is buffering used anywhere with write?)
9
8
  * Inflater.sysread should pass the buffer to produce_input.
10
9
  * Implement ZipFsDir.glob
data/lib/zip.rb CHANGED
@@ -34,7 +34,7 @@ end
34
34
 
35
35
  module Zip
36
36
  extend self
37
- attr_accessor :unicode_names, :on_exists_proc, :continue_on_exists_proc, :sort_entries
37
+ attr_accessor :unicode_names, :on_exists_proc, :continue_on_exists_proc, :sort_entries, :default_compression, :write_zip64_support
38
38
 
39
39
  def reset!
40
40
  @_ran_once = false
@@ -42,6 +42,8 @@ module Zip
42
42
  @on_exists_proc = false
43
43
  @continue_on_exists_proc = false
44
44
  @sort_entries = false
45
+ @default_compression = ::Zlib::DEFAULT_COMPRESSION
46
+ @write_zip64_support = false
45
47
  end
46
48
 
47
49
  def setup
@@ -26,10 +26,13 @@ module Zip
26
26
  @entry_set.each { |entry| entry.write_c_dir_entry(io) }
27
27
  eocd_offset = io.tell
28
28
  cdir_size = eocd_offset - cdir_offset
29
- has_zip64_entry = @entry_set.any? { |entry| entry.extra['Zip64'] }
30
- if has_zip64_entry || cdir_offset > 0xFFFFFFFF || cdir_size > 0xFFFFFFFF || @entry_set.size > 0xFFFF
31
- write_64_e_o_c_d(io, cdir_offset, cdir_size)
32
- write_64_eocd_locator(io, eocd_offset)
29
+ if ::Zip.write_zip64_support
30
+ need_zip64_eocd = cdir_offset > 0xFFFFFFFF || cdir_size > 0xFFFFFFFF || @entry_set.size > 0xFFFF
31
+ need_zip64_eocd ||= @entry_set.any? { |entry| entry.extra['Zip64'] }
32
+ if need_zip64_eocd
33
+ write_64_e_o_c_d(io, cdir_offset, cdir_size)
34
+ write_64_eocd_locator(io, eocd_offset)
35
+ end
33
36
  end
34
37
  write_e_o_c_d(io, cdir_offset, cdir_size)
35
38
  end
@@ -93,7 +96,7 @@ module Zip
93
96
  @size_in_bytes = Entry.read_zip_64_long(buf)
94
97
  @cdir_offset = Entry.read_zip_64_long(buf)
95
98
  @zip_64_extensible = buf.slice!(0, buf.bytesize)
96
- raise ZipError, "Zip consistency problem while reading eocd structure" unless buf.size == 0
99
+ raise Error, "Zip consistency problem while reading eocd structure" unless buf.size == 0
97
100
  end
98
101
 
99
102
  def read_e_o_c_d(buf) #:nodoc:
@@ -105,19 +108,19 @@ module Zip
105
108
  @size_in_bytes = Entry.read_zip_long(buf)
106
109
  @cdir_offset = Entry.read_zip_long(buf)
107
110
  comment_length = Entry.read_zip_short(buf)
108
- @comment = if comment_length <= 0
111
+ @comment = if comment_length.to_i <= 0
109
112
  buf.slice!(0, buf.size)
110
113
  else
111
114
  buf.read(comment_length)
112
115
  end
113
- raise ZipError, "Zip consistency problem while reading eocd structure" unless buf.size == 0
116
+ raise Error, "Zip consistency problem while reading eocd structure" unless buf.size == 0
114
117
  end
115
118
 
116
119
  def read_central_directory_entries(io) #:nodoc:
117
120
  begin
118
121
  io.seek(@cdir_offset, IO::SEEK_SET)
119
122
  rescue Errno::EINVAL
120
- raise ZipError, "Zip consistency problem while reading central directory entry"
123
+ raise Error, "Zip consistency problem while reading central directory entry"
121
124
  end
122
125
  @entry_set = EntrySet.new
123
126
  @size.times do
@@ -137,7 +140,7 @@ module Zip
137
140
 
138
141
  def get_e_o_c_d(buf) #:nodoc:
139
142
  sig_index = buf.rindex([END_OF_CDS].pack('V'))
140
- raise ZipError, "Zip end of central directory signature not found" unless sig_index
143
+ raise Error, "Zip end of central directory signature not found" unless sig_index
141
144
  buf = buf.slice!((sig_index + 4)..(buf.bytesize))
142
145
 
143
146
  def buf.read(count)
@@ -162,9 +165,9 @@ module Zip
162
165
 
163
166
  def get_64_e_o_c_d(buf) #:nodoc:
164
167
  zip_64_start = buf.rindex([ZIP64_END_OF_CDS].pack('V'))
165
- raise ZipError, "Zip64 end of central directory signature not found" unless zip_64_start
168
+ raise Error, "Zip64 end of central directory signature not found" unless zip_64_start
166
169
  zip_64_locator = buf.rindex([ZIP64_EOCD_LOCATOR].pack('V'))
167
- raise ZipError, "Zip64 end of central directory signature locator not found" unless zip_64_locator
170
+ raise Error, "Zip64 end of central directory signature locator not found" unless zip_64_locator
168
171
  buf = buf.slice!((zip_64_start + 4)..zip_64_locator)
169
172
 
170
173
  def buf.read(count)
@@ -179,7 +182,7 @@ module Zip
179
182
  @entry_set.each(&proc)
180
183
  end
181
184
 
182
- # Returns the number of entries in the central directory (and
185
+ # Returns the number of entries in the central directory (and
183
186
  # consequently in the zip archive).
184
187
  def size
185
188
  @entry_set.size
@@ -189,7 +192,7 @@ module Zip
189
192
  cdir = new
190
193
  cdir.read_from_stream(io)
191
194
  return cdir
192
- rescue ZipError
195
+ rescue Error
193
196
  return nil
194
197
  end
195
198
 
@@ -1,7 +1,7 @@
1
1
  module Zip
2
2
  class Deflater < Compressor #:nodoc:all
3
3
 
4
- def initialize(output_stream, level = ::Zlib::DEFAULT_COMPRESSION)
4
+ def initialize(output_stream, level = Zip.default_compression)
5
5
  super()
6
6
  @output_stream = output_stream
7
7
  @zlib_deflater = ::Zlib::Deflate.new(level, -::Zlib::MAX_WBITS)
@@ -15,7 +15,7 @@ module Zip
15
15
 
16
16
  def set_default_vars_values
17
17
  @local_header_offset = 0
18
- @local_header_size = 0
18
+ @local_header_size = nil # not known until local entry is created or read
19
19
  @internal_file_attributes = 1
20
20
  @external_file_attributes = 0
21
21
  @header_signature = ::Zip::CENTRAL_DIRECTORY_ENTRY_SIGNATURE
@@ -46,7 +46,7 @@ module Zip
46
46
 
47
47
  def check_name(name)
48
48
  if name.start_with?('/')
49
- raise ::Zip::ZipEntryNameError, "Illegal ZipEntry name '#{name}', name must not start with /"
49
+ raise ::Zip::EntryNameError, "Illegal ZipEntry name '#{name}', name must not start with /"
50
50
  end
51
51
  end
52
52
 
@@ -92,7 +92,7 @@ module Zip
92
92
  end
93
93
 
94
94
  def file_type_is?(type)
95
- raise ZipInternalError, "current filetype is unknown: #{self.inspect}" unless @ftype
95
+ raise InternalError, "current filetype is unknown: #{self.inspect}" unless @ftype
96
96
  @ftype == type
97
97
  end
98
98
 
@@ -130,9 +130,9 @@ module Zip
130
130
  # check before rewriting an entry (after file sizes are known)
131
131
  # that we didn't change the header size (and thus clobber file data or something)
132
132
  def verify_local_header_size!
133
- return if @local_header_size == 0
133
+ return if @local_header_size.nil?
134
134
  new_size = calculate_local_header_size
135
- raise ZipError, "local header size changed (#{@local_header_size} -> #{new_size})" if @local_header_size != new_size
135
+ raise Error, "local header size changed (#{@local_header_size} -> #{new_size})" if @local_header_size != new_size
136
136
  end
137
137
 
138
138
  def cdir_header_size #:nodoc:all
@@ -177,18 +177,23 @@ module Zip
177
177
  end
178
178
 
179
179
  def read_c_dir_entry(io) #:nodoc:all
180
- entry = new(io.path)
180
+ path = if io.is_a?(::IO)
181
+ io.path
182
+ else
183
+ io
184
+ end
185
+ entry = new(path)
181
186
  entry.read_c_dir_entry(io)
182
187
  entry
183
- rescue ZipError
188
+ rescue Error
184
189
  nil
185
190
  end
186
191
 
187
192
  def read_local_entry(io)
188
- entry = self.new
193
+ entry = self.new(io)
189
194
  entry.read_local_entry(io)
190
195
  entry
191
- rescue ZipError
196
+ rescue Error
192
197
  nil
193
198
  end
194
199
 
@@ -217,13 +222,13 @@ module Zip
217
222
  static_sized_fields_buf = io.read(::Zip::LOCAL_ENTRY_STATIC_HEADER_LENGTH)
218
223
 
219
224
  unless static_sized_fields_buf.bytesize == ::Zip::LOCAL_ENTRY_STATIC_HEADER_LENGTH
220
- raise ZipError, "Premature end of file. Not enough data for zip entry local header"
225
+ raise Error, "Premature end of file. Not enough data for zip entry local header"
221
226
  end
222
227
 
223
228
  unpack_local_entry(static_sized_fields_buf)
224
229
 
225
230
  unless @header_signature == ::Zip::LOCAL_ENTRY_SIGNATURE
226
- raise ::Zip::ZipError, "Zip local header magic not found at location '#{local_header_offset}'"
231
+ raise ::Zip::Error, "Zip local header magic not found at location '#{local_header_offset}'"
227
232
  end
228
233
  set_time(@last_mod_date, @last_mod_time)
229
234
 
@@ -233,7 +238,7 @@ module Zip
233
238
  @name.gsub!('\\', '/')
234
239
 
235
240
  if extra && extra.bytesize != @extra_length
236
- raise ::Zip::ZipError, "Truncated local zip entry header"
241
+ raise ::Zip::Error, "Truncated local zip entry header"
237
242
  else
238
243
  if ::Zip::ExtraField === @extra
239
244
  @extra.merge(extra)
@@ -327,19 +332,19 @@ module Zip
327
332
 
328
333
  def check_c_dir_entry_static_header_length(buf)
329
334
  unless buf.bytesize == ::Zip::CDIR_ENTRY_STATIC_HEADER_LENGTH
330
- raise ZipError, 'Premature end of file. Not enough data for zip cdir entry header'
335
+ raise Error, 'Premature end of file. Not enough data for zip cdir entry header'
331
336
  end
332
337
  end
333
338
 
334
339
  def check_c_dir_entry_signature
335
340
  unless header_signature == ::Zip::CENTRAL_DIRECTORY_ENTRY_SIGNATURE
336
- raise ZipError, "Zip local header magic not found at location '#{local_header_offset}'"
341
+ raise Error, "Zip local header magic not found at location '#{local_header_offset}'"
337
342
  end
338
343
  end
339
344
 
340
345
  def check_c_dir_entry_comment_size
341
346
  unless @comment && @comment.bytesize == @comment_length
342
- raise ::Zip::ZipError, "Truncated cdir zip entry header"
347
+ raise ::Zip::Error, "Truncated cdir zip entry header"
343
348
  end
344
349
  end
345
350
 
@@ -363,7 +368,6 @@ module Zip
363
368
  check_c_dir_entry_comment_size
364
369
  set_ftype_from_c_dir_entry
365
370
  parse_zip64_extra(false)
366
- @local_header_size = calculate_local_header_size
367
371
  end
368
372
 
369
373
  def file_stat(path) # :nodoc:
@@ -422,7 +426,10 @@ module Zip
422
426
  (zip64 && zip64.disk_start_number) ? 0xFFFF : 0, # disk number start
423
427
  @internal_file_attributes, # file type (binary=0, text=1)
424
428
  @external_file_attributes, # native filesystem attributes
425
- (zip64 && zip64.relative_header_offset) ? 0xFFFFFFFF : @local_header_offset
429
+ (zip64 && zip64.relative_header_offset) ? 0xFFFFFFFF : @local_header_offset,
430
+ @name,
431
+ @extra,
432
+ @comment
426
433
  ].pack('VCCvvvvvVVVvvvvvVV')
427
434
  end
428
435
 
@@ -511,7 +518,7 @@ module Zip
511
518
  end
512
519
  :file
513
520
  when 'directory'
514
- @name += "/" unless name_is_directory?
521
+ @name += '/' unless name_is_directory?
515
522
  :directory
516
523
  when 'link'
517
524
  if name_is_directory?
@@ -530,9 +537,9 @@ module Zip
530
537
 
531
538
  def write_to_zip_output_stream(zip_output_stream) #:nodoc:all
532
539
  if @ftype == :directory
533
- zip_output_stream.put_next_entry(self)
540
+ zip_output_stream.put_next_entry(self, nil, nil, ::Zip::Entry::STORED)
534
541
  elsif @filepath
535
- zip_output_stream.put_next_entry(self, nil, nil, nil)
542
+ zip_output_stream.put_next_entry(self, nil, nil, ::Zip::Entry::DEFLATED)
536
543
  get_input_stream { |is| ::Zip::IOExtras.copy_stream(zip_output_stream, is) }
537
544
  else
538
545
  zip_output_stream.copy_raw_entry(self)
@@ -546,7 +553,11 @@ module Zip
546
553
  end
547
554
 
548
555
  def get_raw_input_stream(&block)
549
- ::File.open(@zipfile, "rb", &block)
556
+ if @zipfile.is_a?(::IO) || @zipfile.is_a?(::StringIO)
557
+ yield @zipfile
558
+ else
559
+ ::File.open(@zipfile, "rb", &block)
560
+ end
550
561
  end
551
562
 
552
563
  private
@@ -558,8 +569,8 @@ module Zip
558
569
  end
559
570
 
560
571
  def create_file(dest_path, continue_on_exists_proc = proc { Zip.continue_on_exists_proc })
561
- if ::File.exists?(dest_path) && !yield(self, dest_path)
562
- raise ::Zip::ZipDestinationFileExistsError,
572
+ if ::File.exist?(dest_path) && !yield(self, dest_path)
573
+ raise ::Zip::DestinationFileExistsError,
563
574
  "Destination '#{dest_path}' already exists"
564
575
  end
565
576
  ::File.open(dest_path, "wb") do |os|
@@ -576,11 +587,11 @@ module Zip
576
587
 
577
588
  def create_directory(dest_path)
578
589
  return if ::File.directory?(dest_path)
579
- if ::File.exists?(dest_path)
590
+ if ::File.exist?(dest_path)
580
591
  if block_given? && yield(self, dest_path)
581
592
  ::FileUtils::rm_f dest_path
582
593
  else
583
- raise ::Zip::ZipDestinationFileExistsError,
594
+ raise ::Zip::DestinationFileExistsError,
584
595
  "Cannot create directory '#{dest_path}'. "+
585
596
  "A file already exists with that name"
586
597
  end
@@ -605,12 +616,12 @@ module Zip
605
616
  if ::File.readlink(dest_path) == linkto
606
617
  return
607
618
  else
608
- raise ZipDestinationFileExistsError,
619
+ raise ::Zip::DestinationFileExistsError,
609
620
  "Cannot create symlink '#{dest_path}'. "+
610
621
  "A symlink already exists with that name"
611
622
  end
612
623
  else
613
- raise ZipDestinationFileExistsError,
624
+ raise ::Zip::DestinationFileExistsError,
614
625
  "Cannot create symlink '#{dest_path}'. "+
615
626
  "A file already exists with that name"
616
627
  end
@@ -633,6 +644,7 @@ module Zip
633
644
 
634
645
  # create a zip64 extra information field if we need one
635
646
  def prep_zip64_extra(for_local_header) #:nodoc:all
647
+ return unless ::Zip.write_zip64_support
636
648
  need_zip64 = @size >= 0xFFFFFFFF || @compressed_size >= 0xFFFFFFFF
637
649
  unless for_local_header
638
650
  need_zip64 ||= @local_header_offset >= 0xFFFFFFFF
@@ -77,7 +77,7 @@ module Zip
77
77
 
78
78
  private
79
79
  def to_key(entry)
80
- entry.to_s.sub(/\/$/, '')
80
+ entry.to_s.chomp('/')
81
81
  end
82
82
  end
83
83
  end
@@ -1,8 +1,8 @@
1
1
  module Zip
2
- class ZipError < StandardError; end
3
- class ZipEntryExistsError < ZipError; end
4
- class ZipDestinationFileExistsError < ZipError; end
5
- class ZipCompressionMethodError < ZipError; end
6
- class ZipEntryNameError < ZipError; end
7
- class ZipInternalError < ZipError; end
2
+ class Error < StandardError; end
3
+ class EntryExistsError < Error; end
4
+ class DestinationFileExistsError < Error; end
5
+ class CompressionMethodError < Error; end
6
+ class EntryNameError < Error; end
7
+ class InternalError < Error; end
8
8
  end
@@ -52,7 +52,7 @@ module Zip
52
52
 
53
53
  def create(name)
54
54
  unless field_class = ID_MAP.values.find { |k| k.name == name }
55
- raise ZipError, "Unknown extra field '#{name}'"
55
+ raise Error, "Unknown extra field '#{name}'"
56
56
  end
57
57
  self[name] = field_class.new
58
58
  end
@@ -60,17 +60,19 @@ module Zip
60
60
  # place Unknown last, so "extra" data that is missing the proper signature/size
61
61
  # does not prevent known fields from being read back in
62
62
  def ordered_values
63
- self.keys.sort_by { |k| k == 'Unknown' ? 1 : 0 }.map { |k| self[k] }
63
+ result = []
64
+ self.each { |k,v| k == 'Unknown' ? result.push(v) : result.unshift(v) }
65
+ result
64
66
  end
65
67
 
66
68
  def to_local_bin
67
- ordered_values.map { |v| v.to_local_bin.force_encoding('BINARY') }.join
69
+ ordered_values.map! { |v| v.to_local_bin.force_encoding('BINARY') }.join
68
70
  end
69
71
 
70
72
  alias :to_s :to_local_bin
71
73
 
72
74
  def to_c_dir_bin
73
- ordered_values.map { |v| v.to_c_dir_bin.force_encoding('BINARY') }.join
75
+ ordered_values.map! { |v| v.to_c_dir_bin.force_encoding('BINARY') }.join
74
76
  end
75
77
 
76
78
  def c_dir_size
@@ -88,6 +90,7 @@ end
88
90
 
89
91
  require 'zip/extra_field/generic'
90
92
  require 'zip/extra_field/universal_time'
93
+ require 'zip/extra_field/old_unix'
91
94
  require 'zip/extra_field/unix'
92
95
  require 'zip/extra_field/zip64'
93
96
  require 'zip/extra_field/zip64_placeholder'
@@ -7,7 +7,7 @@ module Zip
7
7
  end
8
8
 
9
9
  def self.name
10
- self.to_s.split("::")[-1]
10
+ @name ||= self.to_s.split("::")[-1]
11
11
  end
12
12
 
13
13
  # return field [size, content] or false
@@ -32,12 +32,12 @@ module Zip
32
32
 
33
33
  def to_local_bin
34
34
  s = pack_for_local
35
- self.class.const_get(:HEADER_ID) + [s.bytesize].pack("v") + s
35
+ self.class.const_get(:HEADER_ID) + [s.bytesize].pack("v") << s
36
36
  end
37
37
 
38
38
  def to_c_dir_bin
39
39
  s = pack_for_c_dir
40
- self.class.const_get(:HEADER_ID) + [s.bytesize].pack("v") + s
40
+ self.class.const_get(:HEADER_ID) + [s.bytesize].pack("v") << s
41
41
  end
42
42
  end
43
- end
43
+ end
@@ -0,0 +1,45 @@
1
+ module Zip
2
+ # Olf Info-ZIP Extra for UNIX uid/gid and file timestampes
3
+ class ExtraField::OldUnix < ExtraField::Generic
4
+ HEADER_ID = "UX"
5
+ register_map
6
+
7
+ def initialize(binstr = nil)
8
+ @uid = 0
9
+ @gid = 0
10
+ @atime = nil
11
+ @mtime = nil
12
+ binstr and merge(binstr)
13
+ end
14
+
15
+ attr_accessor :uid, :gid, :atime, :mtime
16
+
17
+ def merge(binstr)
18
+ return if binstr.empty?
19
+ size, content = initial_parse(binstr)
20
+ # size: 0 for central directory. 4 for local header
21
+ return if (!size || size == 0)
22
+ atime, mtime, uid, gid = content.unpack("VVvv")
23
+ @uid ||= uid
24
+ @gid ||= gid
25
+ @atime ||= atime
26
+ @mtime ||= mtime
27
+ end
28
+
29
+ def ==(other)
30
+ @uid == other.uid &&
31
+ @gid == other.gid &&
32
+ @atime == other.atime &&
33
+ @mtime == other.mtime
34
+ end
35
+
36
+ def pack_for_local
37
+ [@atime, @mtime, @uid, @gid].pack("VVvv")
38
+ end
39
+
40
+ def pack_for_c_dir
41
+ [@atime, @mtime].pack("VV")
42
+ end
43
+ end
44
+
45
+ end
@@ -70,7 +70,7 @@ module Zip
70
70
  @comment = ''
71
71
  @create = create
72
72
  case
73
- when ::File.exists?(file_name) && !buffer
73
+ when !buffer && ::File.exist?(file_name)
74
74
  @create = nil
75
75
  @exist_file_perms = ::File.stat(file_name).mode
76
76
  ::File.open(name, 'rb') do |f|
@@ -79,7 +79,7 @@ module Zip
79
79
  when create
80
80
  @entry_set = EntrySet.new
81
81
  else
82
- raise ZipError, "File #{file_name} not found"
82
+ raise Error, "File #{file_name} not found"
83
83
  end
84
84
  @stored_entries = @entry_set.dup
85
85
  @stored_comment = @comment
@@ -94,40 +94,38 @@ module Zip
94
94
  # ruby's builtin File.open method.
95
95
  def open(file_name, create = nil)
96
96
  zf = ::Zip::File.new(file_name, create)
97
- if block_given?
98
- begin
99
- yield zf
100
- ensure
101
- zf.close
102
- end
103
- else
104
- zf
97
+ return zf unless block_given?
98
+ begin
99
+ yield zf
100
+ ensure
101
+ zf.close
105
102
  end
106
103
  end
107
104
 
108
105
  # Same as #open. But outputs data to a buffer instead of a file
109
106
  def add_buffer
110
- zf = ::Zip::File.new('', true, true)
107
+ io = ::StringIO.new('')
108
+ zf = ::Zip::File.new(io, true, true)
111
109
  yield zf
112
- zf.write_buffer
110
+ zf.write_buffer(io)
113
111
  end
114
112
 
115
113
  # Like #open, but reads zip archive contents from a String or open IO
116
114
  # stream, and outputs data to a buffer.
117
- # (This can be used to extract data from a
115
+ # (This can be used to extract data from a
118
116
  # downloaded zip archive without first saving it to disk.)
119
117
  def open_buffer(io, options = {})
120
- unless io.is_a?(IO) || io.is_a?(String)
121
- raise "Zip::File.open_buffer expects an argument of class String or IO. Found: #{io.class}"
118
+ unless io.is_a?(IO) || io.is_a?(String) || io.is_a?(Tempfile)
119
+ raise "Zip::File.open_buffer expects an argument of class String, IO, or Tempfile. Found: #{io.class}"
122
120
  end
123
- zf = ::Zip::File.new('', true, true, options)
124
121
  if io.is_a?(::String)
125
122
  require 'stringio'
126
123
  io = ::StringIO.new(io)
127
124
  end
125
+ zf = ::Zip::File.new(io, true, true, options)
128
126
  zf.read_from_stream(io)
129
127
  yield zf
130
- zf.write_buffer
128
+ zf.write_buffer(io)
131
129
  end
132
130
 
133
131
  # Iterates over the contents of the ZipFile. This is more efficient
@@ -196,7 +194,7 @@ module Zip
196
194
 
197
195
  # Splits an archive into parts with segment size
198
196
  def split(zip_file_name, segment_size = MAX_SEGMENT_SIZE, delete_zip_file = true, partial_zip_file_name = nil)
199
- raise ZipError, "File #{zip_file_name} not found" unless ::File.exists?(zip_file_name)
197
+ raise Error, "File #{zip_file_name} not found" unless ::File.exist?(zip_file_name)
200
198
  raise Errno::ENOENT, zip_file_name unless ::File.readable?(zip_file_name)
201
199
  zip_file_size = ::File.size(zip_file_name)
202
200
  segment_size = get_segment_size_for_split(segment_size)
@@ -227,24 +225,24 @@ module Zip
227
225
 
228
226
  # Returns an output stream to the specified entry. If entry is not an instance
229
227
  # of Zip::Entry, a new Zip::Entry will be initialized using the arguments
230
- # specified. If a block is passed the stream object is passed to the block and
231
- # the stream is automatically closed afterwards just as with ruby's builtin
228
+ # specified. If a block is passed the stream object is passed to the block and
229
+ # the stream is automatically closed afterwards just as with ruby's builtin
232
230
  # File.open method.
233
- def get_output_stream(entry, permissionInt = nil, comment = nil, extra = nil, compressed_size = nil, crc = nil, compression_method = nil, size = nil, time = nil, &aProc)
234
- newEntry =
231
+ def get_output_stream(entry, permission_int = nil, comment = nil, extra = nil, compressed_size = nil, crc = nil, compression_method = nil, size = nil, time = nil, &aProc)
232
+ new_entry =
235
233
  if entry.kind_of?(Entry)
236
234
  entry
237
235
  else
238
236
  Entry.new(@name, entry.to_s, comment, extra, compressed_size, crc, compression_method, size, time)
239
237
  end
240
- if newEntry.directory?
238
+ if new_entry.directory?
241
239
  raise ArgumentError,
242
- "cannot open stream to directory entry - '#{newEntry}'"
240
+ "cannot open stream to directory entry - '#{new_entry}'"
243
241
  end
244
- newEntry.unix_perms = permissionInt
245
- zipStreamableEntry = StreamableStream.new(newEntry)
246
- @entry_set << zipStreamableEntry
247
- zipStreamableEntry.get_output_stream(&aProc)
242
+ new_entry.unix_perms = permission_int
243
+ zip_streamable_entry = StreamableStream.new(new_entry)
244
+ @entry_set << zip_streamable_entry
245
+ zip_streamable_entry.get_output_stream(&aProc)
248
246
  end
249
247
 
250
248
  # Returns the name of the zip archive
@@ -258,12 +256,13 @@ module Zip
258
256
  end
259
257
 
260
258
  # Convenience method for adding the contents of a file to the archive
261
- def add(entry, srcPath, &continue_on_exists_proc)
262
- continue_on_exists_proc ||= proc { Zip.continue_on_exists_proc }
259
+ def add(entry, src_path, &continue_on_exists_proc)
260
+ continue_on_exists_proc ||= proc { ::Zip.continue_on_exists_proc }
263
261
  check_entry_exists(entry, continue_on_exists_proc, "add")
264
- newEntry = entry.kind_of?(Entry) ? entry : Entry.new(@name, entry.to_s)
265
- newEntry.gather_fileinfo_from_srcpath(srcPath)
266
- @entry_set << newEntry
262
+ new_entry = entry.kind_of?(::Zip::Entry) ? entry : ::Zip::Entry.new(@name, entry.to_s)
263
+ new_entry.gather_fileinfo_from_srcpath(src_path)
264
+ new_entry.dirty = true
265
+ @entry_set << new_entry
267
266
  end
268
267
 
269
268
  # Removes the specified entry.
@@ -290,7 +289,7 @@ module Zip
290
289
 
291
290
  # Extracts entry to file dest_path.
292
291
  def extract(entry, dest_path, &block)
293
- block ||= proc { ::Zip.on_exists_proc }
292
+ block ||= proc { ::Zip.on_exists_proc }
294
293
  found_entry = get_entry(entry)
295
294
  found_entry.extract(dest_path, &block)
296
295
  end
@@ -298,9 +297,9 @@ module Zip
298
297
  # Commits changes that has been made since the previous commit to
299
298
  # the zip archive.
300
299
  def commit
301
- return if !commit_required?
302
- on_success_replace do |tmpFile|
303
- ::Zip::OutputStream.open(tmpFile) do |zos|
300
+ return unless commit_required?
301
+ on_success_replace do |tmp_file|
302
+ ::Zip::OutputStream.open(tmp_file) do |zos|
304
303
  @entry_set.each do |e|
305
304
  e.write_to_zip_output_stream(zos)
306
305
  e.dirty = false
@@ -313,8 +312,8 @@ module Zip
313
312
  end
314
313
 
315
314
  # Write buffer write changes to buffer and return
316
- def write_buffer
317
- OutputStream.write_buffer do |zos|
315
+ def write_buffer(io)
316
+ ::Zip::OutputStream.write_buffer(io) do |zos|
318
317
  @entry_set.each { |e| e.write_to_zip_output_stream(zos) }
319
318
  zos.comment = comment
320
319
  end
@@ -331,7 +330,7 @@ module Zip
331
330
  @entry_set.each do |e|
332
331
  return true if e.dirty
333
332
  end
334
- @comment != @stored_comment || @entry_set != @stored_entries || @create == File::CREATE
333
+ @comment != @stored_comment || @entry_set != @stored_entries || @create == ::Zip::File::CREATE
335
334
  end
336
335
 
337
336
  # Searches for entry with the specified name. Returns nil if
@@ -388,7 +387,7 @@ module Zip
388
387
  if continue_on_exists_proc.call
389
388
  remove get_entry(entryName)
390
389
  else
391
- raise ZipEntryExistsError,
390
+ raise ::Zip::EntryExistsError,
392
391
  procedureName + " failed. Entry #{entryName} already exists"
393
392
  end
394
393
  end
@@ -401,7 +400,7 @@ module Zip
401
400
  end
402
401
 
403
402
  def on_success_replace
404
- tmpfile = get_tempfile
403
+ tmpfile = get_tempfile
405
404
  tmp_filename = tmpfile.path
406
405
  tmpfile.close
407
406
  if yield tmp_filename
@@ -4,26 +4,42 @@ module Zip
4
4
  super
5
5
  @zlib_inflater = ::Zlib::Inflate.new(-Zlib::MAX_WBITS)
6
6
  @output_buffer = ''
7
+ @output_buffer_pos = 0
7
8
  @has_returned_empty_string = false
8
9
  end
9
10
 
10
11
  def sysread(number_of_bytes = nil, buf = '')
12
+ buf ||= ''
13
+ buf.clear
11
14
  readEverything = number_of_bytes.nil?
12
- while readEverything || @output_buffer.bytesize < number_of_bytes
15
+ if readEverything
16
+ buf << @output_buffer[@output_buffer_pos...@output_buffer.bytesize]
17
+
18
+ move_output_buffer_pos(buf.bytesize)
19
+ else
20
+ buf << @output_buffer[@output_buffer_pos, number_of_bytes]
21
+
22
+ move_output_buffer_pos(buf.bytesize)
23
+
24
+ if buf.bytesize == number_of_bytes
25
+ return buf
26
+ end
27
+ end
28
+ while readEverything || buf.bytesize + @output_buffer.bytesize < number_of_bytes
13
29
  break if internal_input_finished?
14
- @output_buffer << internal_produce_input(buf)
30
+ @output_buffer << internal_produce_input
15
31
  end
16
- return value_when_finished if @output_buffer.bytesize == 0 && input_finished?
17
- end_index = number_of_bytes.nil? ? @output_buffer.bytesize : number_of_bytes
18
- @output_buffer.slice!(0...end_index)
32
+ return value_when_finished(number_of_bytes, buf) if @output_buffer.bytesize == 0 && input_finished?
33
+ end_index = (number_of_bytes.nil? ? @output_buffer.bytesize : number_of_bytes) - buf.bytesize
34
+ data = @output_buffer[0...end_index]
35
+
36
+ move_output_buffer_pos(data.bytesize)
37
+
38
+ buf << data
19
39
  end
20
40
 
21
41
  def produce_input
22
- if (@output_buffer.empty?)
23
- internal_produce_input
24
- else
25
- @output_buffer.slice!(0...(@output_buffer.length))
26
- end
42
+ sysread()
27
43
  end
28
44
 
29
45
  # to be used with produce_input, not read (as read may still have more data cached)
@@ -37,7 +53,16 @@ module Zip
37
53
 
38
54
  private
39
55
 
40
- def internal_produce_input(buf = '')
56
+ def move_output_buffer_pos(inc)
57
+ @output_buffer_pos += inc
58
+ if @output_buffer_pos == @output_buffer.bytesize
59
+ @output_buffer.clear
60
+ @output_buffer_pos = 0
61
+ end
62
+ end
63
+
64
+ def internal_produce_input
65
+ buf = ''
41
66
  retried = 0
42
67
  begin
43
68
  @zlib_inflater.inflate(@input_stream.read(Decompressor::CHUNK_SIZE, buf))
@@ -52,10 +77,14 @@ module Zip
52
77
  @zlib_inflater.finished?
53
78
  end
54
79
 
55
- def value_when_finished # mimic behaviour of ruby File object.
56
- return if @has_returned_empty_string
57
- @has_returned_empty_string = true
58
- ''
80
+ def value_when_finished(number_of_bytes, buf) # mimic behaviour of ruby File object.
81
+ if number_of_bytes.nil?
82
+ buf
83
+ elsif buf.bytesize == 0
84
+ nil
85
+ else
86
+ buf
87
+ end
59
88
  end
60
89
  end
61
90
  end
@@ -1,41 +1,41 @@
1
1
  module Zip
2
2
  # InputStream is the basic class for reading zip entries in a
3
3
  # zip file. It is possible to create a InputStream object directly,
4
- # passing the zip file name to the constructor, but more often than not
4
+ # passing the zip file name to the constructor, but more often than not
5
5
  # the InputStream will be obtained from a File (perhaps using the
6
- # ZipFileSystem interface) object for a particular entry in the zip
6
+ # ZipFileSystem interface) object for a particular entry in the zip
7
7
  # archive.
8
8
  #
9
9
  # A InputStream inherits IOExtras::AbstractInputStream in order
10
- # to provide an IO-like interface for reading from a single zip
11
- # entry. Beyond methods for mimicking an IO-object it contains
12
- # the method get_next_entry for iterating through the entries of
10
+ # to provide an IO-like interface for reading from a single zip
11
+ # entry. Beyond methods for mimicking an IO-object it contains
12
+ # the method get_next_entry for iterating through the entries of
13
13
  # an archive. get_next_entry returns a Entry object that describes
14
14
  # the zip entry the InputStream is currently reading from.
15
15
  #
16
- # Example that creates a zip archive with ZipOutputStream and reads it
16
+ # Example that creates a zip archive with ZipOutputStream and reads it
17
17
  # back again with a InputStream.
18
18
  #
19
19
  # require 'zip'
20
- #
20
+ #
21
21
  # Zip::OutputStream.open("my.zip") do |io|
22
- #
22
+ #
23
23
  # io.put_next_entry("first_entry.txt")
24
24
  # io.write "Hello world!"
25
- #
25
+ #
26
26
  # io.put_next_entry("adir/first_entry.txt")
27
27
  # io.write "Hello again!"
28
28
  # end
29
29
  #
30
- #
30
+ #
31
31
  # Zip::InputStream.open("my.zip") do |io|
32
- #
32
+ #
33
33
  # while (entry = io.get_next_entry)
34
34
  # puts "Contents of #{entry.name}: '#{io.read}'"
35
35
  # end
36
36
  # end
37
37
  #
38
- # java.util.zip.ZipInputStream is the original inspiration for this
38
+ # java.util.zip.ZipInputStream is the original inspiration for this
39
39
  # class.
40
40
 
41
41
  class InputStream
@@ -60,7 +60,7 @@ module Zip
60
60
 
61
61
  # Returns a Entry object. It is necessary to call this
62
62
  # method on a newly created InputStream before reading from
63
- # the first entry in the archive. Returns nil when there are
63
+ # the first entry in the archive. Returns nil when there are
64
64
  # no more entries.
65
65
  def get_next_entry
66
66
  @archive_io.seek(@current_entry.next_header_offset, IO::SEEK_SET) if @current_entry
@@ -112,7 +112,9 @@ module Zip
112
112
  def get_io(io_or_file, offset = 0)
113
113
  case io_or_file
114
114
  when IO, StringIO
115
- io_or_file
115
+ io = io_or_file.dup
116
+ io.seek(offset, ::IO::SEEK_SET)
117
+ io
116
118
  else
117
119
  file = ::File.open(io_or_file, 'rb')
118
120
  file.seek(offset, ::IO::SEEK_SET)
@@ -136,7 +138,7 @@ module Zip
136
138
  when @current_entry.compression_method == ::Zip::Entry::DEFLATED
137
139
  ::Zip::Inflater.new(@archive_io)
138
140
  else
139
- raise ZipCompressionMethodError,
141
+ raise ::Zip::CompressionMethodError,
140
142
  "Unsupported compression method #{@current_entry.compression_method}"
141
143
  end
142
144
  end
@@ -24,14 +24,17 @@ module Zip
24
24
 
25
25
  # Opens the indicated zip file. If a file with that name already
26
26
  # exists it will be overwritten.
27
- def initialize(fileName, stream=false)
27
+ def initialize(file_name, stream=false)
28
28
  super()
29
- @fileName = fileName
30
- if stream
31
- @output_stream = ::StringIO.new
32
- else
33
- @output_stream = ::File.new(@fileName, "wb")
34
- end
29
+ @file_name = file_name
30
+ @output_stream = if stream
31
+ iostream = @file_name.dup
32
+ iostream.reopen
33
+ iostream.rewind
34
+ iostream
35
+ else
36
+ ::File.new(@file_name, "wb")
37
+ end
35
38
  @entry_set = ::Zip::EntrySet.new
36
39
  @compressor = ::Zip::NullCompressor.instance
37
40
  @closed = false
@@ -43,19 +46,19 @@ module Zip
43
46
  # stream is passed to the block and closed when the block
44
47
  # returns.
45
48
  class << self
46
- def open(fileName)
47
- return new(fileName) unless block_given?
48
- zos = new(fileName)
49
+ def open(file_name)
50
+ return new(file_name) unless block_given?
51
+ zos = new(file_name)
49
52
  yield zos
50
53
  ensure
51
54
  zos.close if zos
52
55
  end
53
56
 
54
- # Same as #open but writes to a filestream instead
55
- def write_buffer
56
- zos = new('', true)
57
+ # Same as #open but writes to a filestream instead
58
+ def write_buffer(io)
59
+ zos = new(io, true)
57
60
  yield zos
58
- return zos.close_buffer
61
+ zos.close_buffer
59
62
  end
60
63
  end
61
64
 
@@ -79,35 +82,36 @@ module Zip
79
82
  @output_stream
80
83
  end
81
84
 
82
- # Closes the current entry and opens a new for writing.
85
+ # Closes the current entry and opens a new for writing.
83
86
  # +entry+ can be a ZipEntry object or a string.
84
- def put_next_entry(entryname, comment = nil, extra = nil, compression_method = Entry::DEFLATED, level = Zlib::DEFAULT_COMPRESSION)
85
- raise ZipError, "zip stream is closed" if @closed
86
- if entryname.kind_of?(Entry)
87
- new_entry = entryname
87
+ def put_next_entry(entry_name, comment = nil, extra = nil, compression_method = Entry::DEFLATED, level = Zip.default_compression)
88
+ raise Error, "zip stream is closed" if @closed
89
+ if entry_name.kind_of?(Entry)
90
+ new_entry = entry_name
88
91
  else
89
- new_entry = Entry.new(@fileName, entryname.to_s)
92
+ new_entry = Entry.new(@file_name, entry_name.to_s)
90
93
  end
91
- new_entry.comment = comment if !comment.nil?
92
- if (!extra.nil?)
94
+ new_entry.comment = comment unless comment.nil?
95
+ unless extra.nil?
93
96
  new_entry.extra = ExtraField === extra ? extra : ExtraField.new(extra.to_s)
94
97
  end
95
- new_entry.compression_method = compression_method if !compression_method.nil?
98
+ new_entry.compression_method = compression_method unless compression_method.nil?
96
99
  init_next_entry(new_entry, level)
97
100
  @current_entry = new_entry
98
101
  end
99
102
 
100
103
  def copy_raw_entry(entry)
101
104
  entry = entry.dup
102
- raise ZipError, "zip stream is closed" if @closed
103
- raise ZipError, "entry is not a ZipEntry" if !entry.kind_of?(Entry)
105
+ raise Error, "zip stream is closed" if @closed
106
+ raise Error, "entry is not a ZipEntry" unless entry.is_a?(Entry)
104
107
  finalize_current_entry
105
108
  @entry_set << entry
106
- src_pos = entry.local_entry_offset
109
+ src_pos = entry.local_header_offset
107
110
  entry.write_local_entry(@output_stream)
108
111
  @compressor = NullCompressor.instance
109
112
  entry.get_raw_input_stream do |is|
110
113
  is.seek(src_pos, IO::SEEK_SET)
114
+ ::Zip::Entry.read_local_entry(is)
111
115
  IOExtras.copy_stream_n(@output_stream, is, entry.compressed_size)
112
116
  end
113
117
  @compressor = NullCompressor.instance
@@ -123,10 +127,10 @@ module Zip
123
127
  @current_entry.size = @compressor.size
124
128
  @current_entry.crc = @compressor.crc
125
129
  @current_entry = nil
126
- @compressor = NullCompressor.instance
130
+ @compressor = ::Zip::NullCompressor.instance
127
131
  end
128
132
 
129
- def init_next_entry(entry, level = Zlib::DEFAULT_COMPRESSION)
133
+ def init_next_entry(entry, level = Zip.default_compression)
130
134
  finalize_current_entry
131
135
  @entry_set << entry
132
136
  entry.write_local_entry(@output_stream)
@@ -135,10 +139,13 @@ module Zip
135
139
 
136
140
  def get_compressor(entry, level)
137
141
  case entry.compression_method
138
- when Entry::DEFLATED then Deflater.new(@output_stream, level)
139
- when Entry::STORED then PassThruCompressor.new(@output_stream)
140
- else raise ZipCompressionMethodError,
141
- "Invalid compression method: '#{entry.compression_method}'"
142
+ when Entry::DEFLATED then
143
+ ::Zip::Deflater.new(@output_stream, level)
144
+ when Entry::STORED then
145
+ ::Zip::PassThruCompressor.new(@output_stream)
146
+ else
147
+ raise ::Zip::CompressionMethodError,
148
+ "Invalid compression method: '#{entry.compression_method}'"
142
149
  end
143
150
  end
144
151
 
@@ -163,10 +170,13 @@ module Zip
163
170
  end
164
171
 
165
172
  public
173
+
166
174
  # Modeled after IO.<<
167
175
  def << (data)
168
176
  @compressor << data
177
+ self
169
178
  end
179
+
170
180
  end
171
181
  end
172
182
 
@@ -2,39 +2,44 @@ module Zip
2
2
  class StreamableStream < DelegateClass(Entry) #nodoc:all
3
3
  def initialize(entry)
4
4
  super(entry)
5
- @tempFile = Tempfile.new(::File.basename(name), ::File.dirname(zipfile))
6
- @tempFile.binmode
5
+ dirname = if zipfile.is_a?(::String)
6
+ ::File.dirname(zipfile)
7
+ else
8
+ '.'
9
+ end
10
+ @temp_file = Tempfile.new(::File.basename(name), dirname)
11
+ @temp_file.binmode
7
12
  end
8
13
 
9
14
  def get_output_stream
10
15
  if block_given?
11
16
  begin
12
- yield(@tempFile)
17
+ yield(@temp_file)
13
18
  ensure
14
- @tempFile.close
19
+ @temp_file.close
15
20
  end
16
21
  else
17
- @tempFile
22
+ @temp_file
18
23
  end
19
24
  end
20
25
 
21
26
  def get_input_stream
22
- if ! @tempFile.closed?
27
+ if !@temp_file.closed?
23
28
  raise StandardError, "cannot open entry for reading while its open for writing - #{name}"
24
29
  end
25
- @tempFile.open # reopens tempfile from top
26
- @tempFile.binmode
30
+ @temp_file.open # reopens tempfile from top
31
+ @temp_file.binmode
27
32
  if block_given?
28
33
  begin
29
- yield(@tempFile)
34
+ yield(@temp_file)
30
35
  ensure
31
- @tempFile.close
36
+ @temp_file.close
32
37
  end
33
38
  else
34
- @tempFile
39
+ @temp_file
35
40
  end
36
41
  end
37
-
42
+
38
43
  def write_to_zip_output_stream(aZipOutputStream)
39
44
  aZipOutputStream.put_next_entry(self)
40
45
  get_input_stream { |is| ::Zip::IOExtras.copy_stream(aZipOutputStream, is) }
@@ -1,3 +1,3 @@
1
1
  module Zip
2
- VERSION = '1.1.0'
2
+ VERSION = '1.1.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyzip
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Simonov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-01 00:00:00.000000000 Z
11
+ date: 2014-03-16 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -34,6 +34,7 @@ files:
34
34
  - lib/zip/entry_set.rb
35
35
  - lib/zip/errors.rb
36
36
  - lib/zip/extra_field/generic.rb
37
+ - lib/zip/extra_field/old_unix.rb
37
38
  - lib/zip/extra_field/universal_time.rb
38
39
  - lib/zip/extra_field/unix.rb
39
40
  - lib/zip/extra_field/zip64.rb